Mind-boggling variable expansion in problems in 'lookup'

400 views
Skip to first unread message

Roman Revyakin

unread,
Dec 11, 2013, 1:19:45 AM12/11/13
to ansible...@googlegroups.com
Hi guys,

Can anyone tell me why variables in this simple playbook do not get expanded?

---

- hosts: all

  gather_facts: false

  user: ubuntu

  vars:

    tokens_file: /tmp/tokens.yml

  tasks:

  - debug: msg="{{ lookup('file', '{{ tokens_file }}' ) }}"


All I get is

$ ansible-playbook -i host -vvv test_lookup.yaml 


PLAY [all] ******************************************************************** 

ERROR: /private/tmp/{{tokens_file}} does not exist


And this is mind-boggling, because tasks like below from my another playbook work fine, with all variables getting expanded correctly:

- name: register slave on Jenkins master

  local_action: uri user={{ jenkins.admin }} password={{ jenkins.password }} method=POST url="http://{{ jenkins.master_host }}:{{ jenkins.master_port }}/computer/doCreateItem?name={{ node_name }}&type=hudson.slaves.DumbSlave&json={{ lookup('file', '/tmp/{{ node_name }}_newslave.json' )|urlencode }}" force_basic_auth=yes return_content=yes status_code=302

  tags:

   - jenkins_slave

   - setup

  when: '"{{ node_name }}" not in "{{ node_query.json.computer|map(attribute="displayName")|list }}"'


Any hint is greatly appreciated!

Thanks!

Michael DeHaan

unread,
Dec 11, 2013, 8:20:40 AM12/11/13
to ansible...@googlegroups.com
Hi Roman,

Happy to help.

Small request -- can you please send just text based mail in the future?  It would make this a lot easier to read.  Thanks!

Quick public service announcement, assuming you are using a recent Ansible, you should simplify your clauses:

when: none_name not in node_query.json.computer | map(attribute='displayName') | list 

The need to do all the {{ dereference }} is not needed in recent Ansible and can cause problems.

Also, your lookup is should not nest templates, that won't work.

It should look like:

lookup('file', '/tmp/' + node_name + '_newslave.json')

I'm pretty sure you can't urlencode right there inside the lookup statement either, so I'd recommend this:

set_fact:  my_path={{ '/tmp' + node_name + '_newslave.json' | urlencode }}

Save that variable and then it looks much much cleaner!

{{ lookup('file', my_path) }}

I would also define a variable for the URL so your playbooks can be cleaner.

Also, in the future please report what Ansible version you are using when you have questions, as that can sometimes be relevant.

Thanks and hope this helps, let us know if you have more questions!

--Michael


--
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.
For more options, visit https://groups.google.com/groups/opt_out.



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Roman Revyakin

unread,
Dec 11, 2013, 4:47:56 PM12/11/13
to ansible...@googlegroups.com
Hi Michael,

Thanks for your reply - and my apologies for pasting with all the syntax colours and backgrounds - I would have removed those if I was be able to preview how ugly my post would look like :-)

15 minutes past my submit I was able to figure out myself that my claim that this piece of code works was wrong:

  local_action: uri user={{ jenkins.admin }} password={{ jenkins.password }} method=POST url="http://{{ jenkins.master_host }}:{{ jenkins.master_port }}/computer/doCreateItem?name={{ node_name }}&type=hudson.slaves.DumbSlave&json={{ lookup('file', '/tmp/{{ node_name }}_newslave.json' )|urlencode }}" force_basic_auth=yes return_content=yes status_code=302

so I had to rewrite it as 

  local_action: uri user='{{ jenkins.admin }}' password='{{ jenkins.password }}' method=POST url="http://{{ jenkins.master_host }}:{{ jenkins.master_port }}/computer/doCreateItem?name={{ node_name }}&type=hudson.slaves.DumbSlave&json={{ lookup('file', '/tmp/' ~ node_name ~ '_newslave.json' )|urlencode }}" force_basic_auth=yes return_content=yes status_code=302

along the lines of what you proposed. Unfortunately I was not able to edit or reply to my post, as it was not approved as yet.
And yes, urlencode works there inside {{}} after the lookup. But thanks for the hint about the `set_fact:`, it is handy indeed - I was in fact looking for something like that and somehow missed to spot it on the Ansible modules page. May be it's worthwhile to mention it on a Best Practices page?

And yes, I am using the 'develop' branch of Ansible - and will be stating the version in my next posts should they occur.

Thanks again for your time and hints,

Best regards,
Roman
Reply all
Reply to author
Forward
0 new messages