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

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.

Related

Conditional task based on template parameter fails

I'm trying to use Ansible to deploy to two regions in AWS, I have it working with one region at the moment. The issue is I want to only execute my primary_region or my secondary_region depending on the parameter from the template it's using.
My main.yaml:
- hosts: primary_region
name: Create ECR
tasks:
- name: "Create ECR Repository"
cloudformation:
state: "{{ state }}"
stack_name: "{{ stack_create_ecr.name }}"
profile: "{{ aws_profile }}"
region: "{{ inventory_hostname }}"
template_url: "{{ stack_create_ecr.template_url }}"
template_parameters:
"ansibleFile"
tags:
"{{ stack_create_ecr.tags }}"
tags:
- stack_create_ecr
when: stack_create_ecr.region == "primary_region" <-- This
- hosts: secondary_region
name: Create ECR
tasks:
- name: "Create ECR Repository"
cloudformation:
state: "{{ state }}"
stack_name: "{{ stack_create_ecr.name }}"
profile: "{{ aws_profile }}"
region: "{{ inventory_hostname }}"
template_url: "{{ stack_create_ecr.template_url }}"
template_parameters:
"ansibleFile"
tags:
"{{ stack_create_ecr.tags }}"
tags:
- stack_create_ecr
when: stack_create_ecr.region == "secondary_region" <-- This
The template that I am using
stack_create_ecr.yaml:
stack_create_ecr:
name: cloudFormationTemplateNameOmitted
template_url: S3BucketUrl
parameters:
RepoName: EcrRepoName
DevName: cloud-dev
tags:
ansible_playbook: "{{ ansible_playbook_tag }}"
region: primary_region <-- This is what I'm trying to use
Everytime I try to run my playbook I just get msg: 'argument template_parameters is of type <class ''str''> and we were unable to convert to dict: dictionary requested, could not parse JSON or key=value'
I have tried all sorts of things from putting quotes around the string in the when condition. Nothing seems to work, what am I doing wrong?
It seems you massed up with template_parameters prop. It should be a map but you provided a string:
template_parameters:
PropName: "ansibleFile"

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: ec2_eni cannot attach interface

Using ansible I am trying to create ec2 instances and attach an extra network interface to each instance so that they will have two private IP addresses. However, for some reason, it seems that the ec2_eni module can create network interfaces, but will not attach them to the instances specified. What am I doing wrong? Below is my playbook:
---
- hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Create new servers
ec2:
region: "{{ region }}"
vpc_subnet_id: "{{ subnet }}"
group_id: "{{ sec_group }}"
assign_public_ip: yes
wait: true
key_name: '{{ key }}'
instance_type: t2.micro
image: '{{ ami }}'
exact_count: '{{ count }}'
count_tag:
Name: "{{ server_name }}"
instance_tags:
Name: "{{ server_name }}"
register: ec2
- name: Show ec2 instance json data
debug:
msg: "{{ ec2['tagged_instances'] }}"
- name: allocate new elastic IPs and associate it with instances
ec2_eip:
region: "{{ region }}"
device_id: "{{ item['id'] }}"
with_items: "{{ ec2['tagged_instances'] }}"
register: eips
- name: Show eip instance json data
debug:
msg: "{{ eips['results'] }}"
- ec2_eni:
subnet_id: "{{ subnet }}"
state: present
secondary_private_ip_address_count: 1
security_groups: "{{ sec_group }}"
region: "{{ region }}"
device_index: 1
description: "test-eni"
instance_id: "{{ item['id'] }}"
with_items: "{{ ec2['tagged_instances'] }}"
The strange thing is that the ec2_eni task succeeds, saying that it has attached the network interface to each instance when in reality it just creates the network interface and then does nothing with it.
As best I can tell, since attached defaults to None, but the module docs say:
Specifies if network interface should be attached or detached from instance. If ommited, attachment status won't change
then the code does what they claim and skips the attachment step.
This appears to be a bug in the documentation, which claims the default is 'yes' but is not accurate.

How to use list variables defined using 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 }}"

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

Resources