Ventor
Ventor

Reputation: 33

How to add key-value-pair to each dictionary in a list

I have to add a key and a value to a list which is read from a csv-file into a variable.

To explain it a bit better. First I load a list from a csv-file:

- name: Load user list from csv
  community.general.read_csv:
    path: ../files/example-prod.csv
    delimiter: ','
  register: users
  delegate_to: localhost

When I look at the "users" variable I get the following output:

"list": [
        {
            "firstName": "Max",
            "gid": "2002",
            "homedir": "example",
            "lastName": "Mustermann",
            "uid": "m.example"
        },
        {
            "firstName": "Martin",
            "gid": "2002",
            "homedir": "staff",
            "lastName": "Muster",
            "uid": "martin.muster"
        }
    ]

Now I need to generate passwords for all users in the list. So I want to loop through the items and add a new key-value-pair to each item in the list.

The output that I want after the password creation loop is:

"list": [
        {
            "firstName": "Max",
            "gid": "2002",
            "homedir": "example",
            "lastName": "Mustermann",
            "uid": "m.example",
            "password": "examplepassword"
        },
        {
            "firstName": "Martin",
            "gid": "2002",
            "homedir": "staff",
            "lastName": "Muster",
            "uid": "martin.muster",
            "password": "examplepassword"
        }
    ]

...so I can read out the variables later.

How to accomplish this? I've read many things about how to do this with a dictionary, but since I'm using a list here, I could not find it out.

Upvotes: 3

Views: 1157

Answers (1)

toydarian
toydarian

Reputation: 4554

You are actually getting a list of dictionaries from the read_csv module. The content of "list" is a list, but the elements in this list are dictionaries.

What you want to do is to add a key-value-pair to each dictionary.
Here is an example generating random passwords. See the password-lookup documentation on details how it generates passwords:

- set_fact:
    users: |
      {{ users.list | map('combine', { "password": "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=8') }}"}) }}

# this resolves the template added above and is required to avoid changing passwords on each resolve of users
- set_fact:
    users: "{{ users }}"

- debug:
    msg: "{{ users }}"

Explanation:

  • users.list contains your list of users
  • map('combine', <dict>) runs the combine filter on each dictionary in the input list (users.list in this case) and adds the contents of <dict> to it
  • { "password": "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=8') }}"} is the dictionary we combine each input-dictionary with
  • "password" is the key, and the value is the lookup that is generating the password

Remark:
I use the multi-line string literal of yaml to avoid the quoting-hell.

Upvotes: 2

Related Questions