Ansible: How to use a Variable as an Index?

5,016 views
Skip to first unread message

lilf...@cisco.com

unread,
Aug 11, 2015, 5:20:30 PM8/11/15
to Ansible Project
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 
---
nics:
- {type: 'static', ip: '10.3.5.4'}
- {type: 'dhcp'}
- {type: 'static', ip: '10.3.5.5'}

host # cat test.yml 
- hosts: 127.0.0.1
  vars_files:
    - "nics.yml"
  tasks:
    - name: Static IP Case - Find out Static Overlay IP
      set_fact: 
         cvmip: "{{nics[{{num}}].ip}}"                     <----- HOW DO I GET PAST THIS?
      when: nics[{{num}}].type == "static"           <--- It works fine here

    - name: Write Overlay IP to file
      shell: echo {{cvmip}} >> /tmp/staticip.txt
      when: nics[{{num}}].type == "static"

host# ansible-playbook test.yml --extra-vars "num=0"
[SNIP]
TASK: [Static IP Case - Find out Static Overlay IP] *************************** 
fatal: [127.0.0.1] => Failed to template {{nics[{{num}}].ip}}: template error while templating string: expected token ':', got '}'

Timothy Appnel

unread,
Aug 11, 2015, 6:49:34 PM8/11/15
to Ansible Project
Don't use nested mustaches. In other words try this:

cvmip: "{{ nics[num].ip }}"


photo
Timothy Appnel
Senior Solutions Architect

Ansible, Inc.  www.ansible.com

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/8066dec4-1cae-4ca7-b75d-d4d0e8e09397%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Josh Smift

unread,
Aug 11, 2015, 8:38:16 PM8/11/15
to ansible...@googlegroups.com
TA> 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 (j...@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.

Timothy Appnel

unread,
Aug 11, 2015, 9:35:06 PM8/11/15
to Ansible Project
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.



photo
Timothy Appnel
Senior Solutions Architect

Ansible, Inc.  www.ansible.com

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

lilf...@cisco.com

unread,
Aug 12, 2015, 12:27:42 PM8/12/15
to Ansible Project
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

Brian Coca

unread,
Aug 12, 2015, 1:09:51 PM8/12/15
to Ansible Project
sounds like nics is an empty list, your first example is correct syntax, the rest are not.


For more options, visit https://groups.google.com/d/optout.



--
Brian Coca

lilf...@cisco.com

unread,
Aug 12, 2015, 2:08:06 PM8/12/15
to Ansible Project
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 
---
nics:
- {type: 'static', ip: '10.3.5.4'}
- {type: 'dhcp'}
- {type: 'static', ip: '10.3.5.5'}

The first example is exactly where I am stuck - it should work, but doesn't...
cvmip: "{{nics[num].ip}}"

Thanks,
Lillian

Brian Coca

unread,
Aug 12, 2015, 2:09:34 PM8/12/15
to Ansible Project
when are you setting num?


For more options, visit https://groups.google.com/d/optout.



--
Brian Coca

lilf...@cisco.com

unread,
Aug 12, 2015, 2:19:27 PM8/12/15
to Ansible Project
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 
---
nics:
- {type: 'static', ip: '10.3.5.4'}
- {type: 'dhcp'}
- {type: 'static', ip: '10.3.5.5'}

# cat test.yml 
- hosts: 127.0.0.1
  vars_files:
    - "nics.yml"
  tasks:

# Static IP Case: Find out the Overlay IP
    - name: Static IP Case - Find out Static Overlay IP
      set_fact: 
         cvmip: "{{nics[num].ip}}"
      when: nics[{{num}}].type == "static"

    - name: Write Overlay IP to file
      shell: echo {{cvmip}} >> /tmp/staticip.txt
      when: nics[{{num}}].type == "static"


NOTE:
If I replace the bad line with a hardcoded "0" as shown here, the play succeeds, indicating that nics.yml is correct:
         cvmip: "{{nics[0].ip}}"

# cat /tmp/staticip.txt 
10.3.5.4


Thanks!
Lilian

Matt Martz

unread,
Aug 12, 2015, 2:46:22 PM8/12/15
to ansible...@googlegroups.com
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.

For more options, visit https://groups.google.com/d/optout.


--
Matt Martz
@sivel
sivel.net

Brian Coca

unread,
Aug 12, 2015, 3:37:56 PM8/12/15
to Ansible Project
also, change the conditional:
  when: nics[num|int].type == "static"


For more options, visit https://groups.google.com/d/optout.



--
Brian Coca

lilf...@cisco.com

unread,
Aug 12, 2015, 4:51:41 PM8/12/15
to Ansible Project
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
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-project+unsubscribe@googlegroups.com.
To post to this group, send email to ansible-project@googlegroups.com.


--
Matt Martz
@sivel
sivel.net

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/CAD8N0v-77nk-j0SwA0L8V48bphhH1AO2YrgXKsYfe%2B3s1kNUsg%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--
Brian Coca
Reply all
Reply to author
Forward
0 new messages