Reputation: 33
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
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 usersmap('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 passwordRemark:
I use the multi-line string literal of yaml to avoid the quoting-hell.
Upvotes: 2