snippetMinor
Doing map and filter of a list of dictionaries in ansible
Viewed 0 times
mapdictionariesdoingfilterandlistansible
Problem
Given a list of users:
How would I do the following in an ansible playbook:
resulting in:
Is this even possible/intended use of playbook language?
# Python Syntax
users = [{'name': 'alice', 'sudo': True}, {'name': 'bob'}, {'name': 'charlie'}]
# YAML Syntax
users:
- name: alice
sudo: yes
- name: bob
- name: charlieHow would I do the following in an ansible playbook:
# Python Syntax
[ dict(user, home="/home/{}/".format(user['name'])) for user in users if not 'sudo' in user]
# more verbose
for user in users:
if not 'sudo' in user:
user['home'] = '/home/' + user['name'] + '/'resulting in:
# Python Syntax
[{'name': 'bob', 'home': '/home/bob/'}, {'name': 'charlie', 'home': '/home/charlie/'}]
# YAML Syntax
users:
- name: bob
home: /home/bob/
- name: charlie
home: /home/charlie/Is this even possible/intended use of playbook language?
Solution
There's a lot that you can do, but I'm not sure with the existing filters you easily augment a dict.
Creating a new filter to do it was easier.
You can use set_facts and loop to get the values you want, but the question becomes what format and use of the data is really needed. I'm not sure creating a new structure is the Right Way (TM). It could be easier to just calculate the individual value for each item in the list when it is used.
Creating a new filter to do it was easier.
$ cat filter_plugins/addhomedir.py
class FilterModule:
@staticmethod
def add_home(_val):
return [dict(user, home='/home/{0}/'.format(user['name'])) for user in
_val if 'sudo' not in user]
def filters(self):
return {
'add_homedir': self.add_home
}
$ cat test1.yml
---
- hosts: localhost
vars:
users:
- name: alice
sudo: yes
- name: bob
- name: charlie
tasks:
- debug:
msg: "{{ users | add_homedir | list }}"You can use set_facts and loop to get the values you want, but the question becomes what format and use of the data is really needed. I'm not sure creating a new structure is the Right Way (TM). It could be easier to just calculate the individual value for each item in the list when it is used.
$ cat test2.yml
---
- hosts: localhost
vars:
users:
- name: alice
sudo: yes
- name: bob
- name: charlie
tasks:
- user:
name: "{{ item['name'] }}"
create_home: true
home: "{{ '/home/{}/'.format(item['name'] }}"
when: "'sudo' not in item"
loop: "{{ users }}"Code Snippets
$ cat filter_plugins/addhomedir.py
class FilterModule:
@staticmethod
def add_home(_val):
return [dict(user, home='/home/{0}/'.format(user['name'])) for user in
_val if 'sudo' not in user]
def filters(self):
return {
'add_homedir': self.add_home
}
$ cat test1.yml
---
- hosts: localhost
vars:
users:
- name: alice
sudo: yes
- name: bob
- name: charlie
tasks:
- debug:
msg: "{{ users | add_homedir | list }}"$ cat test2.yml
---
- hosts: localhost
vars:
users:
- name: alice
sudo: yes
- name: bob
- name: charlie
tasks:
- user:
name: "{{ item['name'] }}"
create_home: true
home: "{{ '/home/{}/'.format(item['name'] }}"
when: "'sudo' not in item"
loop: "{{ users }}"Context
StackExchange DevOps Q#11481, answer score: 4
Revisions (0)
No revisions yet.