variables in hostname doesn't work well with jinja2 templates

1,583 views
Skip to first unread message

Aneesh Joseph

unread,
Jul 2, 2016, 12:17:23 PM7/2/16
to Ansible Project
I'm using variables within the inventory host name to provision environments dynamically using the ansible openstack modules and this is working well

[openstack]
myserver
-{{env}}.subdomain.mycompany.com


but, when I try to use these hostnames in a jinja2 template snippet, it's giving me errors

- name: find list of openstack servers which
  set_fact
:
    openstack_servers
: "{% for host in groups['openstack'] %}{{ hostvars[host]['inventory_hostname']{% if not loop.last %},{% endif %}{% endfor %}"

Is there a way to make it working? Any help or references in this regard  will be appreciated :-) 

To  replicate this kind of error, run the below play (test.yml) with the below inventory file(inventory.txt)

test.yml
---
- hosts: openstack
  connection
: local
  tasks
:
 
- debug: msg="inventory_hostname={{inventory_hostname}}"
 
- debug: msg="openstack_hosts={% for host in groups['openstack'] %}{{ hostvars[host]['inventory_hostname']}}{% if not loop.last %},{% endif %}{% endfor %}"


inventory.txt
[openstack]
myserver
-{{env}}.subdomain.mycompany.com

and run the play using

ansible-playbook test.yml -i inventory.txt --extra-vars="env=dev1"

The play fails with the below error :(

PLAY [openstack] ***************************************************************

TASK [setup] *******************************************************************
ok: [myserver-{{env}}.subdomain.mycompany.com]

TASK [debug] *******************************************************************
ok: [myserver-{{env}}.subdomain.mycompany.com] => {
    "msg": "inventory_hostname=myserver-dev1.subdomain.mycompany.com"
}

TASK [debug] *******************************************************************
fatal: [myserver-{{env}}.subdomain.mycompany.com]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'ansible.vars.hostvars.HostVars object' has no attribute u'myserver-dev1.subdomain.mycompany.com'\n\nThe error appears to have been in '/home/hos/test.yml': line 6, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  - debug: msg=\"inventory_hostname={{inventory_hostname}}\"\n  - debug: msg=\"openstack_hosts={% for host in groups['openstack'] %}{{ hostvars[host]['inventory_hostname']}}{% if not loop.last %},{% endif %}{% endfor %}\"\n    ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes.  Always quote template expression brackets when they\nstart a value. For instance:\n\n    with_items:\n      - {{ foo }}\n\nShould be written as:\n\n    with_items:\n      - \"{{ foo }}\"\n"}

NO MORE HOSTS LEFT *************************************************************
        to retry, use: --limit @test.retry

PLAY RECAP *********************************************************************
myserver-{{env}}.subdomain.mycompany.com : ok=2    changed=0    unreachable=0    failed=1

Aneesh Joseph

unread,
Jul 2, 2016, 3:51:58 PM7/2/16
to Ansible Project
looks like ansible lazily loads the hostvars dict with the raw hostname and doesn't apply variable substitution, but the for other dicts like groups variable substitutions are applied. Is this a bug?

The hostvars dict has myserver-{{env}}.subdomain.mycompany.com as the key instead of myserver-dev1.subdomain.mycompany.com and ansible fails with the error The error was: 'ansible.vars.hostvars.HostVars object' has no attribute u'myserver-dev1.subdomain.mycompany.com

Aneesh Joseph

unread,
Jul 4, 2016, 8:07:30 AM7/4/16
to Ansible Project
raised a GitHub issue for the same :) - https://github.com/ansible/ansible/issues/16565 
Reply all
Reply to author
Forward
0 new messages