AnsibleUndefinedVariable: 'dict object' has no attribute

2,410 views
Skip to first unread message

Freddie Eisa

unread,
Jan 3, 2019, 1:04:12 PM1/3/19
to Ansible Project
SUMMARY

jinja2 template issues with hostvars

ISSUE TYPE
  • Bug Report
COMPONENT NAME

jinja2 template

ANSIBLE VERSION

ansible 2.7.2
config file = /home/feisa/ansible-linux/ansible.cfg
configured module search path = [u'/home/feisa/ansible-linux/library']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

CONFIGURATION

jinja2 template

{% for host in groups['servers_production'] %}
   {{ hostvars[host]['ansible_facts']['eth0']['ipv4']['address'] }}
{% endfor %}
- name: Template Knownhosts
  template: src=./ssh.j2 dest=/tmp/temp.conf
OS / ENVIRONMENT

Centos 7.6

STEPS TO REPRODUCE

run normal ansible playblook

EXPECTED RESULTS

playbook runs succesfully

ACTUAL RESULTS

{"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'eth0'"}

Hugo Gonzalez

unread,
Jan 3, 2019, 4:31:40 PM1/3/19
to ansible...@googlegroups.com

Hello Freddie,


On 1/3/19 12:04 PM, Freddie Eisa wrote:

{"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'eth0'"}


How do you know what to look for in ansible_facts? Run the setup module against your managed hosts and see what the facts look like.

I have this on a node of mine:

  "ansible_facts": {
...,

     "ansible_default_ipv4": {
            "address": "XXXX",
            "alias": "eth0",
            "broadcast": "XXXX",
            "gateway": "XXXX",
            "interface": "eth0",
            "macaddress": "XXXXX",
            "mtu": 1500,
            "netmask": "255.255.248.0",
            "network": "XXXXXXX",
            "type": "ether"
        },
}


I don't see any hostvars[host]['ansible_facts']['eth0']['ipv4']['address']

Try  $ ansible <hostgroup> -m  setup and examine the output to see how you should look for eth0's IP address.


Cheers,


Hugo





--

Hugo F. gonzalez

Senior Consultant

Red Hat LATAM

Freddie Eisa

unread,
Jan 3, 2019, 4:34:59 PM1/3/19
to ansible...@googlegroups.com
So it depends on the host and how they are named and was really a test case. The one I’m really concerned about is this one now 


{% for host in groups['servers_production'] %}
   {{ hostvars[host]['ssh_host_key_ecdsa_public'] }}
{% endfor %}

-- 
HUGO F. GONZALEZ

SENIOR CONSULTANT


-- 
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/4473f03c-a4f0-f89c-5d92-77b2cf85ba01%40redhat.com.
For more options, visit https://groups.google.com/d/optout.

Hugo Gonzalez

unread,
Jan 3, 2019, 5:23:26 PM1/3/19
to ansible...@googlegroups.com


On 1/3/19 3:34 PM, Freddie Eisa wrote:
So it depends on the host and how they are named and was really a test case. The one I’m really concerned about is this one now 


{% for host in groups['servers_production'] %}
   {{ hostvars[host]['ssh_host_key_ecdsa_public'] }}
{% endfor %}

I think you mean:  hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public']

This works for me and prints the key.---
- hosts: all

  tasks:
    - debug:
        msg: "{% for host in groups['all'] %} {{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }} {% endfor %}"


Hugo G.



Freddie Eisa

unread,
Jan 3, 2019, 5:27:10 PM1/3/19
to ansible...@googlegroups.com
I had tried but still receive 

fatal: [server]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'ssh_host_key_ecdsa_public'"}

--
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.

Hugo Gonzalez

unread,
Jan 3, 2019, 5:31:57 PM1/3/19
to ansible...@googlegroups.com

On 1/3/19 4:26 PM, Freddie Eisa wrote:
I had tried but still receive 

fatal: [server]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'ssh_host_key_ecdsa_public'"}

Please post the play you're using, or at least the relevant task and template.

This works for me and prints the key.---
- hosts: all

  tasks:
    - debug:
        msg: "{% for host in groups['all'] %} {{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }} {% endfor %}"


Freddie Eisa

unread,
Jan 3, 2019, 5:33:45 PM1/3/19
to ansible...@googlegroups.com
This is what I’m running 

My role
- name: Template Knownhosts
  template: src=./ssh_key.j2 dest=/tmp/temp.conf

My template 
{% for host in groups['all'] %}
   "{{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }}"
{% endfor %}

My playbook

---
- name: Centos 7 Servers
  hosts: servers_all
  gather_facts: True
  ignore_errors: yes
  roles:
   - linux-role

-- 

HUGO F. GONZALEZ

SENIOR CONSULTANT

-- 
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.

Hugo Gonzalez

unread,
Jan 3, 2019, 6:06:20 PM1/3/19
to ansible...@googlegroups.com

Got to be something else. Are these linux hosts?

I tried this and it works:

playbook:

---
- hosts: all

  tasks:

    - template:
        src: template.j2
        dest: /tmp/knownhosts

--------------------

template:

{% for host in groups['all'] %}
{{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }} 
{% endfor %}

----------------------

I suggest you run the setup module on your managed hosts and see the structure of the facts on your hosts then, and see if the host keys are there with that name.


Hugo G.


On 1/3/19 4:33 PM, Freddie Eisa wrote:
This is what I’m running 

My role
- name: Template Knownhosts
  template: src=./ssh_key.j2 dest=/tmp/temp.conf

My template 
{% for host in groups['all'] %}
   "{{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }}"
{% endfor %}

My playbook

---
- name: Centos 7 Servers
  hosts: servers_all
  gather_facts: True
  ignore_errors: yes
  roles:
   - linux-role
-- 
HUGO F. GONZALEZ

SENIOR CONSULTANT


-- 
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/51fe343a-0562-0849-9161-4a0d04366503%40redhat.com.
For more options, visit https://groups.google.com/d/optout.
--
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.

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

Freddie Eisa

unread,
Jan 3, 2019, 6:07:15 PM1/3/19
to ansible...@googlegroups.com
They keys are there in facts

Freddie Eisa

unread,
Jan 3, 2019, 6:20:13 PM1/3/19
to ansible...@googlegroups.com
I just ran the same thing you ddi with the same issue I had. 

Freddie Eisa

unread,
Jan 3, 2019, 6:23:35 PM1/3/19
to ansible...@googlegroups.com
What version are you running? The linux host is centos7.6

Verified in my facts

"ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGpMZqjhIzo6gGjz4eczxnatrAgmPxdWVYf0zY29MDngkKuOzjB0bMrR5sQm1X6leGgYowv3wNloWOZVbhwPU2A=", 

Karl Auer

unread,
Jan 3, 2019, 6:38:58 PM1/3/19
to ansible-project
Your version has double quotes around the second line. The known working version does not. Could that be an issue?

Regards, K.


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


--
Karl Auer

Email  : ka...@2pisoftware.com
Website: http://2pisoftware.com


GPG/PGP : 958A 2647 6C44 D376 3D63 86A5 FFB2 20BC 0257 5816
Previous: F0AB 6C70 A49D 1927 6E05 81E7 AD95 268F 2AB6 40EA

Freddie Eisa

unread,
Jan 3, 2019, 6:40:56 PM1/3/19
to ansible...@googlegroups.com
I removed it with the same issue

{% for host in groups['all'] %}
   {{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }}
{% endfor %}

Hugo Gonzalez

unread,
Jan 4, 2019, 1:18:17 PM1/4/19
to ansible...@googlegroups.com

Hello Freddie

On 1/3/19 5:23 PM, Freddie Eisa wrote:
What version are you running? The linux host is centos7.6

Ansible is 2.5.1, managed hosts are two Centos 7.6 cloud servers in my tests.


I tried the following:

- gather facts (automatic)

- locally render the template *on the controlling node*, once

- push the templated file to the managed hosts.


Curious if this will work for you:


template:

{% for host in groups['all'] %}
{{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }} 
{% endfor %}

playbook:

---
- hosts: all

  tasks:

    - name: Render the known_hosts file locally
      template:
        src: template.j2
        dest: /tmp/known_hosts
      delegate_to: localhost
      run_once: true

    - name: Copy the rendered file to all the nodes
      copy:
        src: /tmp/known_hosts
        dest: /tmp


---


Still not getting the error you're getting, except when trying to use the variable as  ansible_ssh_host_key_ecdsa_public and that's not consistent, so I may be running into a completely different issue.

Hugo Gonzalez

unread,
Jan 4, 2019, 1:47:18 PM1/4/19
to ansible...@googlegroups.com

template:

{% for host in groups['all'] %}
{{ hostvars[host]['ansible_facts']['ssh_host_key_ecdsa_public'] }} 
{% endfor %}

This template also works for me, and the keys are different. So you might want to try it:

{% for host in groups['all'] %}

{{ hostvars[host]['ansible_ssh_host_key_ecdsa_public'] }}
{% endfor %}


Freddie Eisa

unread,
Jan 7, 2019, 10:40:34 AM1/7/19
to ansible...@googlegroups.com
Ill test today

--
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.

Freddie Eisa

unread,
Jan 7, 2019, 11:28:03 AM1/7/19
to ansible...@googlegroups.com
No luck so far 

On Jan 4, 2019, at 11:47 AM, Hugo Gonzalez <hgon...@redhat.com> wrote:

--
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.

Freddie Eisa

unread,
Jan 7, 2019, 11:30:52 AM1/7/19
to ansible...@googlegroups.com
Same error, can you send full playbook details over you are testing?

localhost]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible.vars.hostvars.HostVarsVars object' has no attribute 'ansible_ssh_host_key_ecdsa_public'"}

On Jan 4, 2019, at 11:47 AM, Hugo Gonzalez <hgon...@redhat.com> wrote:

--
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.

Hugo Gonzalez

unread,
Jan 7, 2019, 11:53:21 AM1/7/19
to ansible...@googlegroups.com

Can you try removing the "

  ignore_errors: yes
"you had before? Maybe something in failing in the facts gathering and, naturally, the variables did not get populated.


Here's the full playbook and template I used to test (this does not even need to escalate privileges):

---
- hosts: all

  tasks:

    - name: Render the known_hosts file locally
      template:
        src: template.j2
        dest: /tmp/known_hosts
      delegate_to: localhost
      run_once: true
     
    - name: Copy the rendered file to all the nodes
      copy:
        src: /tmp/known_hosts
        dest: /tmp


Template:

Freddie Eisa

unread,
Jan 7, 2019, 1:49:26 PM1/7/19
to ansible...@googlegroups.com
Getting this now.

localhost]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible.vars.hostvars.HostVarsVars object' has no attribute 'ansible_ssh_host_key_ecdsa_public'"}

I debug the facts and see it

Brian Coca

unread,
Jan 7, 2019, 2:57:58 PM1/7/19
to Ansible Project
can you do this debug:

- debug: msg={{ hostvars[item]['ansible_ssh_host_key_ecdsa_public'] }}
loop: '{{groups["all"]}}'


--
----------
Brian Coca

Freddie Eisa

unread,
Jan 7, 2019, 3:13:42 PM1/7/19
to ansible...@googlegroups.com
"The task includes an option with an undefined variable. The error was: 'ansible.vars.hostvars.HostVarsVars object' has no attribute 'ansible_ssh_host_key_ecdsa_public'\n\nThe error appears to have been in '/home/feisa/ansible-linux/test_single_server.yml': line 6, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n   - debug: msg={{ hostvars[item]['ansible_ssh_host_key_ecdsa_public'] }}\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"

Freddie Eisa

unread,
Jan 7, 2019, 3:17:30 PM1/7/19
to ansible...@googlegroups.com
---
- hosts: all

  tasks:

   - debug: msg={{ hostvars[item]['ansible_ssh_host_key_ecdsa_public'] }}
     loop: '{{groups["all"]}}’

My playbook

On Jan 7, 2019, at 12:57 PM, Brian Coca <bc...@redhat.com> wrote:

Brian Coca

unread,
Jan 7, 2019, 3:24:16 PM1/7/19
to Ansible Project
so one of your hosts is not returning the fact for
`ansible_ssh_host_key_ecdsa_public`, its not an issue with the
template, but of getting the variable defined in the first place, the
'item' from the error will tell the first host host it is (add
ignore_errors:yes and you'll see all the hosts that fail).

To avoid such issues you might want to use the |default() filter or
check if the key exists before using it.


--
----------
Brian Coca

Freddie Eisa

unread,
Jan 7, 2019, 3:37:24 PM1/7/19
to ansible...@googlegroups.com
I ran the following

Tasks:
   - debug: 
      var: ansible_ssh_host_key_ecdsa_public

Received this 

 {
    "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMj3Y7I/7ByqhoT22sBg2D0tUO8rCVQRTUQXyecCPVfXud9tnInwxXJUI8KKoIScw2YEKQuq8SPB46CE6ce6Bqw="


--
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.
Reply all
Reply to author
Forward
0 new messages