Complex host_vars file and roles/with_items workaround

Hi everybody,

I’ve been on IRC with a bunch of questions related to the same problem, and haven’t found a good answer yet so I thought I’d post here. It’s hard to explain the full picture in detail on IRC.

Background

I am using Ansible 1.9.

I am using a role that reads a host_vars file with a somewhat complex data structure. It looks something like this (the values are meaningless). There are only 3 tenants listed here, but the real-world counterpart would be closer to hundreds:

db:
Tenant1:
name: Tenant1
key_a: hello
key_b:

  • { subkey_a: 1, subkey_b: 2, subkey_c: 3 }

  • { subkey_a: 1, subkey_b: 5, subkey_c: 6 }

Tenant2:

name: Tenant2
key_a: world
key_b:

  • { subkey_a: 7, subkey_b: 8, subkey_c: 9 }
  • { subkey_a: 10, subkey_b: 11, subkey_c: 12 }

Tenant3:

name: Tenant3
key_a: bye
key_b:

  • { subkey_a: these, subkey_b: values, subkey_c: do }
  • { subkey_a: not, subkey_b: matter, subkey_c: thanks }

The old way of doing things was that the user would supply an extra variable ‘tenant_id’ as a string (e.g. ‘Tenant1’ or ‘Tenant2’).
The role would be invoked like:

roles:
tenant_role

and the role would execute tasks like:

  • set_fact:
    tenant: “{{ db[tenant_id] }}”

  • name: Tenant Setup
    tenant_setup :
    tenant_name: “{{ tenant.name }}”
    tenant_value_a: “{{ tenant.key_a }}”
    tenant_subvalue_a: “{{ item.subkey_a }}”
    tenant_subvalue_b: “{{ item.subkey_b }}”
    tenant_subvalue_c: “{{ item.subkey_c }}”
    with_items: tenant.key_b

Everything worked fine this way.

New Requirements

The new requirements is that this role be adapted to instead take in a list of tenants instead of a string, and that the parameters for the tasks in the roles be populated with corresponding data. Under the new requirements, a user would supply an extra variable ‘tenant_list’ that might look like [‘Tenant1’, ‘Tenant3’] instead of a string as before.

The perfect fix would be to simply invoke the role using with_items, like:

roles:

  • { role: tenant_role, tenant_id: item, with_items: tenant_list }

However, I am on Ansbile 1.9 and 2.0 isn’t a possibility here. So the role must, within itself, deal with the list.

Request for Help

I understand there are many things on the surface that look like they might solve this, like with_nested, with_dict, or with_subelement. But I can’t seem to work them into the form needed to solve this specific problem. If you think you have an answer to this problem, please post an example of how the ‘Tenant Setup’ task would look under these new requirements, and what would replace the set_fact task above.

Related Questions

I am convinced I can work around this myself if I can do any of the following, so if you have answers on these please also let me know:

  • Append an element to an existing list in a playbook
  • Add a key/value pair to an existing hash in a playbook

Thanks so much for any help. I really appreciate it,
Michael