Im trying to modify winshare permissions depending on yaml list that follows:
Name:
path: C:\sharepath
Full:
- DOMAIN\USER
- DOMAIN\USER2
I have imported that list to my ansible code
- name: Shareperm
win_share:
name: "{{ Name }}
path: "{{ Name.path }}"
full: "{{ Name.Full | default(omit) | join(', ') }}"
That code gives me an error
account_name _ is not a valid account, cannot get SID: Exception calling "Translate" with "1" argument(s): "Some or all identity references could not be translated.
What am I missing to pass argument list containing escape character \ correct way (string - comma separated) according to
https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_share_module.html
Related
I can obtain a list of VPC subnets using Ansible playbook:
tasks:
- name: Gathering VPC info ...
amazon.aws.ec2_vpc_subnet_info:
region: "eu-east-1"
filters:
vpc-id: vpc-433434432aad778ad
register: output
- name: Register new var
ansible.builtin.set_fact:
cidr_list: "{{ cidr_list|default([]) + [item.cidr_block] }}"
loop: "{{ output.subnets }}"
- name: Debugger...
ansible.builtin.debug:
msg: "{{ cidr_list }}"
What I want now is to calculate all IPv4 addresses by giving a size of each subnet and the initial VPC CIDR (this is actually successfully can be done using AWS Fn::Cidr):
"Fn::Cidr" : ["10.0.0.0/16", 15, 29 ]
Which will create a list of 15 subnets where each has a mask of /29. Then my goal is to compare two lists, and if not used IPv4 found from Fn::Cidr list, then use that one.
However I was wondering is there such an Ansible module to accomplish same task as would Fn::Cidr do?
The | ipsubnet filter will do what you want, but it may require some {% for %} loops because I don't think it is designed (ootb) to do 15 subnets at a time
I wish to set labels inside a Helm chart using the Terraform helm_release resource with a helpers function.
When using the chart values there are no issues, as seen here:
values.yaml
mylabels:
name: "foo"
type: "boo"
_helpers.tpl
{{- define "aws.labels" -}}
{{- range $k, $v := .Values.mylabels }}
{{ $k }}: {{ $v | quote }}
{{- end -}}
{{- end -}}
deployment.yaml
metadata:
labels:
{{- include "aws.labels" . | trim | nindent 4 }}
But when values are passed in from the helm_release resource it fails.
set {
name = "mylabels"
value = yamlencode(var.aws_tags)
}
The output values for the above is:
+ set {
+ name = "mylabels"
+ value = <<-EOT
"Environment": "123"
"Owner": "xyz"
EOT
}
Which generates error:
│ Error: template: aws-efs-csi-driver/templates/controller-deployment.yaml:9:6: executing "aws-efs-csi-driver/templates/controller-deployment.yaml" at <include "aws.tags" .>: error calling include: template: aws-efs-csi-driver/templates/_helpers.tpl:68:27: executing "aws.tags" at <.Values.mylabels>: range can't iterate over
│ "Environment": "123"
│ "Owner": "xyz"
Any ideas or pointers would be greatly appreciated :-)
Solution
Thank you #jordanm that worked :~)
When using set in this way, it's the same as --set on the helm cli. You can't provide a yaml value that includes multiple values and must set each individually.
set {
name = "mylabels.Environment"
value = var.aws_tags["Environment"]
}
set {
name = "mylabels.Owner"
value = var.aws_tags["Owner"]
}
You may also be able the dynamic feature of terraform to iterate over your aws_tags variable:
dynamic "set" {
for_each = var.aws_tags
content {
name = "mylabels.${set.key}"
value = set.value
}
}
I am relatively new to Ansible and I am struggling to understand how to perform the following scenario:
I have an array with AWS security group names looking like this
['Security-Group-Name1', 'SecurityGroup-Name2', 'SecurityGroup-Name3']
However, what I want is to have an array of SecurityGroupIds. Using Ansible I have the ec2_group_info as an option to retrieve information about a security group. So far so good ...
Now comes my question. I need to loop through the above array using ec2_group_info, set the name of the security group I need and return the retrieved Id into a new array so in the end I have something like this.
['Security-Group-Id1', 'SecurityGroup-Id2', 'SecurityGroup-Id3']
I know I need to use a loop with sort of a dynamic index. But it is not really clear to me how to do this in Ansible.
I am aware of the latest loop section of Ansible Docs and I find them more than confusing...
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
Edit:
This is the current code which works as needed:
- name: Installing pip if not existing on host
pip:
name: boto3
- name: Get SecurityGroupId information
ec2_group_info:
filters:
group_name: ['SG-One', 'SG-Two']
vpc_id: 'vpc-id'
register: my_groups
- set_fact:
my_group_ids: '{{ my_groups.security_groups | map(attribute="group_id") | list }}'
- debug:
msg: "{{ my_groups }}"
- debug:
msg: "{{ my_group_ids }}"
This is the outcome:
TASK [Gathering Facts] ***************************************************
ok: [localhost]
TASK [machine-provisioning : Installing pip if not existing on host] ************
ok: [localhost]
TASK [machine-provisioning : Get SecurityGroupId information] *************************
ok: [localhost]
TASK [machine-provisioning : set_fact] *********************************
ok: [localhost]
TASK [machine-provisioning : debug] ***********************************************
ok: [localhost] => {
"msg": [
"sg-00000000",
"sg-11111111"
]
}
On that linked page about loops, you'll observe the use of register:, which is how you'd capture the result of that ec2_group_info: lookup, then use the map jinja filter to extract map(attribute="group_id") from the resulting list of results; you have to feed the output of map into the list filter, because map and a few others are python generators, and thus need a terminal action to materialize their data. The set_fact: is how ansible does "assignment"
- ec2_group_info:
filters:
group_name: '{{ the_group_names }}'
vpc_id: '{{ my_vpc_id }}'
register: my_groups
- set_fact:
my_group_ids: '{{ my_groups.security_groups | map(attribute="group_id") | list }}'
yields:
ok: [localhost] => {"ansible_facts": {"my_group_ids": ["sg-0c5c277ed1edafb54", "sg-7597a123"]}, "changed": false}
I'm trying to parse ansible variables using python specified in an inventory file like below:
[webservers]
foo.example.com type=news
bar.example.com type=sports
[dbservers]
mongodb.local type=mongo region=us
mysql.local type=mysql region=eu
I want to be able to parse type=news for host foo.example.com in webservers and type=mongo region=us for host mongodb.local under dbservers. Any help with this is greatly appreciated
The play below
- name: List type=news hosts in the group webservers
debug:
msg: "{{ hostvars[item].inventory_hostname }}"
loop: "{{ groups['webservers'] }}"
when: hostvars[item].type == "news"
- name: List type=mongo and region=us hosts in the group dbservers
debug:
msg: "{{ hostvars[item].inventory_hostname }}"
loop: "{{ groups['dbservers'] }}"
when:
- hostvars[item].type == "mongo"
- hostvars[item].region == "us"
gives:
"msg": "foo.example.com"
"msg": "mongodb.local"
If the playbook will be run on the host:
foo.example.com
you can get "type = news" simply by specifying "{{type}}". If you want to use in "when" conditions, then simply indicating "type"
If the playbook will be run on the host:
mongodb.local
then the value for "type" in this case will automatically be = "mongo", and "region" will automatically be = "us"
The values of the variables, if they are defined in the hosts file as you specified, will automatically be determined on the specified hosts
Thus, the playbook can be executed on all hosts and if you get a value for "type", for example:
- debug:
msg: "{{type}}"
On each of the hosts you will get your unique values that are defined in the hosts file
I'm not sure that I understood the question correctly, but if it meant that on the foo.example.com host it was necessary to get a list of servers from the "webservers" group that have "type = news", then the answer is already given.
Rather than re-inventing the wheel, I suggest you have a look at how ansible itsef is parsing ini files to turn them into an inventory object
You could also easily get this info in json format with a very simple playbook (as suggested by #vladimirbotka), or rewrite your inventory in yaml which would be much easier to parse with any external tool
inventory.yaml
---
all:
children:
webservers:
hosts:
foo.example.com:
type: news
bar.example.com:
type: sports
dbservers:
hosts:
mongodb.local:
type: mongo
region: us
mysql.local:
type: mysql
region: eu
I am encountering a strange problem with ansible, and I'm sure its just due to my lack of experience as I am relatively new to ansible (I've only been working with it for a couple weeks)
So, in short what I am trying to do is use the command module to run AWS CLI commands to list AWS access keys for a user then delete them from that user. The reason I am using CLI instead of iam module is because I believe there to be a bug with the IAM module in regard to removing access keys. Even when I specified state update and the access keys to remove and access key state remove it still would not remove access keys, or make them inactive when i set access key state to inactive.
The first task lists access keys for a given user and registers the output:
- name: List the access keys (if any) of the user(s) we just created
vars:
use_key: "{{ enable_access_keys }}"
command: "aws iam list-access-keys --user-name {{ item }}"
with_items:
- "{{ iam_user_name_list }}"
when: not use_key
register: list_key_output
^Keep in mind that iam_user_name_list only contains 1 user at the moment, which is why i access results the way I do. I know this needs to be changed in the future.
Since the stdout from list_key_output looks like this
"stdout": "{\n \"AccessKeyMetadata\": [\n {\n \"UserName\": \"other-guy\", \n \"Status\": \"Active\", \n \"CreateDate\": \"2017-06-29T18:45:04Z\", \n \"AccessKeyId\": \"removed\"\n }\n ]\n}",
I debug msg the stdout and register that to a variable test to give it proper json format without the slashes and newlines so I can use json_query to get the key from the stdout. I am using json query because AccessKeyId is not recognized as a key for the AccessKeyMetadata dictionary for whatever reason.
- name: list keys stdout
debug:
msg: "{{ list_key_output.results[0].stdout }}"
register: test
- name: test variable output
debug:
msg: "{{ test.msg.AccessKeyMetadata | json_query('[].AccessKeyId') }}"
At this point, I am successfully getting the access key from the stdout
ok: [127.0.0.1] => {
"changed": false,
"msg": [
"correct access key here"
]
}
Now, I feed the access key to the delete CLI command like so
- name: Remove any access keys our new console user might have
vars:
use_key: "{{ enable_access_keys }}"
command: "aws iam delete-access-key --access-key {{ test.msg.AccessKeyMetadata | json_query('[].AccessKeyId') }} --user-name other-guy"
when: not use_key
register: delete_key_output
This task fails due to an invalid access key being provided.
fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": ["aws", "iam", "delete-access-key", "--access-key", "[u********************]", "--user-name", "other-guy"], "delta": "0:00:00.388902", "end": "2017-06-29 18:59:13.308230", "failed": true, "rc": 255, "start": "2017-06-29 18:59:12.919328", "stderr": "\nAn error occurred (ValidationError) when calling the DeleteAccessKey operation: The specified value for accessKeyId is invalid. It must contain only alphanumeric characters.", "stderr_lines": ["", "An error occurred (ValidationError) when calling the DeleteAccessKey operation: The specified value for accessKeyId is invalid. It must contain only alphanumeric characters."], "stdout": "", "stdout_lines": []}
As you can see, when I pass the access key to the command, [u is prepended to the front of the access key and ] is appended to the back of it.
Why is this happening? How can I achieve my goal without having the 3 characters added to the access key making it invalid? I don't understand why this happens because when I debug msg the access key the same way i provide it to the command, it only shows the access key without [u in front and ] behind.
Sorry for the long post but I felt I really had to describe the situation to be able to get help here. Thanks in advance for any answers!
To answer your exact question:
ok: [127.0.0.1] => {
"changed": false,
"msg": [
"correct access key here"
]
}
Note the [ and ] in the msg – this means that you print a list, that contain one element – correct access key here string.
When you try to convert list into string, you get it's Python interpretation [u'correct access key here'].
You need to get first element of a list:
{{ test.msg.AccessKeyMetadata | json_query('[].AccessKeyId') | first }}
P.S. but from my point of view, you are going in a wrong way. try to fix your issues with iam module.