Ansible get a dictionary item with a dynamically compiled key name

ansible

In one Ansible playbook I include a variables file which contains one variable like this:

dictionaries:
  - host1:
    - key1:
      - name: "Foo"
        params:
        - bar: "Baz"
  - host2:
    - key1:
      - name: "Foo2"
        params:
        - bar: "Baz2"
  - host3:
    - key1:
      - name: "Foo3"
        params:
        - bar: "Baz3"

I want to take only the element of the list which key name is the Ansible {{ inventory_hostname }} of the host Ansible is executing the playbook on.

So for example, if I execute the playbook on host2 I want to get the dictionary:

- key1:
  - name: "Foo2"
    params:
    - bar: "Baz2"

I'm trying to use the lookup plugin but I'm not sure how I can use it in this situation.

Best Answer

After my comment above, let's try an answer with what I think is the correct data structure. This is how I would change it:

dictionaries:
  host1:
    key1:
      name: "Foo"
      params:
        bar: "Baz"
  host2:
    key1:
      name: "Foo2"
      params:
        bar: "Baz2"
  host3:
    key1:
      name: "Foo3"
      params:
        bar: "Baz3"
    key2:
      name: "toto"
      params:
        titi: "tata"

Now let's say you want to access the name of key2 for host3, your jinja2 template string would be

"{{ dictionnaries.host3.key2.name }}"

You can also use the bracket notation for this, i.e.

"{{ dictionnaries['host3']['key2']['name'] }}"

... or a combination (these are all equivalent, non exhaustive list of examples)

"{{ dictionnaries['host3'].key2.name }}"
"{{ dictionnaries['host3']['key2'].name }}"
"{{ dictionnaries.host3.key2['name'] }}"

Back to your question: you now want to access a hashmap of keys for a specific host while running a playbook. I take for granted that the keys in your dictionnaries variable are named after the host in your inventory. So I use the inventory_hostname magic variable which contains that name when running on a specific host

---
- name: debug vars from my dict
  hosts: whatever_group

  vars:
    dictionaries:
      host1:
        key1:
          name: "Foo"
          params:
            bar: "Baz"
      host2:
        key1:
          name: "Foo2"
          params:
        bar: "Baz2"
      host3:
        key1:
          name: "Foo3"
          params:
            bar: "Baz3"
        key2:
          name: "toto"
          params:
            titi: "tata"

  tasks:
    - name: debug hashmap per host
      debug:
        msg: "{{ dictionaries[inventory_hostname] }}"

All of this being said, this is sort-of reinventing the wheel as ansible already has a mechanism to declare variables per host in your inventory. You could symply declare your hashmaps in a host_vars/<hostname>.yml file for each of your hosts. Then all you have to do is to use those variables as-is.

Have a look at the ansible documentation on inventories and more specifically the chapter on organizing host and group variables