Dave L
Dave L

Reputation: 25

How can I use a variable's value to look up another variable whose name is said value

I'm trying to use the value of one variable to use as a reference as the name of another variable in Jinja2, but am not having much luck.

This is for an Ansible job, but it's the Jinja2 part itself that I'm currently having problems with. I'm not sure if it is possible, but I feel like it should be and I am simply missing something obvious.

For example, with the following yaml:

item:
 key: second_var
 value: foobar

second_var:
  dict1:
    key1: value1
    key2: value2
  dict2:
    key1: v1
    key2: v2

I am attempting to get the value of second_var, so say: {{ second_var.dict2.key1 }} would be v1

The contents of item.key contains second_var. But when I reference {{ item.key }} I obviously just get the string 'second_var'.

I would like to be able to convert this item.key string some-way, some-how, so I could (for example) use {{ item.key }}.dict2.key1

I've been using this useful live parser: http://jinja.quantprogramming.com/

I know that you cannot nest Jinja2 variables, so {{ {{ item.key }}.dict2.key1 }} is out, but that should give a good idea of what I am trying to achieve. I'm not sure how to approach this now!

Testing template:

{{ item.key }}
{% set var_name = item.key -%}
{{ var_name }}
{% set dict = var_name -%}
"{{ dict }}.dict2.key1" = "{{ another_var.dict2.key1 }}"
item:
 key: another_var
 value: foobar

another_var:
  dict1:
    key1: value1
    key2: value2
  dict2:
    key1: v1
    key2: v2

Upvotes: 1

Views: 1298

Answers (2)

CrommCruach
CrommCruach

Reputation: 91

How do I access a variable name programmatically? An example may come up where we need to get the ipv4 address of an arbitrary interface, where the interface to be used may be supplied via a role parameter or other input. Variable names can be built by adding strings together, like so:

{{ hostvars[inventory_hostname]['ansible_' + which_interface]['ipv4']['address'] }} The trick about going through hostvars is necessary because it’s a dictionary of the entire namespace of variables. ‘inventory_hostname’ is a magic variable that indicates the current host you are looping over in the host loop.

Also see dynamic_variables: https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#dynamic-variables

Upvotes: 1

Vladimir Botka
Vladimir Botka

Reputation: 68004

It is possible to lookup vars. The template below

"{{ item.key }}.dict2.key1" = "{{ lookup('vars', item.key).dict2.key1 }}"

gives

"second_var.dict2.key1" = "v1"

Upvotes: 2

Related Questions