is it possible to add a condition statement in .yml file ansible? - if-statement

I have created a role and a playbook , Now in my playbook , I am defining Ec2 tags such as :
instance_tags: "Name={{ name }},bld_env={{ bld_env }},server={{ app_name }}-{{ bld_env }}"
I also have to make a condition here for bld_env thats suppose if bld_env is "test", add more tags .
can you help me out with tagging in case of conditional statement ?
Eg:
My
tagging.yml
file :
- name: Launch EC2 host
hosts: localhost
connection: local
gather_facts: False
vars:
bld_env: "{{ bld_env }}"
count: 1
instance_type: "{{ size }}"
image: "{{ image }}"
ansible_ssh_user: "ec2-user"
region: "{{ region }}"
pem_path: "~/.ssh"
group_name: "ec2hosts"
vpc_subnet_id: "{{ lookup('ini', 'vpc_subnet section=vpc file=./{{ bld_env }}.ini') }}"
assign_public_ip: "{{ ip }}"
keypair: "{{ key }}"
access_key: "{{ access }}"
secret_key: "{{ secret }}"
instance_tags: "Name={{ name }},bld_env={{ bld_env }},server={{ app_name }}-{{ bld_env }}"
security_group: "[{{ group }}]"
roles:
- ec2
Now as you can see the instance_tags here , I want to add a condition under this instance_tags as : when bld_env is "test" add another tag "Label=ec2start-stop"
So this Label has to be added only when bld_env is "test" since I am dealing with multiple env here ..

You can use any Jinja2 conditions inside expressions, for example (see end of line):
instance_tags: "Name={{ name }},bld_env={{ bld_env }},server={{ app_name }}-{{ bld_env }}{{ '' if bld_env != 'test' else ',other_tag='+other_tag_value }}"
This will append empty line if bld_env != 'test' or ,other_tag=<other_tag_value> otherwise.

Related

Check if EC2 instances exists and running then skip deployment

I am trying to run a playbook that calls a role to deploy some EC2 instances, everything works fine except that I want to put a condition when the EC2 instance exists and in running state to skip the deployment I used the following to retrieve the ec2_infos :
## Check if an instance with same name exist on AWS
- name: Get {{ ec2_name }} infos
ec2_instance_info:
region: "us-east-1"
filters:
"tag:Name": "{{ ec2_name }}"
instance-state-name: [ "running"]
register: ec2_infos
- name: DEBUG
debug: msg="{{ aws_ec2_infos }}"
and on the Deployment stage my condition is as follows :
- name: "{{ ec2_description }} - {{ ec2_name }}"
cloudformation:
stack_name: "some name "
state: "present"
region: "{{ aws_region }}"
template: "PATH/ec2.json"
template_parameters:
Name: "{{ ec2_name }}"
Description: "{{ ec2_description }}"
KeyName: "{{key_name }}"
KmsKeyId: "{{ key_id }}"
GroupSet: "{{ id }}"
IamInstanceProfile: "{{ name }}"
Type: "OS"
**when: ec2_infos.state[0].name != 'running'**
but I get an error that says :
"msg": "The conditional check 'aws_ec2_infos.state[0].name != 'running'' failed. The error was: error while evaluating conditional (aws_ec2_infos.state[0].name != 'running'): 'dict object' has no attribute
I think I am missing something in my condition but I can't find what exactly. Any tip or advice is more than welcome
As #benoit and #mdaniel said the error was in my understanding the condition should be :
aws_ec2_infos.instances[0].state.name != 'running'

Ansible "ec2_asg" module keeps changing the desired/min/max capacity settings

For cost reasons, our ASG's in the QA environment run with desired/min/max capacity set to "1". That's not the case for Production but since we use the same code for QA and Prod deployment (minus a few variables of course) this is causing problems with the QA automation jobs.
- name: create autoscale groups original_lc
ec2_asg:
name: "{{ app_name }}"
target_group_arns: "{{alb_target_group_facts.target_groups[0].target_group_arn}}"
launch_config_name: "{{ launch_config.name }}"
min_size: 1
max_size: 1
desired_capacity: 1
region: "{{ region }}"
vpc_zone_identifier: "{{ subnets | join(',') }}"
health_check_type: "{{health_check}}"
replace_all_instances: yes
wait_for_instances: false
replace_batch_size: '{{ rollover_size }}'
lc_check: false
default_cooldown: "{{default_cooldown}}"
health_check_period: "{{health_check_period}}"
notification_topic: "{{redeem_notification_group}}"
tags:
- Name : "{{ app_name }}"
- Application: "{{ tag_Application }}"
- Product_Owner: "{{ tag_Product_Owner }}"
- Resource_Owner: "{{ tag_Resource_Owner }}"
- Role: "{{ tag_Role }}"
- Service_Category: "{{ tag_Service_Category }}"
register: asg_original_lc
On the first run, the "ec2_asg" module creates the group properly, with the correct desired/min/max settings.
But when we run the job a second time to update the same ASG, it changes desired/min/max to "2" in AWS. We don't want that. We just want it to rotate out that one instance in the group. Is there a way to achieve that?

Is it possible to loop into two different lists in the same playbook (Ansible)?

I'm writing a Playbook Ansible and I want to loop into two different lists.
I now that I can use with_items to loop in a list, but can I use with_items twice in the same playbook?
Here is what I want to do:
- name: Deploy the network in fabric 1 and fabric 2
tags: [merged]
role_network:
config:
- net_name: "{{ networkName }}"
vrf_name: "{{ vrf }}"
net_id: 30010
net_template: "{{ networkTemplate }}"
net_extension_template: "{{ networkExtensionTemplate }}"
vlan_id: "{{ vlan }}"
gw_ip_subnet: "{{ gw }}"
attach: "{{ item }}"
deploy: false
fabric: "{{ item }}"
state: merged
with_items:
- "{{ attachs }}"
"{{ fabric }}"
register: networks
So for the first call, I want to use the playbook with fabric[0] and attachs[0].
For the second call, I want to use the playbook with fabric[1] and attachs[1].
And so on...
Can someone help me please?
What you are looking to achieve is what was with_together and that is, now, recommanded to achieve with the zip filter.
So: loop: "{{ attachs | zip(fabric) | list }}".
Where the element of the first list (attachs) would be item.0 and the element of the second list (fabric) would be item.1.
- name: Deploy the network in fabric 1 and fabric 2
tags: [merged]
role_network:
config:
- net_name: "{{ networkName }}"
vrf_name: "{{ vrf }}"
net_id: 30010
net_template: "{{ networkTemplate }}"
net_extension_template: "{{ networkExtensionTemplate }}"
vlan_id: "{{ vlan }}"
gw_ip_subnet: "{{ gw }}"
attach: "{{ item.0 }}"
deploy: false
fabric: "{{ item.1 }}"
state: merged
loop: "{{ attachs | zip(fabric) | list }}"
register: networks

Ansible undefined variable

i have role for Route53 (http://docs.ansible.com/ansible/route53_module.html) and task is:
- name: "SET DNS record"
route53:
aws_access_key: "ACCESSKEY"
aws_secret_key: "SECRET"
command: "create"
zone: "{{ dns_zone }}"
hosted_zone_id: "{{ dns_zone_id }}"
record: "{{ item.dns_record }}"
type: "{{ item.dns_type }}"
ttl: "{{ item.dns_ttl }}"
value: "{{ item.dns_value }}"
failover: "{{item.failover}}"
health_check: "{{item.health_check}}"
identifier: "{{item.identifier}}"
with_items:
- "{{ dns_records }}"
Example of DNS records:
dns_records:
- dns_record: "try1.example.com"
dns_type: "A"
dns_ttl: "3600"
dns_value: "1.1.1.1"
failover: "PRIMARY"
health_check: "aeejas728asd"
identifier: "identifier01"
- dns_record: "try2.example.com"
dns_type: "A"
dns_ttl: "3600"
dns_value: "2.2.2.2"
If i run paybook role FAILS because second value have undefined failover, health_check and identifier. How can i set expression for IF else?
My try:
identifier: "{{item.identifier if item.identifier is defined else '!'}}"
is not working. I need IF not defined THEN IGNORE VALUE.
Thanks for help!
From the docs:
identifier: "{{item.identifier|default(omit)}}"

how to add a disk to vcenter guest using Ansible

I'm attempting to add a second disk to a vmware vcenter instance.
Here is what I have:
- name: "Modifying ..."
local_action:
module: vsphere_guest
vcenter_hostname: "{{ vcenter.hostname }}"
username: "{{ vcenter_user[datacenter]['username'] }}"
password: "{{ vcenter_user[datacenter]['password'] }}"
guest: "{{ inventory_hostname }}"
# Looky looky heeya ...#
state: reconfigured
########################
vm_extra_config:
vcpu.hotadd: yes
mem.hotadd: yes
notes: "{{ datacenter }} {{ purpose |replace('_',' ') }}"
vm_disk:
disk1:
size_gb: 50
type: thin
datastore: "{{ vcenter.datastore }}"
disk2:
size_gb: 200
type: thin
datastore: "{{ vcenter.datastore }}"
vm_hardware:
memory_mb: "{{ vm.memory|int }}"
num_cpus: "{{ vm.cpus|int }}"
osid: "{{ os.id }}"
esxi:
datacenter: "{{ esxi.datacenter }}"
hostname: "{{ esxi.hostname }}"
So the vcenter sees the reconfigure and there are no errors displayed.
Also there are no errors on the console when I runt the playbook.
It just simply does not add the second disk.
So is there a way to add the disk or will I have to write a python script to do it?
Thanks.
The function def reconfigure_vm in the vsphere_guest module does only include code for changing the RAM and the CPU. But i don't see any code for changing the other hardware. This is only possible while creating a new VM at the moment.