Ansible - grab a key from a dictionary (but not in a loop)

36,326

Given a nested dictionary...

mysql_dbs:
  db1:
    user: db1user
    pass: "jdhfksjdf"
    accessible_from: localhost
  db2:
    user: db2user
    pass: "npoaivrpon"
    accessible_from: localhost

You can either use dotted notation:

- debug:
    var: mysql_dbs.db1

Or you can use a more Python-esque syntax:

- debug:
    var: mysql_dbs['db1']

It looks like you tried to use an unholy hybrid:

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...

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:

- debug:
    msg: "key: {{ item }}"
  with_items: "{{ mysql_dbs.keys() }}"

The output of which would be:

TASK [debug] *******************************************************************
ok: [localhost] => (item=db1) => {
    "item": "db1", 
    "msg": "key: db1"
}
ok: [localhost] => (item=db2) => {
    "item": "db2", 
    "msg": "key: db2"
}
Share:
36,326
ticktockhouse
Author by

ticktockhouse

Updated on July 31, 2020

Comments

  • ticktockhouse
    ticktockhouse almost 4 years

    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.

    mysql_dbs:
      db1:
        user: db1user
        pass: "jdhfksjdf"
        accessible_from: localhost
      db2:
        user: db2user
        pass: "npoaivrpon"
        accessible_from: localhost
    

    task:

    - 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:

    - name: Add the db1 schema
      shell: mysql {{ item }} < /path/to/db1.sql 
      with_items: '{{ mysql_dbs[db1] }}'
    

    Error in ansible run:

    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...