Question:
Another question regarding dictionaries in Ansible!
For convenience, I have certain values for mysql databases held in dictionaries, which works fine to loop over using with_dict
to create the DBs and DB users.
1 2 3 4 5 6 7 8 9 10 |
mysql_dbs: db1: user: db1user pass: "jdhfksjdf" accessible_from: localhost db2: user: db2user pass: "npoaivrpon" accessible_from: localhost |
task:
1 2 3 4 |
- name: Configure mysql users mysql_user: name={{ item.value.user }} password={{ item.value.pass }} host={{ item.value.accessible_from }} priv={{ item.key }}.*:ALL state=present with_dict: "{{ mysql_dbs }}" |
However, I would like to use the key from one of the dictionaries in another task, but I don’t want to loop over the dictionaries, I would only like to use one at a time. How would I grab the key that describes the dictionary (sorry, not sure about terminology)?
problem task:
1 2 3 4 |
- name: Add the db1 schema shell: mysql {{ item }} < /path/to/db1.sql with_items: '{{ mysql_dbs[db1] }}' |
Error in ansible run:
1 2 |
fatal: [myhost]: FAILED! => {"failed": true, "msg": "'item' is undefined"} |
I’m willing to believe with_items
isn’t the best strategy here, but does anyone have any ideas what is the right one?
Thanks in advance, been stuck on this for a while now…
Answer:
Given a nested dictionary…
1 2 3 4 5 6 7 8 9 10 |
mysql_dbs: db1: user: db1user pass: "jdhfksjdf" accessible_from: localhost db2: user: db2user pass: "npoaivrpon" accessible_from: localhost |
You can either use dotted notation:
1 2 3 |
- debug: var: mysql_dbs.db1 |
Or you can use a more Python-esque syntax:
1 2 3 |
- debug: var: mysql_dbs['db1'] |
It looks like you tried to use an unholy hybrid:
1 2 |
mysql_dbs[db1] |
In this case, you are trying to dereference a variable named db1
,
which presumably doesn’t exist and would lead to a “variable is
undefined” sort of error.
Update
Your question is unclear because in your example you have…
1 2 |
with_items: '{{ mysql_dbs[db1] }}' |
…which looks like you are trying to do exactly what I have described here. If what you actually want to do is iterate over the keys of the
mysql_dbs
dictionary, remember that it is simply a Python dictionary and you have available all the standard dictionary methods, so:
1 2 3 4 |
- debug: msg: "key: {{ item }}" with_items: "{{ mysql_dbs.keys() }}" |
The output of which would be:
1 2 3 4 5 6 7 8 9 10 |
TASK [debug] ******************************************************************* ok: [localhost] => (item=db1) => { "item": "db1", "msg": "key: db1" } ok: [localhost] => (item=db2) => { "item": "db2", "msg": "key: db2" } |