Items are overwritten in Task - ansible

We're trying to fill an Palo Alto Object Group with multiple objects.
Our current script does run through all the items in the following line:
static_value: "{{ item[1].addressobjectname|join }}"
But only registers the last object.
For Example:
We have 3 objects in the list. So we expect to add object 1, 2, 3.
Instead the script only registers the 3 and 1 and 2 are overwritten in the process.
How should we fix this?
This is our code:
- name: Create object group
with_nested:
- "{{ tag_firewall# }}"
- "{{ addressobjects }}"
panos_address_group:
provider: "{{ palo_provider }}"
name: "Prisma-Unsecure"
static_value: "{{ item[1].addressobjectname|join }}"
tag: ["ansible_test_tag"]
device_group: "{{ item[0] }}"
description: "Created by ansible automation"
commit: 'no'
Thanks in advance!
As mentioned before we expect all items to be added to the group in stead of the last one in the list.

Hard to say without the precision asked by Vladimir in comments. Meanwhile it looks like you are creating an address group for each addressojects for each firewall definition. My guess at this stage is that the last one wins with the latest address.
Guess again: I believe you want to create one group with all adresses, something like the following (to be tested and adapted with your actual input data):
- name: Create object group
loop: "{{ tag_firewall# }}"
panos_address_group:
provider: "{{ palo_provider }}"
name: "Prisma-Unsecure"
static_value: "{{ addressobjects | map(attribute='addressobjectname') }}"
tag: ["ansible_test_tag"]
device_group: "{{ item }}"
description: "Created by ansible automation"
commit: 'no'

My guess is to remove the join filter. For example,
shell> cat pb.yml
- hosts: localhost
vars:
tag_firewall: [Prod1, Prod2]
addressobjects:
- addressobjectname: [Test-One, Test-Three]
- addressobjectname: [Test-Two, Test-Four]
tasks:
- debug:
msg: |
panos_address_group:
provider: Palo_provider_dict
name: Prisma-Unsecure
static_value: "{{ item.1.addressobjectname }}"
tag: Ansible_test_tag
device_group: "{{ item.0 }}"
description: Created by Ansible automation
commit: false
with_nested:
- "{{ tag_firewall }}"
- "{{ addressobjects }}"
shows the iteration
shell> ansible-playbook pb.yml
PLAY [localhost] *****************************************************************************
TASK [debug] *********************************************************************************
ok: [localhost] => (item=['Prod1', {'addressobjectname': ['Test-One', 'Test-Three']}]) =>
msg: |-
panos_address_group:
provider: Palo_provider_dict
name: Prisma-Unsecure
static_value: "['Test-One', 'Test-Three']"
tag: Ansible_test_tag
device_group: "Prod1"
description: Created by Ansible automation
commit: false
ok: [localhost] => (item=['Prod1', {'addressobjectname': ['Test-Two', 'Test-Four']}]) =>
msg: |-
panos_address_group:
provider: Palo_provider_dict
name: Prisma-Unsecure
static_value: "['Test-Two', 'Test-Four']"
tag: Ansible_test_tag
device_group: "Prod1"
description: Created by Ansible automation
commit: false
ok: [localhost] => (item=['Prod2', {'addressobjectname': ['Test-One', 'Test-Three']}]) =>
msg: |-
panos_address_group:
provider: Palo_provider_dict
name: Prisma-Unsecure
static_value: "['Test-One', 'Test-Three']"
tag: Ansible_test_tag
device_group: "Prod2"
description: Created by Ansible automation
commit: false
ok: [localhost] => (item=['Prod2', {'addressobjectname': ['Test-Two', 'Test-Four']}]) =>
msg: |-
panos_address_group:
provider: Palo_provider_dict
name: Prisma-Unsecure
static_value: "['Test-Two', 'Test-Four']"
tag: Ansible_test_tag
device_group: "Prod2"
description: Created by Ansible automation
commit: false
PLAY RECAP ***********************************************************************************
localhost: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Related

Ansible Executing Nested Variable Loops on Multiple Files

I want to perform the following command using an Ansible playbook:
sed -i.bak 's/^mirror/#mirror/;s/#baseurl/baseurl/;s/mirror.centos/vault.centos/' /etc/yum.repos.d/CentOS-*.repo
A basic working Ansible playbook looks like this:
---
- name: Resolve any CentOS issues
hosts: "{{ nodes }}"
tasks:
- shell: sed -i.bak 's/^mirror/#mirror/;s/#baseurl/baseurl/;s/mirror.centos/vault.centos/' /opt/yum.repos.d/CentOS-*.repo
However, I would like to create a more advanced playbook, which *might *look something like this:
---
- name: Modify CentOS Reps
hosts: localhost
vars:
filelist: []
reg:
- ^mirrorlist
- ^#baseurl
- mirror.centos
rep:
- #mirror
- baseurl
- vault.centos
tasks:
- name: Find matching repo files and register to a variable
find:
paths: /etc/yum.repos.d
file_type: file
recurse: no
patterns: CentOS-*.repo
register: output
- name: Adding filelist to the LIST
no_log: true
set_fact:
filelist: "{{ filelist + [item.path]}}"
with_items: "{{ output.files }}"
- debug: var=filelist
- name: Change the lines
replace:
path: "{{ item.0 }}"
regexp: "{{ item.1.regexp }}"
replace: "{{ item.1.replace }}"
backup: true
with_nested:
- "{{ filelist }}"
- '{ regexp: "{{ reg }}", replace: "{{ rep }}" }'
The above gives the following attribute error:
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'regexp'\n\nThe error appears to be in '/etc/ansible/playbooks/centos-correct-repo301.yml': line 33, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Change the lines\n ^ here\n"}
Any thoughts?
Thanks
There are more options. For example,
Put the regex/replace logic into a dictionary
reg_rep:
- {reg: '^mirror', rep: '#mirror'}
- {reg: '^#baseurl', rep: 'baseurl'}
- {reg: 'mirror.centos', rep: 'vault.centos'}
Declare the list of the files
filelist: "{{ output.files|map(attribute='path')|list }}"
and find the files (no changes to your code in this task)
- name: Find matching repo files and register to a variable
find:
paths: /etc/yum.repos.d
file_type: file
recurse: no
patterns: CentOS-*.repo
register: output
Update the configuration
- name: Change the lines
replace:
path: "{{ item.0 }}"
regexp: "{{ item.1.reg }}"
replace: "{{ item.1.rep }}"
backup: true
with_nested:
- "{{ filelist }}"
- "{{ reg_rep }}"
loop_control:
label: "{{ item.0|basename }}"
Example of a complete playbook for testing
shell> cat pb.yml
- hosts: test_24
vars:
reg_rep:
- {reg: '^mirror', rep: '#mirror'}
- {reg: '^#baseurl', rep: 'baseurl'}
- {reg: 'mirror.centos', rep: 'vault.centos'}
filelist: "{{ output.files|map(attribute='path')|list }}"
tasks:
- name: Find matching repo files and register to a variable
find:
paths: /etc/yum.repos.d
file_type: file
recurse: no
patterns: CentOS-*.repo
register: output
- debug:
var: filelist
- debug:
msg: |
path: "{{ item.0 }}"
regexp: "{{ item.1.reg }}"
replace: "{{ item.1.rep }}"
backup: true
with_nested:
- "{{ filelist }}"
- "{{ reg_rep }}"
loop_control:
label: "{{ item.0|basename }}"
when: debug|d(false)|bool
- name: Change the lines
replace:
path: "{{ item.0 }}"
regexp: "{{ item.1.reg }}"
replace: "{{ item.1.rep }}"
backup: true
with_nested:
- "{{ filelist }}"
- "{{ reg_rep }}"
loop_control:
label: "{{ item.0|basename }}"
gives abridged, running in --check --diff mode
shell> ansible-playbook pb.yml -CD
PLAY [test_24] *******************************************************************************
TASK [Find matching repo files and register to a variable] ***********************************
ok: [test_24]
TASK [debug] *********************************************************************************
ok: [test_24] =>
filelist:
- /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
- /etc/yum.repos.d/CentOS-Linux-Debuginfo.repo
- /etc/yum.repos.d/CentOS-Linux-Devel.repo
- /etc/yum.repos.d/CentOS-Linux-Extras.repo
- /etc/yum.repos.d/CentOS-Linux-FastTrack.repo
- /etc/yum.repos.d/CentOS-Linux-HighAvailability.repo
- /etc/yum.repos.d/CentOS-Linux-Media.repo
- /etc/yum.repos.d/CentOS-Linux-Plus.repo
- /etc/yum.repos.d/CentOS-Linux-PowerTools.repo
- /etc/yum.repos.d/CentOS-Linux-Sources.repo
- /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
- /etc/yum.repos.d/CentOS-Linux-AppStream.repo
TASK [debug] *********************************************************************************
skipping: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo)
skipping: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo)
...
skipping: [test_24] => (item=CentOS-Linux-AppStream.repo)
skipping: [test_24]
TASK [Change the lines] **********************************************************************
--- before: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
+++ after: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
## -17,7 +17,7 ##
[cr]
name=CentOS Linux $releasever - ContinuousRelease
-mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=cr&infra=$infra
+#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=cr&infra=$infra
#baseurl=http://mirror.centos.org/$contentdir/$releasever/cr/$basearch/os/
gpgcheck=1
enabled=0
changed: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo)
--- before: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
+++ after: /etc/yum.repos.d/CentOS-Linux-ContinuousRelease.repo
## -18,7 +18,7 ##
[cr]
name=CentOS Linux $releasever - ContinuousRelease
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=cr&infra=$infra
-#baseurl=http://mirror.centos.org/$contentdir/$releasever/cr/$basearch/os/
+baseurl=http://mirror.centos.org/$contentdir/$releasever/cr/$basearch/os/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
changed: [test_24] => (item=CentOS-Linux-ContinuousRelease.repo)
...
--- before: /etc/yum.repos.d/CentOS-Linux-AppStream.repo
+++ after: /etc/yum.repos.d/CentOS-Linux-AppStream.repo
## -11,7 +11,7 ##
[appstream]
name=CentOS Linux $releasever - AppStream
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra
-#baseurl=http://mirror.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
+#baseurl=http://vault.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
baseurl=http://vault.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=0
changed: [test_24] => (item=CentOS-Linux-AppStream.repo)
PLAY RECAP ***********************************************************************************
test_24: ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

Ansible how to reference the variables from different tasks files

I want to be able to reference the variable vpc_info registered by file create-public-vpc from file create-public-sunbet
/etc/ansible/roles/ec2/tasks/main.yml
# tasks file for ec2-provision
- name:
import_tasks: create-vpc.yml
import_tasks: create-public-subnet.yml
/etc/ansible/roles/ec2/vars/main.yml
---
# vars file for ec2-provision
################################### designate python interpreter ########################
ansible_python_interpreter: /usr/local/bin/python3.8
############################## VPC INFO #########################################
vpc_name: "My VPC"
vpc_cidr_block: "10.0.0.0/16"
aws_region: "us-east-1"
################################### VPC Subnet ###############################################
aws_zone: "us-east-1a"
# Subnets
vpc_public_subnet_cidr: "10.0.0.0/24"
# Subnet
vpc_private_subnet_cidr: "10.0.1.0/24"
create-vpc.yml
- name: Create AWS VPC
ec2_vpc_net:
name: "{{ vpc_name }}"
cidr_block: "{{ vpc_cidr_block }}"
region: "{{ aws_region }}"
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
state: present
register: vpc_info
- name: Set vpc_info as fact
set_fact:
vpc_info_fact: "{{ vpc_info }}"
create-public-sunbet.yml
- name: print vpc_info_fact
debug:
msg: "{{ hostvars['localhost']['vpc_info_fact'] }}"
- name: Create Public Subnet in VPC
ec2_vpc_subnet:
vpc_id: "{{ vpc_info['vpc']['id'] }}"
cidr: "{{ vpc_public_subnet_cidr }}"
region: "{{ aws_region }}"
az: "{{ aws_zone }}"
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
state: present
tags:
Name: Public Subnet
register: public_subnet_info
When I run ansible-playbook ec2-provision.yml, the error message is as follows:
[root#VM-0-14-centos tasks]# ansible-playbook ec2-provision.yml
[WARNING]: While constructing a mapping from /etc/ansible/roles/EC2/tasks/main.yml, line 4, column 3, found a duplicate dict key (import_tasks). Using last defined value
only.
PLAY [localhost] ************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************
ok: [localhost]
TASK [EC2 : print vpc_info_fact] ********************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'vpc_info_fact' is undefined\n\nThe error appears to be in '/etc/ansible/roles/EC2/tasks/create-public-subnet.yml': line 3, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: print vpc_info_fact\n ^ here\n"}
PLAY RECAP ******************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Try to set the variable value as a fact once the variable is created and then you'd access the corresponding fact via hostvars.
For example:
- name: Create AWS VPC
ec2_vpc_net:
name: "{{ vpc_name }}"
cidr_block: "{{ vpc_cidr_block }}"
region: "{{ aws_region }}"
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
state: present
register: vpc_info
- name: Set vpc_info as fact
set_fact: vpc_info_fact="{{ vpc_info }}"
To access it from a different file, we have the following task:
- name: Create Public Subnet in VPC
ec2_vpc_subnet:
vpc_id: "{{ hostvars['localhost']['vpc_info']['vpc']['id'] }}"
cidr: "{{ vpc_public_subnet_cidr }}"
region: "{{ aws_region }}"
az: "{{ aws_zone }}"
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
state: present
tags:
Name: Public Subnet
register: public_subnet_info
Your main.yml contains a tasks with two modules. It should be
- name: Create VPC
import_tasks: create-vpc.yml
- name: Create Public Subnets
import_tasks: create-public-subnet.yml
The running playbooks prints the warning about that issue.
[WARNING]: While constructing a mapping from /etc/ansible/roles/EC2/tasks/main.yml, line 4, column 3, found a duplicate dict key (import_tasks). Using last defined value
only.
Ansible cannot have more then one module per task - and include_tasks is a module. It picks the last module, if there are multiple modules in one task (after writing the warning message and not exiting).
This is the main problem of all your issues. Everything else looks ok to me.

Parse yaml files in Ansible

I have got multiple yaml files on remote machine. I would like to parse those files in order to get information about names for each kind (Deployment, Configmap, Secret) of object, For example:
...
kind: Deployment
metadata:
name: pr1-dep
...
kind: Secret
metadata:
name: pr1
...
....
kind: ConfigMap
metadata:
name: cm-pr1
....
Ecpected result:
3 variables:
deployments = [pr1-dep]
secrets = [pr1]
configmaps = [cm-pr1]
I started with:
- shell: cat "{{ item.desc }}"
with_items:
- "{{ templating_register.results }}"
register: objs
but i have no idea how to correctly parse item.stdout from objs
Ansible has a from_yaml filter that takes YAML text as input and outputs an Ansible data structure. So for example you can write something like this:
- hosts: localhost
gather_facts: false
tasks:
- name: Read objects
command: "cat {{ item }}"
register: objs
loop:
- deployment.yaml
- configmap.yaml
- secret.yaml
- debug:
msg:
- "kind: {{ obj.kind }}"
- "name: {{ obj.metadata.name }}"
vars:
obj: "{{ item.stdout | from_yaml }}"
loop: "{{ objs.results }}"
loop_control:
label: "{{ item.item }}"
Given your example files, this playbook would output:
PLAY [localhost] ***************************************************************
TASK [Read objects] ************************************************************
changed: [localhost] => (item=deployment.yaml)
changed: [localhost] => (item=configmap.yaml)
changed: [localhost] => (item=secret.yaml)
TASK [debug] *******************************************************************
ok: [localhost] => (item=deployment.yaml) => {
"msg": [
"kind: Deployment",
"name: pr1-dep"
]
}
ok: [localhost] => (item=configmap.yaml) => {
"msg": [
"kind: ConfigMap",
"name: pr1-cm"
]
}
ok: [localhost] => (item=secret.yaml) => {
"msg": [
"kind: Secret",
"name: pr1"
]
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Creating the variables you've asked for is a little trickier. Here's
one option:
- hosts: localhost
gather_facts: false
tasks:
- name: Read objects
command: "cat {{ item }}"
register: objs
loop:
- deployment.yaml
- configmap.yaml
- secret.yaml
- name: Create variables
set_fact:
names: >-
{{
names|combine({
obj.kind.lower(): [obj.metadata.name]
}, list_merge='append')
}}
vars:
names: {}
obj: "{{ item.stdout | from_yaml }}"
loop: "{{ objs.results }}"
loop_control:
label: "{{ item.item }}"
- debug:
var: names
This creates a single variable named names that at the end of the
playbook will contain:
{
"configmap": [
"pr1-cm"
],
"deployment": [
"pr1-dep"
],
"secret": [
"pr1"
]
}
The key to the above playbook is our use of the combine filter, which can be used to merge dictionaries and, when we add list_merge='append', handles keys that resolve to lists by appending to the existing list, rather than replacing the existing key.
Include the dictionaries from the files into the new variables, e.g.
- include_vars:
file: "{{ item }}"
name: "objs_{{ item|splitext|first }}"
register: result
loop:
- deployment.yaml
- configmap.yaml
- secret.yaml
This will create dictionaries objs_deployment, objs_configmap, and objs_secret. Next, you can either use the dictionaries
- set_fact:
objs: "{{ objs|d({})|combine({_key: _val}) }}"
loop: "{{ query('varnames', 'objs_') }}"
vars:
_obj: "{{ lookup('vars', item) }}"
_key: "{{ _obj.kind }}"
_val: "{{ _obj.metadata.name }}"
, or the registered data
- set_fact:
objs: "{{ dict(_keys|zip(_vals)) }}"
vars:
_query1: '[].ansible_facts.*.kind'
_keys: "{{ result.results|json_query(_query1)|flatten }}"
_query2: '[].ansible_facts.*.metadata[].name'
_vals: "{{ result.results|json_query(_query2)|flatten }}"
Both options give
objs:
ConfigMap: cm-pr1
Deployment: pr1-dep
Secret: pr1

Iterate sub-items Ansible with sublements

Have task which copies each user's key
- name: SSH Keys
authorized_key:
user: "{{ item.0.name }}"
key: "{{ item.0.ssh_key.0.key }}"
state: "{{ item.0.ssh_key.0.state }}"
when:
- item.1 == 'all' or item.1 in group_names or item.1 == inventory_hostname
with_subelements:
- "{{ users }}"
- servers
Var list:
users:
- name: user1
ssh_key:
- key:
- "key1.user1"
- "key2.user1"
- "key3.user1"
state: present
servers:
- server1
- name: user2
ssh_key:
- key:
- "key1.user2"
- "key2.user2"
state: present
servers:
- all
QUESTION: How can we allow users to copy multiple keys? Without deleting servers from with_subelements.
When starting the task, either the last key or an array with keys is copied, depending on how we write it in var list.
In this format copied last key.
- key: "key1.user1"
- key: "key2.user1"
- key: "key3.user1"
In this array.
- key:
- "key1"
- "key2"
Let's fit the structure of the data to this purpose. For example,
users:
- name: user1
ssh_key:
- "key1.user1"
- "key2.user1"
- "key3.user1"
state: present
servers:
- server1
...
It's possible to loop include_tasks. For example, create the task (test it with debug first)
shell> cat conf_authorized_key.yml
- name: SSH Keys
# authorized_key:
debug:
msg:
- "user: {{ item.0.name }}"
- "state: {{ item.0.state }}"
- "key: {{ iitem }}"
loop: "{{ item.0.ssh_key }}"
loop_control:
loop_var: iitem
Then include it in the playbook
shell> cat playbook.yml
- hosts: localhost
vars:
users:
- name: user1
ssh_key:
- "key1.user1"
- "key2.user1"
- "key3.user1"
state: present
servers:
- server1
- name: user2
ssh_key:
- "key1.user2"
- "key2.user2"
state: present
servers:
- all
tasks:
- name: Loop include_task
include_tasks: conf_authorized_key.yml
loop: "{{ users|subelements('servers') }}"
loop_control:
label: "{{ item.1 }}"
when: (item.1 == 'all') or
(item.1 in group_names) or
(item.1 == inventory_hostname)
gives
shell> ansible-playbook playbook.yml
PLAY [localhost] ****
TASK [Loop include_task] ****
skipping: [localhost] => (item=server1)
included: /export/scratch/tmp/conf_authorized_key.yml for localhost
TASK [SSH Keys] ****
ok: [localhost] => (item=key1.user2) => {
"msg": [
"user: user2",
"state: present",
"key: key1.user2"
]
}
ok: [localhost] => (item=key2.user2) => {
"msg": [
"user: user2",
"state: present",
"key: key2.user2"
]
}
PLAY RECAP ****
localhost: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Loops within loops

I've set up some application information in my Ansible group_vars like this:
applications:
- name: app1
- name: app2
- name: app3
- name: app4
settings:
log_dir: /var/logs/app4
associated_files:
- auth/key.json
- name: app5
settings:
log_dir: /var/logs/app5
repo_path: new_apps/app5
I'm struggling to get my head around how I can use these "sub loops".
My tasks for each application are:
Create some folders based purely on the name value
Create a log folder if a settings/log_dir value exists
Copy associated files over, if specified
The syntax for these tasks isn't the problem here, I'm comfortable with those - I just need to know how to access the information from this applications variable. Number 3 in particular seems troublesome to me - I need to loop within a loop.
To debug this, I've been trying to run the following task:
- debug:
msg: "{{ item }}"
with_subelements:
- "{{ applications }}"
- settings
Here's the output:
with_items: I get the error with_items expects a list or a set
with_nested: I can see the top level information (e.g. msg: {{ item }} outputs an array of app1, app2 etc)
with_subelements: I get the error subelements lookup expects a dictionary, got 'None'
It's possible/probable that the way I've set the variable up in the first instance is wrong. If there's a better way to do this, it's not a problem to change it.
You can't use with_subelements because settings is a dictionary, not a list. If you were to restructure your data so that settings is a list, like this:
applications:
- name: app1
- name: app2
- name: app3
- name: app4
settings:
- name: log_dir
value: /var/logs/app4
- name: associated_files
value:
- auth/key.json
- name: app5
settings:
- name: log_dir
value: /var/logs/app5
- name: repo_path
value: new_apps/app5
You could then write something like the following to iterate over each setting for each application:
---
- hosts: localhost
gather_facts: false
vars_files:
- applications.yml
tasks:
- debug:
msg: "set {{ item.1.name }} to {{ item.1.value }} for {{ item.0.name }}"
loop: "{{ applications|subelements('settings', skip_missing=true) }}"
loop_control:
label: "{{ item.0.name }}.{{ item.1.name }} = {{ item.1.value }}"
(I'm using loop_control here just to make the output nicer.)
Using the sample data you posted in applications.yml, this will produce as output:
PLAY [localhost] *********************************************************************
TASK [debug] *************************************************************************
ok: [localhost] => (item=app4.log_dir = /var/logs/app4) => {
"msg": "set log_dir to /var/logs/app4 for app4"
}
ok: [localhost] => (item=app4.associated_files = ['auth/key.json']) => {
"msg": "set associated_files to ['auth/key.json'] for app4"
}
ok: [localhost] => (item=app5.log_dir = /var/logs/app5) => {
"msg": "set log_dir to /var/logs/app5 for app5"
}
ok: [localhost] => (item=app5.repo_path = new_apps/app5) => {
"msg": "set repo_path to new_apps/app5 for app5"
}
PLAY RECAP ***************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Resources