How to mount all ephemeral drive using ansible - amazon-ec2

I wan to spin up ec2 instance using ansible and then mount all available ephemeral drive to mount point.
I checked ec2 module but there isn't a way to activate all available ephemeral drive and then mount these drive.
If i want to do this then I need to write task specific to instance type like following.
- ec2:
key_name: mykey
group: webserver
instance_type: c3.xlarge
image: ami-123456
wait: yes
wait_timeout: 500
volumes:
- device_name: /dev/xvda
volume_type: standard
volume_size: 100
- device_name: /dev/xvdb
volume_type: ephemeral
volume_size: 40
- device_name: /dev/xvd
volume_type: ephemeral
volume_size: 40
vpc_subnet_id: subnet-29e63245
assign_public_ip: yes
exact_count: 1
Is there any way to parameterize following part
volumes:
- device_name: /dev/xvda
volume_type: standard
volume_size: 100
- device_name: /dev/xvdb
volume_type: ephemeral
volume_size: 40
- device_name: /dev/xvd
volume_type: ephemeral
volume_size: 40
any one know how to do this ?
Thanks

My solution for that was to have a pre-defined list of the volume types per instance, usually in group_vars/all but could be anywhere else as long as it is visible to your role. Something like:
one_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
two_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
three_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
four_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
- { device_name: /dev/sde, ephemeral: ephemeral3 }
ephemeral_volumes:
c1.medium: "{{ one_ephemeral }}"
c1.xlarge: "{{ four_ephemeral }}"
c3.large: "{{ two_ephemeral }}"
c3.xlarge: "{{ two_ephemeral }}"
c3.2xlarge: "{{ two_ephemeral }}"
c3.4xlarge: "{{ two_ephemeral }}"
c3.8xlarge: "{{ two_ephemeral }}"
i2.xlarge: "{{ one_ephemeral }}"
i2.2xlarge: "{{ two_ephemeral }}"
i2.4xlarge: "{{ four_ephemeral }}"
m1.small: "{{ one_ephemeral }}"
m1.medium: "{{ one_ephemeral }}"
m1.large: "{{ two_ephemeral }}"
m1.xlarge: "{{ four_ephemeral }}"
m2.xlarge: "{{ one_ephemeral }}"
m2.2xlarge: "{{ one_ephemeral }}"
m2.4xlarge: "{{ two_ephemeral }}"
m3.medium: "{{ one_ephemeral }}"
m3.large: "{{ one_ephemeral }}"
m3.xlarge: "{{ two_ephemeral }}"
m3.2xlarge: "{{ two_ephemeral }}"
r3.large: "{{ one_ephemeral }}"
r3.xlarge: "{{ one_ephemeral }}"
r3.2xlarge: "{{ one_ephemeral }}"
r3.4xlarge: "{{ one_ephemeral }}"
r3.8xlarge: "{{ two_ephemeral }}"
Then, when calling ec2 or ec2_lc modules I concatenate that to the list of volumes - something like:
volumes: "{{ instance_conf.volumes + (ephemeral_volumes[instance_conf.instance_type]|default([])) }}"
Here's how it fits in the module's call:
local_action:
module: ec2_lc
image_id: "{{ instance_conf.ami }}"
instance_type: "{{ instance_conf.instance_type }}"
instance_profile_name: "{{ instance_conf.instance_profile }}"
key_name: "{{ instance_conf.key_name | default(omit) }}"
name: "{{ instance_conf.name }}-lc"
region: "{{ instance_conf.region }}"
assign_public_ip: "{{ instance_conf.assign_public_ip | default(omit) }}"
security_groups: "{{ instance_conf.security_groups }}"
volumes: "{{ instance_conf.volumes + (ephemeral_volumes[instance_conf.instance_type]|default([])) }}"
state: present
user_data: "{{ lookup('template', instance_conf.userdata_template | default('userdata.sh.j2')) }}"

Here is an updated ec2 instance list
one_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
two_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
three_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
four_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
- { device_name: /dev/sde, ephemeral: ephemeral3 }
six_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
- { device_name: /dev/sde, ephemeral: ephemeral3 }
- { device_name: /dev/sdf, ephemeral: ephemeral4 }
- { device_name: /dev/sdg, ephemeral: ephemeral5 }
eight_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
- { device_name: /dev/sde, ephemeral: ephemeral3 }
- { device_name: /dev/sdf, ephemeral: ephemeral4 }
- { device_name: /dev/sdg, ephemeral: ephemeral5 }
- { device_name: /dev/sdh, ephemeral: ephemeral6 }
- { device_name: /dev/sdi, ephemeral: ephemeral7 }
twelve_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
- { device_name: /dev/sde, ephemeral: ephemeral3 }
- { device_name: /dev/sdf, ephemeral: ephemeral4 }
- { device_name: /dev/sdg, ephemeral: ephemeral5 }
- { device_name: /dev/sdh, ephemeral: ephemeral6 }
- { device_name: /dev/sdi, ephemeral: ephemeral7 }
- { device_name: /dev/sdj, ephemeral: ephemeral8 }
- { device_name: /dev/sdk, ephemeral: ephemeral9 }
- { device_name: /dev/sdl, ephemeral: ephemeral10 }
- { device_name: /dev/sdm, ephemeral: ephemeral11 }
twenty_four_ephemeral:
- { device_name: /dev/sdb, ephemeral: ephemeral0 }
- { device_name: /dev/sdc, ephemeral: ephemeral1 }
- { device_name: /dev/sdd, ephemeral: ephemeral2 }
- { device_name: /dev/sde, ephemeral: ephemeral3 }
- { device_name: /dev/sdf, ephemeral: ephemeral4 }
- { device_name: /dev/sdg, ephemeral: ephemeral5 }
- { device_name: /dev/sdh, ephemeral: ephemeral6 }
- { device_name: /dev/sdi, ephemeral: ephemeral7 }
- { device_name: /dev/sdj, ephemeral: ephemeral8 }
- { device_name: /dev/sdk, ephemeral: ephemeral9 }
- { device_name: /dev/sdl, ephemeral: ephemeral10 }
- { device_name: /dev/sdm, ephemeral: ephemeral11 }
- { device_name: /dev/sdn, ephemeral: ephemeral12 }
- { device_name: /dev/sdo, ephemeral: ephemeral13 }
- { device_name: /dev/sdp, ephemeral: ephemeral14 }
- { device_name: /dev/sdq, ephemeral: ephemeral15 }
- { device_name: /dev/sdr, ephemeral: ephemeral16 }
- { device_name: /dev/sds, ephemeral: ephemeral17 }
- { device_name: /dev/sdt, ephemeral: ephemeral18 }
- { device_name: /dev/sdu, ephemeral: ephemeral19 }
- { device_name: /dev/sdv, ephemeral: ephemeral20 }
- { device_name: /dev/sdw, ephemeral: ephemeral21 }
- { device_name: /dev/sdx, ephemeral: ephemeral22 }
- { device_name: /dev/sdy, ephemeral: ephemeral23 }
ephemeral_volumes:
c1.medium: "{{ one_ephemeral }}"
c1.xlarge: "{{ four_ephemeral }}"
c3.large: "{{ two_ephemeral }}"
c3.xlarge: "{{ two_ephemeral }}"
c3.2xlarge: "{{ two_ephemeral }}"
c3.4xlarge: "{{ two_ephemeral }}"
c3.8xlarge: "{{ two_ephemeral }}"
cc2.8xlarge: "{{ four_ephemeral }}"
cg1.4xlarge: "{{ two_ephemeral }}"
cr1.8xlarge: "{{ two_ephemeral }}"
d2.xlarge: "{{ three_ephemeral }}"
d2.2xlarge: "{{ six_ephemeral }}"
d2.4xlarge: "{{ twelve_ephemeral }}"
d2.8xlarge: "{{ twenty_four_ephemeral }}"
g2.2xlarge: "{{ one_ephemeral }}"
hi1.xlarge: "{{ two_ephemeral }}"
hs1.xlarge: "{{ twenty_four_ephemeral }}"
i2.xlarge: "{{ one_ephemeral }}"
i2.2xlarge: "{{ two_ephemeral }}"
i2.4xlarge: "{{ four_ephemeral }}"
i2.8xlarge: "{{ eight_ephemeral }}"
m1.small: "{{ one_ephemeral }}"
m1.medium: "{{ one_ephemeral }}"
m1.large: "{{ two_ephemeral }}"
m1.xlarge: "{{ four_ephemeral }}"
m2.xlarge: "{{ one_ephemeral }}"
m2.2xlarge: "{{ one_ephemeral }}"
m2.4xlarge: "{{ two_ephemeral }}"
m3.medium: "{{ one_ephemeral }}"
m3.large: "{{ one_ephemeral }}"
m3.xlarge: "{{ two_ephemeral }}"
m3.2xlarge: "{{ two_ephemeral }}"
r3.large: "{{ one_ephemeral }}"
r3.xlarge: "{{ one_ephemeral }}"
r3.2xlarge: "{{ one_ephemeral }}"
r3.4xlarge: "{{ one_ephemeral }}"
r3.8xlarge: "{{ two_ephemeral }}"
x1.16xlarge: "{{ one_ephemeral }}"
x1.32xlarge: "{{ two_ephemeral }}"

Related

Ansible adding items to nested list

starting data:
ok: [test#test.com] => {
"msg": {
"testdb1": {
"dbe_user_not_in_db": [
"test_user1",
"test_user2"
],
}
}
}
I currently have the following in ansible:
- name: Create dbe_pass_pairs
set_fact:
ora_sid_home_map: "{{ora_sid_home_map|combine({ item[0].key: {'dbe_pass_pairs': {item[1]: password} }}, recursive=True)}}"
loop: "{{ ora_sid_home_map | dict2items | subelements('value.dbe_user_not_in_db') }}"
vars:
password: "{{ lookup('password', '/dev/null length=10 chars=ascii_letters,digits') }}"
Which yields:
ok: [test#test.com] => {
"msg": {
"testdb1": {
"dbe_pass_pairs": {
"test_user1": "4SS2kJ7p0z",
"test_user2": "VLIzNfoaxf"
},
"dbe_user_not_in_db": [
"test_user1",
"test_user2"
],
}
}
}
Instead of dbe_pass_pairs containing dictionary items I'd like them to be a list of strings like such with a semicolon as:
ok: [test#test.com] => {
"msg": {
"testdb1": {
"dbe_pass_pairs": [
"test_user1;4SS2kJ7p0z",
"test_user2;VLIzNfoaxf"
],
"dbe_user_not_in_db": [
"test_user1",
"test_user2"
],
}
}
}
Doing something like the following just overwrite the list instead of appending:
- name: Create dbe_pass_pairs
set_fact:
ora_sid_home_map: "{{ora_sid_home_map|combine({ item[0].key: {'dbe_pass_pairs': [item[1] + ';' + password] }}, recursive=True)}}"
loop: "{{ ora_sid_home_map | dict2items | subelements('value.dbe_user_not_in_db') }}"
vars:
password: "{{ lookup('password', '/dev/null length=10 chars=ascii_letters,digits') }}"
"dbe_pass_pairs": [
"test_user2;AxL6ayeZIH"
],
Any idea how to get what I'm looking for data wise?
a solution using jinja2:
- name: Reproduce issue
hosts: localhost
gather_facts: yes
vars:
ora_sid_home_map:
testdb1:
dbe_user_not_in_db: ["test_user1", "test_user2"]
tasks:
- name: Create paswords
set_fact:
ora_sid_home_map: >-
{%- set ns=namespace(result=[], ident="", final={}) -%}
{%- set ns.ident = ora_sid_home_map |first -%}
{%- for user in ora_sid_home_map[ns.ident].dbe_user_not_in_db -%}
{%- set password = lookup('password', '/dev/null length=10 chars=ascii_letters,digits') -%}
{%- if ns.result.append(user ~ ';' ~ password) -%}{%- endif -%}
{%- endfor -%}
{{ {ns.ident: ora_sid_home_map[ns.ident] | combine({'dbe_pass_pairs': ns.result})} }}
- debug:
msg: "{{ ora_sid_home_map }}"
result:
ok: [localhost] => {
"msg": {
"testdb1": {
"dbe_pass_pairs": [
"test_user1;tPOSfCzLLq",
"test_user2;e0A92Dkuac"
],
"dbe_user_not_in_db": [
"test_user1",
"test_user2"
]
}
}
}
without jinja2:
- name: Reproduce issue
hosts: localhost
gather_facts: yes
vars:
ora_sid_home_map:
testdb1:
dbe_user_not_in_db: ["test_user1", "test_user2"]
tasks:
- name: Create paswords
set_fact:
passwords: "{{ passwords | d([]) + [data] }}"
loop: "{{ ora_sid_home_map[ident].dbe_user_not_in_db }}"
vars:
password: "{{ lookup('password', '/dev/null length=10 chars=ascii_letters,digits') }}"
data: "{{ item ~ ';' ~ password }}"
ident: "{{ ora_sid_home_map|first }}"
- name: result
set_fact:
ora_sid_home_map: "{{ {ident: data} }}"
vars:
ident: "{{ ora_sid_home_map|first }}"
data: "{{ ora_sid_home_map[ident]| combine({'dbe_pass_pairs': passwords}) }}"
- debug:
msg: "{{ ora_sid_home_map }}"

SUM value from 2 lists

I have the following outputs:
{
"vmoff": [
{
"CONT2": [
"vm1",
"vm2",
"vm5"
]
},
{
"CONT1": [
"vm3",
"vm4",
"vm6"
]
}
]
}
AND
{
"vmprof2": [
{
"proc": {
"vm1": "0.5",
"vm2": "0.7",
"vm3": "1.0",
"vm4": "0.5",
"vm5": "0.5",
"vm6": "0.5"
},
"sec_sys": "CONT1"
},
{
"proc": {
"vm1": "1.0",
"vm2": "0.7",
"vm3": "1.0",
"vm4": "0.7",
"vm5": "0.5",
"vm6": "0.7"
},
"sec_sys": "CONT2"
}
]
}
I want to sum the value of proc of each vm in vmoff, for example:
proc_steal:
- sec_sys: CONT1
proc: 2.0
- sec_sys: CONT2
proc: 2.2
Obtain the proc of the not activated vm, I'm getting confused on the output, don't know to use list or dict.
I suggest you to use a custom filter:
Create a folder filter_plugins at the same level as your playbook.
I created a file myfilter.py with a filter named extractfilter
.
├── filter_plugins
│ └── myfilter.py
└── playbook.yml
whith the following content:
#!/usr/bin/python
class FilterModule(object):
def filters(self):
return {
'extractfilter': self.extractfilter
}
def extractfilter(self, l1, l2):
result = []
ky = {}
for k in l1:
ky.update(k)
for k in l2:
s = k['sec_sys']
l = ky[s]
if s in ky:
total = 0.0
proc = k['proc']
for p in proc:
if p in l:
total = total + float(proc[p])
result.append({'sec_sys': s, 'proc': total})
return result
Then the playbook which uses the custom filter:
- name: testplaybook jinja2
hosts: localhost
gather_facts: no
vars:
vmoff:
- CONT2:
- vm1
- vm2
- vm5
- CONT1:
- vm3
- vm4
- vm6
vmprof2:
- proc:
vm1: '0.5'
vm2: '0.7'
vm3: '1.0'
vm4: '0.5'
vm5: '0.5'
vm6: '0.5'
sec_sys: CONT1
- proc:
vm1: '1.0'
vm2: '0.7'
vm3: '1.0'
vm4: '0.7'
vm5: '0.5'
vm6: '0.7'
sec_sys: CONT2
tasks:
- name: DEFINE VARIABLE SPINE
set_fact:
proc_steal: "{{ vmoff | extractfilter(vmprof2) }}"
- debug: msg="{{ proc_steal }}"
result:
{
"msg": [
{
"proc": 2.0,
"sec_sys": "CONT1"
},
{
"proc": 2.2,
"sec_sys": "CONT2"
}
]
}
If you have a problem with the custom filter you could use jinja:
- name: "make this working"
hosts: localhost
vars:
vmoff:
- CONT2:
- vm1
- vm2
- vm5
- CONT1:
- vm3
- vm4
- vm6
vmprof2:
- proc:
vm1: '0.5'
vm2: '0.7'
vm3: '1.0'
vm4: '0.5'
vm5: '0.5'
vm6: '0.5'
sec_sys: CONT1
- proc:
vm1: '1.0'
vm2: '0.7'
vm3: '1.0'
vm4: '0.7'
vm5: '0.5'
vm6: '0.7'
sec_sys: CONT2
tasks:
- name: list to dict
set_fact:
ky: "{{ ky | d({}) | combine( item ) }}"
loop: "{{ vmoff }}"
- name: list to dict
set_fact:
result: "{{ result| d([]) + [{'sec_sys': s, 'proc': total}] }}"
loop: "{{ vmprof2 }}"
vars:
s: "{{ item['sec_sys'] }}"
l: "{{ ky[s] }}"
total: >-
{%- set st = namespace(tt=0.0) -%}
{%- for p in item['proc'] if p in l -%}
{%- set st.tt = st.tt + (item['proc'][p] | float) -%}
{%- endfor -%}
{{ st.tt | float }}
when: s in ky
- name: list to dict
debug:
msg: "{{ result }}"

How to iterate over variables in an ansible dictionary

I have a role that should scatter NGINX configs across different servers using Jinja2 templates, referring to the variables specified in defaults/main, please tell me how to write a loop to iterate over these variables correctly, tried it through with_items and with_nested, but nothing happens.
The defaults/main file looks like this:
allservers:
server1:
- { src: 'templates/sites-enabled/api.j2', dest: '/etc/nginx/sites-enabled/api.conf' }
- { src: 'templates/sites-enabled/citizens.j2', dest: '/etc/nginx/sites-enabled/citizens.conf' }
- { src: 'templates/sites-enabled/control.j2', dest: '/etc/nginx/sites-enabled/control.conf' }
- { src: 'templates/sites-enabled/documents.j2', dest: '/etc/nginx/sites-enabled/documents.conf' }
- { src: 'templates/sites-enabled/orders.j2', dest: '/etc/nginx/sites-enabled/orders.conf' }
- { src: 'templates/sites-enabled/logs.j2', dest: '/etc/nginx/sites-enabled/logs.conf' }
server2:
- { src: 'templates/sites-enabled/permissions.j2', dest: '/etc/nginx/sites-enabled/permissions.conf' }
- { src: 'templates/sites-enabled/documents.j2', dest: '/etc/nginx/sites-enabled/documents.conf' }
- { src: 'templates/sites-enabled/default.j2', dest: '/etc/nginx/sites-enabled/default' }
- { src: 'templates/sites-enabled/orders.j2', dest: '/etc/nginx/sites-enabled/orders.conf' }
- { src: 'templates/sites-enabled/settings.j2', dest: '/etc/nginx/sites-enabled/settings.conf' }
I assume you do not want to change your data structure, and that server1 and server2 refer to hosts in your inventory.
---
- hosts: server1:server2
remote_user: ansible
vars:
allservers:
server1:
- { src: "/tmp/file1", dest: "/tmp"}
- { src: "/tmp/file2", dest: "/tmp"}
- { src: "/tmp/file3", dest: "/tmp"}
server2:
- { src: "/tmp/file4", dest: "/tmp"}
- { src: "/tmp/file5", dest: "/tmp"}
- { src: "/tmp/file6", dest: "/tmp"}
tasks:
- name: Copy template
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
when: inventory_hostname in allservers.keys()
with_items:
- "{{ allservers[inventory_hostname] }}"
Another solutions is to include a task (copy_template.yml) which you will iterate over using with_dict: allservers.
playbook.yml
---
- hosts: server1:server2
remote_user: ansible
vars:
allservers:
server1:
- { src: "/tmp/file1", dest: "/tmp"}
- { src: "/tmp/file2", dest: "/tmp"}
- { src: "/tmp/file3", dest: "/tmp"}
server2:
- { src: "/tmp/file4", dest: "/tmp"}
- { src: "/tmp/file5", dest: "/tmp"}
- { src: "/tmp/file6", dest: "/tmp"}
tasks:
- include: copy_template.yml
vars:
server: "{{ item.key }}"
with_dict:
- "{{ allservers }}"
copy_template.yml
---
- debug:
msg: "{{ template.src }} and {{ template.dest }}"
loop: "{{ allservers[server] }}"
when: server == inventory_hostname
loop_control:
loop_var: template

Ansible merge listed dictionaries

I'm currently building a Ansible playbook which provides me with below two variables. I need to merge these into one variable where the ipAddresses match as showed in the example below.
---
- hosts: localhost
gather_facts: no
vars:
sites:
- siteGroupId: 123
siteName: name123
siteDevices:
- ipAddress: 1.1.1.1
- ipAddress: 2.2.2.2
- siteGroupId: 456
siteName: name456
siteDevices:
- ipAddress: 3.3.3.3
- ipAddress: 4.4.4.4
devices:
- ipAddress: 1.1.1.1
deviceName: name123-a.tld
- ipAddress: 2.2.2.2
deviceName: name123-b.tld
- ipAddress: 3.3.3.3
deviceName: name456-a.tld
- ipAddress: 4.4.4.4
deviceName: name456-b.tld
Expected output:
sites:
- siteGroupId: 123
siteName: name123
siteDevices:
- ipAddress: 1.1.1.1
deviceName: name123-a.tld
- ipAddress: 2.2.2.2
deviceName: name123-b.tld
- siteGroupId: 456
siteName: name456
siteDevices:
- ipAddress: 3.3.3.3
deviceName: name456-a.tld
- ipAddress: 4.4.4.4
deviceName: name456-b.tld
What I have succeed so far with the below code is that I get the name added to the site but get 4 sites (duplicated siteGroupID as output).
---
- hosts: localhost
gather_facts: no
vars:
sites:
- siteGroupId: 123
siteName: name123
siteDevices:
- ipAddress: 1.1.1.1
- ipAddress: 2.2.2.2
- siteGroupId: 456
siteName: name456
siteDevices:
- ipAddress: 3.3.3.3
- ipAddress: 4.4.4.4
devices:
- ipAddress: 1.1.1.1
deviceName: name123-a.tld
- ipAddress: 2.2.2.2
deviceName: name123-b.tld
- ipAddress: 3.3.3.3
deviceName: name456-a.tld
- ipAddress: 4.4.4.4
deviceName: name456-b.tld
tasks:
- set_fact:
tmpVar1: "{{ item.0 | combine({'siteDevices': [ item.1 | combine(devices | selectattr('ipAddress','equalto',item.1.ipAddress) | first) ] }) }}"
loop: "{{lookup('subelements', sites, 'siteDevices', {'skip_missing': True})}}"
register: tmpVar2
- name: tmpVar1
debug:
msg: "{{ tmpVar1 }}"
- name: tmpVar2
debug:
msg: "{{ tmpVar2 }}"
- set_fact:
sites: "{{ tmpVar2.results | map(attribute='ansible_facts.tmpVar1') | list }}"
- name: SITES
debug:
msg: "{{ sites }}"
OUTPUT:
{
"siteDevices": [
{
"deviceName": "name123-a.tld",
"ipAddress": "1.1.1.1"
}
],
"siteGroupId": 123,
"siteName": "name123"
},
{
"siteDevices": [
{
"deviceName": "name123-b.tld",
"ipAddress": "2.2.2.2"
}
],
"siteGroupId": 123,
"siteName": "name123"
},
{
"siteDevices": [
{
"deviceName": "name456-a.tld",
"ipAddress": "3.3.3.3"
}
],
"siteGroupId": 456,
"siteName": "name456"
},
{
"siteDevices": [
{
"deviceName": "name456-b.tld",
"ipAddress": "4.4.4.4"
}
],
"siteGroupId": 456,
"siteName": "name456"
}
The tasks
- set_fact:
devices_dict: "{{ devices|
items2dict(key_name='ipAddress',
value_name='deviceName') }}"
- set_fact:
sites2: "{{ sites2|default([]) + [
item|
combine({'siteDevices':
dict(my_ipAddress|
zip(my_ipAddress|
map('extract', devices_dict)))|
dict2items(key_name='ipAddress',
value_name='deviceName')})] }}"
vars:
my_ipAddress: "{{ item.siteDevices|json_query('[].ipAddress') }}"
loop: "{{ sites }}"
- debug:
var: sites2
give
"sites2": [
{
"siteDevices": [
{
"deviceName": "name123-a.tld",
"ipAddress": "1.1.1.1"
},
{
"deviceName": "name123-b.tld",
"ipAddress": "2.2.2.2"
}
],
"siteGroupId": 123,
"siteName": "name123"
},
{
"siteDevices": [
{
"deviceName": "name456-a.tld",
"ipAddress": "3.3.3.3"
},
{
"deviceName": "name456-b.tld",
"ipAddress": "4.4.4.4"
}
],
"siteGroupId": 456,
"siteName": "name456"
}
]

Create an AMI using ansible ec2_ami module and grab snapshot_id(s) from registered variable

I have the following playbook:
- hosts: localhost
connection: local
gather_facts: False
tasks:
- name: Read Variables
include_vars:
file: variables.yml
- name: Create AMI
ec2_ami:
aws_access_key: "{{ ACCESS_KEY }}"
aws_secret_key: "{{ SECRET_KEY }}"
region: "{{ AWS_REGION }}"
delete_snapshot: yes
instance_id: "{{ ID_INSTANCE }}"
name: "{{ SUFFIX_BACKUP }}-{{ NAME_BACKUP }}"
wait: yes
description: "{{ DESCR }}"
tags:
project: project1
register: ami_data
Example content of "ami_data" variable:
"msg": {
"architecture": "x86_64",
"block_device_mapping": {
"/dev/sda1": {
"delete_on_termination": true,
"encrypted": false,
"size": 30,
"snapshot_id": "snap-0e95eac98734af1d1",
"volume_type": "gp2"
}
},
"changed": false,
"creationDate": "2017-12-13T17:02:47.000Z",
"description": "descripition",
"failed": false,
"hypervisor": "xen",
"image_id": "ami-XXXXXX",
"is_public": false,
"launch_permissions": {},
"location": "457841571138/MYAMINAME",
"msg": "AMI not updated",
"name": "MYAMINAME",
"ownerId": "XXXXXXXXXX",
"platform": null,
"root_device_name": "/dev/sda1",
"root_device_type": "ebs",
"state": "available",
"tags": {
"project": "project1",
},
"virtualization_type": "hvm"
}
}
And now I want to grab the "snapshot_id" that was registered on "ami_data" variable for every disk on it. I have tried the following debug tasks using "msg" to show the value(s) of "snapshot_id" but non of them worked. What I'm doing wrong?
- name: Show data
debug:
msg: "{{ ami_data.block_device_mapping[*].snapshot_id }}"
- name: Show data
debug:
msg: "{{ ami_data.block_device_mapping[/dev/sda1].snapshot_id }}"
- name: Show data
debug:
msg: "{{ ami_data.block_device_mapping./dev/sda1.snapshot_id }}"
- name: Show data
debug:
msg: "{{ ami_data.block_device_mapping.[*].snapshot_id }}"
This one works:
- name: Show data
debug:
msg: "{{ ami_data.block_device_mapping }}"
And give me the following:
ok: [localhost] => {
"msg": {
"/dev/sda1": {
"delete_on_termination": true,
"encrypted": false,
"size": 30,
"snapshot_id": "snap-0ea846d9aca82b51f",
"volume_type": "gp2"
}
}
}
Firstly, with the ami_data.block_device_mapping you have to iterate with the list and after search under the map with the key name of the element (snapshot_id in this case):
- debug:
msg: {{ item }}
with_items: "{{ ami_data.block_device_mapping|map(attribute='snapshot_id')|list}}"
You were really close. Use square brackets but use quotes to specify literals:
- name: Show data
debug:
msg: "{{ ami_data.block_device_mapping['/dev/sda1'].snapshot_id }}"
or using variables:
- name: Show data
debug:
msg: "{{ ami_data.block_device_mapping[item].snapshot_id }}"
with_items: "{{ ami_data.block_device_mapping }}"

Resources