4

Given a list of users:

# Python Syntax
users = [{'name': 'alice', 'sudo': True}, {'name': 'bob'}, {'name': 'charlie'}]

# YAML Syntax
users:
  - name: alice
    sudo: yes
  - name: bob
  - name: charlie

How 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?

3
  • Did you check with_items?
    – 030
    Commented May 1, 2020 at 19:11
  • My Intention is to save the result in a variable for later use. Is that possible with with_items? Commented May 2, 2020 at 7:26
  • Could you give it a try? Otherwise you could check register. With this it is possible to run a script and store the output in a variable. In later steps one could grep this output. Example.
    – 030
    Commented May 2, 2020 at 11:48

1 Answer 1

4

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.

$ 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 }}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.