'dict object' has no attribute....

526 views
Skip to first unread message

Kathy L

unread,
Feb 13, 2024, 8:22:13 AM2/13/24
to Ansible Project
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

-------------------------------------------------------------------------------
This is the ansible task I have:

- name: Save new iptables - IPv4
  shell: "{{ iptables_save }} > {{ iptables_v4_rules[ansible_distribution] }}"
  when: firewall == "iptables"

And in my default.yml file I have:

iptables_directory:
  CentOS: "/etc/sysconfig"
  Rocky: "/etc/sysconfig"
  Debian: "/etc/iptables"
  Ubuntu: "/etc/iptables"
iptables_v4_rules:
  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"

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

  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?


Dick Visser

unread,
Feb 13, 2024, 8:53:03 AM2/13/24
to ansible...@googlegroups.com
On Tue, 13 Feb 2024 at 14:22, Kathy L <lyon...@gmail.com> wrote:
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"?

Kathy L

unread,
Feb 13, 2024, 9:33:00 AM2/13/24
to Ansible Project
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

Dick Visser

unread,
Feb 13, 2024, 10:03:52 AM2/13/24
to ansible...@googlegroups.com
Does the same thing happen for all distros? Or only for Debian/CentOS, and not for Rocky/Ubuntu?


Todd Lewis

unread,
Feb 13, 2024, 10:43:22 AM2/13/24
to ansible...@googlegroups.com, uto...@gmail.com
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
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:
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,
--
Todd

Dick Visser

unread,
Feb 13, 2024, 10:51:41 AM2/13/24
to ansible...@googlegroups.com
On Tue, 13 Feb 2024 at 15:33, Kathy L <lyon...@gmail.com> wrote:
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

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)

 

Kathy L

unread,
Feb 13, 2024, 11:35:46 AM2/13/24
to Ansible Project
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?

Rowe, Walter P. (Fed)

unread,
Feb 13, 2024, 11:45:48 AM2/13/24
to 'Rowe, Walter P. (Fed)' via Ansible Project
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
--
Walter Rowe, Division Chief
Infrastructure Services Division
Mobile: 202.355.4123

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/dc20f5fa-0045-4673-915f-8668c47d3acdn%40googlegroups.com.

Dick Visser

unread,
Feb 13, 2024, 12:19:38 PM2/13/24
to ansible...@googlegroups.com
On Tue, 13 Feb 2024 at 17:35, Kathy L <lyon...@gmail.com> wrote:
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?

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)

Todd Lewis

unread,
Feb 13, 2024, 2:51:31 PM2/13/24
to ansible...@googlegroups.com, uto...@gmail.com
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.

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

Kathy Lyons

unread,
Feb 13, 2024, 3:55:23 PM2/13/24
to ansible...@googlegroups.com, uto...@gmail.com
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

You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/irvn6QeOB_w/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/4858ac06-ca17-447e-a345-d52724145520%40gmail.com.

Todd Lewis

unread,
Feb 13, 2024, 4:38:46 PM2/13/24
to Ansible Project
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.]

Kathy L

unread,
Feb 14, 2024, 12:57:00 PM2/14/24
to Ansible Project
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.

Rowe, Walter P. (Fed)

unread,
Feb 14, 2024, 1:00:13 PM2/14/24
to 'Rowe, Walter P. (Fed)' via Ansible Project
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
--
Walter Rowe, Division Chief
Infrastructure Services Division
Mobile: 202.355.4123
Reply all
Reply to author
Forward
0 new messages