Ansible: How to use a Variable as an Index?

Hi Ansible Users,

I am trying to use a variable passed in via “–extra-vars” to index into ‘nics’ which is defined in nics.yml.

It works fine in the “when” clause, but not in the “set_fact”. Any suggestions?

Thanks,
Lilian

host# cat nics.yml

Don’t use nested mustaches. In other words try this:

Don't use nested mustaches.

This should probably be a FAQ. :^) FWIW, what helped me understand this is
that the mustaches aren't saying "here's a variable" (in which case you
might think, incorrectly, that you need to put them around all variables
all the time everywhere), but rather "start parsing this as Jinja", and
that once you say that, it keeps happening until you close the mustaches
(which means "stop parsing this as Jinja"). One of the things that happens
when you're parsing as Jinja is that variables get expanded, but thinking
of it as "start Jinja" and "stop Jinja" helped me keep it straight when I
first started with this stuff, anyway.

                                      -Josh (jbs@care.com)

This email is intended for the person(s) to whom it is addressed and may contain information that is PRIVILEGED or CONFIDENTIAL. Any unauthorized use, distribution, copying, or disclosure by any person other than the addressee(s) is strictly prohibited. If you have received this email in error, please notify the sender immediately by return email and delete the message and any attachments from your system.

That is a good way of thinking of explaining it in the context of Ansible – start Jinja, stop Jinja. At the same time, how would you have represented this in a Jinja template? Jinja doesn’t allow for nested mustaches in any context that I am aware of.

I’m sure a patch to the docs to make light of this would be appreciated.

Hi Guys,

Thank you for the responses. I should have mentioned this - I had already tried several combinations (including the suggestion above) with and without nested {{ }}, but still can’t get a working syntax. Please see below for some attempts and their results.

Putting an example/note in the docs would be really helpful as well.

Thanks,

Lilian

host# ansible-playbook test.yml --extra-vars “num=0”

Format Attempt:

cvmip: “{{nics[num].ip}}”

Result:

TASK: [Static IP Case - Find out Static Overlay IP] ***************************
fatal: [127.0.0.1] => One or more undefined variables: ‘list object’ has no attribute u’0’

Format Attempt:

cvmip: “{{nics[‘num’].ip}}”

Result:

TASK: [Static IP Case - Find out Static Overlay IP] ***************************
fatal: [127.0.0.1] => One or more undefined variables: ‘list object’ has no attribute ‘num’

Format Attempt:

cvmip: “{{nics}}”[“{{num}}”].ip}}

Result:

ERROR: Syntax Error while loading YAML script, test.yml

sounds like nics is an empty list, your first example is correct syntax, the rest are not.

Hi Brian,

nics.yml is not an empty list - as I pointed out, in the “when:” clause, the playbook correctly detects it as type static:

host# cat nics.yml

when are you setting num?

Let me paste the output of all files & the invoking call again here:

ansible-playbook test.yml --extra-vars “num=0”

[SNIP]

TASK: [Static IP Case - Find out Static Overlay IP] ***************************
fatal: [127.0.0.1] => One or more undefined variables: ‘list object’ has no attribute u’0’

cat nics.yml

I believe the original error holds the answer:

fatal: [127.0.0.1] => One or more undefined variables: ‘list object’ has no attribute u’0’

That states that the list object has not attribute of the Unicode string “0”.

So “num” appears to be a string and needs to be an int.

Try using

“{{ nics[num|int].ip }}”

The |int will cast the string to an int.

also, change the conditional:
when: nics[num|int].type == “static”

Hello,

That was indeed the problem!! The play works great now. Thanks so much for your help everyone.

It would be excellent if we could also add a note to the docs about nested moustaches.

Thanks again,
Lilian