How to use list variables defined using Ansible? - ansible

I have defined a variable in my defaults as a list:
aws-sec-group-name:
- "es-external"
- "elasticsearch-production"
I am trying to use the above variable in my task playbook as follows:
---
- name: Create EC2 instances
ec2:
keyname: "{{ aws-key-name }}"
#group: "{{ aws-sec-group-name }}"
instance_type: "{{ aws-instance-type }}"
image: "{{ aws-ami }}"
wait: yes
wait_timeout: 500
count: 2
instance_tags:
Name: "{{ aws-tag-name }}"
vpc_subnet_id: "{{ subnet-id }}"
group: ["{{ aws-sec-group-name.[0] }}","{{ aws-sec-group-name.[1] }}"].
Which is not the right way.
Can someone tell me how to use list variable?
And also since the count is 2, I am also interested in knowing if i can add -1- and -2- in the Name tag?

Can someone tell me how to use list variable?
Here you are:
Fix the name of the variable as they cannot contain dashes:
aws_sec_group_name:
- "es-external"
- "elasticsearch-production"
Use the variable:
group: "{{ aws_sec_group_name }}"

Related

Registering and using multiple variables in Ansible

I'm trying to pop VM instances, put them into different host groups (say webservers and devops/admin machines) and install what is needed on them in one single playbook.
I don't know what IP addresses, for instance, GCP will give these instances, and so i am trying to capture them in a variable for use later on in the playbook. I can capture them fine by using "register" but using them is proving tricky. For instance if I do.
- name: création des adresses statiques
gcp_compute_address:
name: "{{ item }}"
state: present
region: "{{ region }}"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
loop:
- adresse-1
- adresse-2
- adresse-3
- adresse-4
- adresse-5
register: address
The best way i have figured out to use these variables later on is:
network_interfaces:
- network: "{{ network.name }}"
access_configs:
- name: 'External NAT'
type: 'ONE_TO_ONE_NAT'
nat_ip:
- "{{ address.results[0].address }}"
- "{{ address.results[1].address }}"
- "{{ address.results[2].address }}"
Which fails miserably.
Please help ? How can I use the range of addresses I have created ?
I am going nuts over this
It is possible to add_host to the group webservers and proceed with the next play
- add_host:
name: "{{ item }}"
groups: webservers
loop: "{{ address.results|json_query('[*].address') }}"
- debug:
msg: "{{ groups['webservers'] }}"
- hosts: webservers
tasks:
- name: Configure cluster
...
The tasks below split the hosts into two groups
- set_fact:
my_hosts: "{{ address.results|json_query('[*].address') }}"
- add_host:
name: "{{ item }}"
groups: webservers1
loop: "{{ my_hosts[0:(my_hosts|length / 2)|int] }}"
- add_host:
name: "{{ item }}"
groups: webservers2
loop: "{{ my_hosts[(my_hosts|length / 2)|int:my_hosts|length] }}"
- debug:
msg: "{{ groups['webservers1'] }}"
- debug:
msg: "{{ groups['webservers2'] }}"
There is also GCE Dynamic Inventory and other 100+ gcp modules. You might want to start with Google Cloud Platform Guide.
FWIW, Ansible 2 Cloud Automation Cookbook covers leading providers incl. GCP.

Loop through variables in task that has another list embedded in the variables

I am looking to loop through a list of variables. I have it looping through the of variables using with_items, however the catch is there is a list within that variables list that needs to have a different subset / number of variables that i need to iterate through as well.
I have tried different filters to include with_nested, with_subelements, and with_items. I know that they are moving towards loops as the primary driver moving forward so any solution ideally would leverage the ansible path moving forward. I am looking at having an "inner" loop or an external task that will iterate through the vlans_list and input that data as its to that point.
group Variables
vnic_templates:
- name: vNIC-A
fabric: A
mac_pool: testmac1
mtu: 1500
org_dn: org-root
redundancy_type: none
state: present
template_type: initial-template
vlans_list: ### THE PROBLEM CHILD
- name: vlan2
native: 'no'
state: present
- name: vlan3
native: 'no'
state: present
The actual task - i have issues when i have to input multiple vlans. The vnic template will have a 1 to one relationship however the vlans_list could be 1 vnic_template to many vlans.
ucs_vnic_template:
hostname: "{{ ucs_manager_hostname }}"
username: "{{ ucs_manager_username }}"
password: "{{ ucs_manager_password }}"
name: "{{ item.name }}"
fabric: "{{ item.fabric }}"
mac_pool: "{{ item.mac_pool }}"
mtu: "{{ item.mtu }}"
org_dn: "{{ item.org_dn }}"
redundancy_type: "{{ item.redundancy_type }}"
state: "{{ item.state }}"
template_type: "{{ item.template_type }}"
vlans_list:
- name: "{{ item.1.name }}"
native: "{{ item.1.native }}"
state: "{{ item.1.present }}"
# loop: "{{ vnic_templates | subelements('vlans_list') }}"
with_items:
- "{{ vnic_templates }}"
I am starting down the road of adding an include vlan_list.yml outside of this task but no familiar with out to do that.
Actual results are
The task includes an option with an undefined variable. The error was: 'item' is undefined\n\n
I need the create a single vnic template with multiple vlans defined in that list.
Another engineer i work with was able to solve the question. By the way the variables are laid out we were able to easily just change the code
Change this:
vlans_list:
- name: "{{ item.1.name }}"
native: "{{ item.1.native }}"
state: "{{ item.1.present }}"
To this:
vlans_list: "{{ item.vlans_list }}"
Full Code listed below.
- name: Add vNIC Templates
ucs_vnic_template:
hostname: "{{ ucs_manager_hostname }}"
username: "{{ ucs_manager_username }}"
password: "{{ ucs_manager_password }}"
name: "{{ item.name }}"
fabric: "{{ item.fabric }}"
mac_pool: "{{ item.mac_pool }}"
mtu: "{{ item.mtu }}"
org_dn: "{{ item.org_dn }}"
redundancy_type: "{{ item.redundancy_type }}"
state: "{{ item.state }}"
template_type: "{{ item.template_type }}"
vlans_list: "{{ item.vlans_list }}"
with_items:
- "{{ vnic_templates }}"

Ansible : defined variable or output from ansible task as a variable

Hi I am trying to get a task setup which is as below.
- name: Create a route53 record for RDS instance.
route53:
state: present
aws_access_key: "{{ aws_create_route53_record.access_key }}"
aws_secret_key: "{{ aws_create_route53_record.secret_key }}"
zone: "{{ aws_create_route53_record.zone }}"
hosted_zone_id: "{{ aws_create_route53_record.id }}"
type: "{{ aws_create_route53_record.type }}"
value: "{{ aws_create_route53_record.value }}"
record: "{{ aws_create_route53_record.record }}"
private_zone: "{{ aws_create_route53_record.private_zone }}"
ttl: 30
Now I know passing variable from group_vars/all.yml I can define aws_create_route53_record.value in group_vars/all.yml and use it however in certain cases there is possibility where I am going to use this task as role and want to pass aws_create_route53_record.value runtime from previous task to this one and use it in creation of route53 record. for e.g. creating a rds instance using ansible task and use rds endpoint as value for route53_record
Any suggestion would help a lot. Thanks
Note: I've checked rds module page for return values which I thought would use instantly to solve this however there is no provision for endpoint return in it.
I was able to solve my problem by using a variable in my task and initially assigning it the value of group_vars variable and putting a condition that if after assigning a value of group_vars variable, variable is still blank then take a value from last task. Below is the code snippet which works fine. You would need to register variable from previous task as endpoint_host
---
-
name: "Set facts of record value"
set_fact:
record_value: "{{ aws_create_route53_record.value }}"
-
name: "If record value not present, Look for endpoint-host variable"
set_fact:
record_value: "{{ endpoint_host }}"
when: "aws_create_route53_record.value == \"\""
-
name: "Create a route53 record for RDS instance."
route53:
aws_access_key: "{{ aws_create_route53_record.access_key }}"
aws_secret_key: "{{ aws_create_route53_record.secret_key }}"
hosted_zone_id: "{{ aws_create_route53_record.hosted_zone_id }}"
private_zone: "{{ aws_create_route53_record.private_zone }}"
record: "{{ aws_create_route53_record.record }}"
state: present
ttl: 30
type: "{{ aws_create_route53_record.type }}"
value: "{{ record_value }}"
zone: "{{ aws_create_route53_record.zone }}"
Hope this helps.

How can i assign a varaible in a variable

Here's my task.
- name: Add A record for "{{ ec2_hostname }}.{{ internal_domain }}"
route53:
command: create
zone: "{{ internal_domain }}"
private_zone: "{{ private_type }}"
record: "{{ ec2_hostname }}.{{ internal_domain }}"
type: A
ttl: 300
value: "{{ ansible_ec2_[ec2_r53_type]_ipv4 }}"
Specifically having trouble with this line:
value: "{{ ansible_ec2_[ec2_r53_type]_ipv4 }}"
I need to insert ec2_r53_type inside a string to create another variable. This should be either "public" or "local".
So the expected result should be
value: "{{ ansible_ec2_local_ipv4 }}"
or
value: "{{ ansible_ec2_public_ipv4 }}"
Whats the logic here, tried all i knew no luck
This should work
value: "{{ vars['ansible_ec2_' + ec2_r53_type + '_ipv4'] }}"
- find: ^CODEDEPLOY_USER=""
replace: CODEDEPLOY_USER=""{{ app_install_user }}""
"/"{{ app_install_user }}/"" something as such, This is on the vars folder of a play
I would require to add the variable in qoutes on the vars of roles.
roles/xxxx/vars/main.yml
app_install_user is added on group_vars of ansible

Ansible: Access facts set by set_fact

I need to be able to set variables using tasks in Ansible. I use set_fact for this, but cannot seem to access the fact I set with this. What is wrong with the code below:
- name: kludge1
set_fact: fake_y = "{{ [] }}"
- name: Loop
debug:
msg: "{{ item }}"
with_items: "{{ fake_y }}"
You have spaces before and after =...
- name: kludge1
set_fact: fake_y="{{ [] }}"
Avoid var= shortcut syntax. Use original YAML syntax instead, it gives less errors:
- name: kludge1
set_fact:
fake_y: "{{ [] }}"

Resources