# 'dict object' has no attribute....

**URL:** <https://forum.ansible.com/t/dict-object-has-no-attribute/38686>\
**Category:** Ansible Project\
**Tags:** ubuntu\
**Created:** [February 13, 2024, 1:22pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686 "2024-02-13T13:22:13Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [February 13, 2024, 1:22pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/1 "2024-02-13T13:22:13Z")

</div>

I’ve been working this issue for a week now. The code used to work perfectly and now it fails. Here is the error I get:

The task includes an option with an undefined variable. The error was: {‘CentOS’: ‘{{ iptables\_directory[ansible\_distribution] }}/iptables’,  
‘Rocky’: ‘{{ iptables\_directory[ansible\_distribution] }}/iptables’, ‘Debian’: ‘{{ iptables\_directory[ansible\_distribution] }}/rules.v4’,  
‘Ubuntu’: ‘{{ iptables\_directory[ansible\_distribution] }}/rules.v4’}: ‘dict object’ has no attribute ‘Debian’. ‘dict object’ has no attribute ‘Debian’.

The error appears to be in ‘/work/armory/roles/xxx/tasks/xxx.yml’: line 266, column 3, but may be elsewhere in the file depending on the exact syntax problem.  
The offending line appears to be:

- name: Save new iptables - IPv4  
^ here

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [February 13, 2024, 1:52pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/2 "2024-02-13T13:52:37Z")

</div>

> I’ve been working this issue for a week now. The code used to work perfectly and now it fails. Here is the error I get:

Logic dictates that something has changed. Did you upgrade anything? Or otherwise make changes?  
That would be the obvious thing to check for you.

> I get a similar error when I target CentOS 9.

Similar means that it is different. What is the actual error there?

> ansible-core 2.14.3  
> python 3.11.2  
> jinja version = 3.1.2

> default.yml is being read in as I refer to other variables in the same file. Can anyone see an error that I’ve missed?

Where does this file reside? I.e. how is it “being read in”?

---

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [February 13, 2024, 2:32pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/3 "2024-02-13T14:32:59Z")

</div>

When I target CentOS I get this error:

The task includes an option with an undefined variable. The error was: {‘CentOS’: ‘{{ iptables\_directory[ansible\_distribution] }}/iptables’,  
‘Rocky’: ‘{{ iptables\_directory[ansible\_distribution] }}/iptables’, ‘Debian’: ‘{{ iptables\_directory[ansible\_distribution] }}/rules.v4’,  
‘Ubuntu’: ‘{{ iptables\_directory[ansible\_distribution] }}/rules.v4’}: ‘dict object’ has no attribute ‘CentOS’. ‘dict object’ has no attribute ‘CentOS’.

The error appears to be in ‘/work/armory/roles/xxx/tasks/xxx.yml’: line 266, column 3, but may be elsewhere in the file depending on the exact syntax problem.

Default.yml is at the playbook level in a folder called group\_vars. It is being read in by my playbook like this:

vars\_files:

- group\_vars/default.yml

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [February 13, 2024, 3:03pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/4 "2024-02-13T15:03:18Z")

</div>

Does the same thing happen for all distros? Or only for Debian/CentOS, and not for Rocky/Ubuntu?

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 13, 2024, 3:43pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/5 "2024-02-13T15:43:08Z")

</div>

Hey Kathy,

I’ve been trying to reproduce the problem without success. However, I think you’ve got one level of indirection too many going on. You have

```auto
iptables_directory:
  CentOS: "/etc/sysconfig"
  Fedora: "/etc/sysconfig"
  Rocky: "/etc/sysconfig"
  Debian: "/etc/iptables"
  Ubuntu: "/etc/iptables"
iptables_v4_rules:
  CentOS: "{{ iptables_directory[ansible_distribution] }}/iptables"
  Fedora: "{{ iptables_directory[ansible_distribution] }}/iptables"
  Rocky: "{{ iptables_directory[ansible_distribution] }}/iptables"
  Debian: "{{ iptables_directory[ansible_distribution] }}/rules.v4"
  Ubuntu: "{{ iptables_directory[ansible_distribution] }}/rules.v4"

```

(I added “Fedora” because that’s what I’m testing on; otherwise this doesn’t work at all.)

But, surly, the iptables\_v4\_rules[‘Rocky’] value is not going to change if I’m running on “Debian”? The way its written, if I’m on a Debian host, all of the iptables\_v4\_rules values will be “/etc/iptables/rules.v4”.

I think what it should be is this:

```auto
iptables_directory:
  CentOS: "/etc/sysconfig"
  Fedora: "/etc/sysconfig"
  Rocky: "/etc/sysconfig"
  Debian: "/etc/iptables"
  Ubuntu: "/etc/iptables"
iptables_v4_rules:
  CentOS: "{{ iptables_directory['CentOS'] }}/iptables"
  Fedora: "{{ iptables_directory['Fedora'] }}/iptables"
  Rocky: "{{ iptables_directory['Rocky'] }}/iptables"
  Debian: "{{ iptables_directory['Debian'] }}/rules.v4"
  Ubuntu: "{{ iptables_directory['Ubuntu'] }}/rules.v4"

```

In any case, it looks like somehow you’ve tricked the “lazy evaluation” engine to be even more lazy than it’s supposed to be, because it looks like it isn’t resolving the templates in the values. Not sure how you’ve managed that, but I’d really like to know!

Hope this helps. Cheers,

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [February 13, 2024, 3:51pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/6 "2024-02-13T15:51:10Z")

</div>

If ‘group\_vars’ is adjacent to your playbook, then ‘group\_vars/default.yml’ would also load if the host is in a group called ‘default’.  
So this file name/location is a bit ambiguous.

In any case I would only use the ‘vars\_files’ statement for files that are not automatically loaded.  
So I would remove the vars\_files statement from your playbook and then rename the vars file to ‘group\_vars/all.yml’.

Or create a dir ‘group\_vars/all’ and move it there: ‘group\_vars/all/default.yml’ (or main.yml, doesn’t matter)

---

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [February 13, 2024, 4:35pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/7 "2024-02-13T16:35:46Z")

</div>

When I make Todd’s changes, I get the same original error EXCEPT it tells me CentOS is not a dict, even though I am targeting a Debian box.

Dick, are you saying that the file all.yml in the group\_vars folder does not need to be explicitly stated in my playbook?

---

<div class="post-metadata">

**Author:** ![Walter\_Rowe](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/walter_rowe/32/4506_2.png) [@Walter\_Rowe](https://forum.ansible.com/u/Walter_Rowe)\
**Post date:** [February 13, 2024, 4:45pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/8 "2024-02-13T16:45:34Z")

</div>

> The error appears to be in ‘/work/armory/roles/xxx/tasks/xxx.yml’: line 266, column 3, but may be elsewhere in the file depending on the exact syntax problem.

> 

> The offending line appears to be:
> 
> - name: Save new iptables - IPv4  
> ^ here

The error is being reported by a role.

Is the group\_vars/default.yml being sourced by the role, or by the playbook that invokes the role? How are you invoking the role?

Walter

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [February 13, 2024, 5:19pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/9 "2024-02-13T17:19:06Z")

</div>

Yes.  
It sounds like the vars file is somehow used twice, which I think (after Todd’s comment) may screw up the level of laziness.  
(speculation on my side, but let’s see)

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 13, 2024, 7:51pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/10 "2024-02-13T19:51:17Z")

</div>

This bears repeating. I know I missed it the first few times I was told, and then the light came on.

- All hosts are in the “all” group. (That much I got the first time. 🙂

- Any files _or directories_ in ./group\_vars/ that match a host’s group names – including “all” – get loaded for that host. It was the “or directories” part I didn’t appreciate at first. For example, if a host is in the “foo” group, then the files ./group\_vars/foo, or better, ./group\_vars/foo.yml (the former won’t be ansible-linted; the latter will be) get loaded for that host. But more than that, if ./group\_vars/foo/ is a directory, then all the files within ./group\_vars/foo/ get loaded for all hosts in the foo group.

- That works even for groups that don’t exist when the playbook starts but are created on-they-fly by, for example, the ansible.builtin.group\_by module. This allows you to have amazingly crazy ad hoc groups – like “hosts the CEO has logged into in the last 30 minutes” – and still use relevant ./group\_vars/ files in a straightforward way.

We suffered a bit initially because in some of our projects different competing interests clashed over ownership of the ./group\_vars/all.yml file. When we realized we could have files ./group\_vars/all/interest\_aaa.yml, ./group\_vars/all/interest\_bbb.yml, ./group\_vars/all/interest\_ccc.yml, ./group\_vars/all/interest\_ddd.yml, etc., then the competition for that namespace became cooperation, and things just got much easier.

---

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [February 13, 2024, 8:55pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/11 "2024-02-13T20:55:01Z")

</div>

Todd- thank you for clearing that up for me

I made default.yml all.yml amd reran things with the same errors.

I am running my roles from within a playbook like this.

- roles

- role1  
become: true

- role2  
become: true

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [February 13, 2024, 9:38pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/12 "2024-02-13T21:38:45Z")

</div>

Do you still have that vars\_files: thing? As Dick suggested, it feels like that file is getting loaded more than once, and you don’t want that.

Is it at all possible that variables iptables\_v4\_rules and/or iptables\_directory are being set anywhere else?

_[If you want to toss the whole thing in a private repo that I can clone, or some other way get to me, I’m willing to take a look; I’m really curious to know how this is happening.]_

---

<div class="post-metadata">

**Author:** ![Kathy\_L](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kathy_l/32/2652_2.png) [@Kathy\_L](https://forum.ansible.com/u/Kathy_L)\
**Post date:** [February 14, 2024, 5:56pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/13 "2024-02-14T17:56:59Z")

</div>

I removed the vars\_file from my playbook.

I just double-checked and I am not loading iptables\_v4\_rules and/or iptables\_directory twice…

I wish I could throw it into a repo but this is on a non-Internet connected device and can’t be moved off.

I’ve moved from curious to frustrated.

---

<div class="post-metadata">

**Author:** ![Walter\_Rowe](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/walter_rowe/32/4506_2.png) [@Walter\_Rowe](https://forum.ansible.com/u/Walter_Rowe)\
**Post date:** [February 14, 2024, 5:59pm UTC](https://forum.ansible.com/t/dict-object-has-no-attribute/38686/14 "2024-02-14T17:59:55Z")

</div>

What if you don’t place the vars file in a groups\_vars subdirectory. What if you place it in the directory of the playbook that runs the roles.

vars\_files:

- my\_vars.yml

Where my\_vars.yml exists next to the playbook?

Walter
