<p>It appears that the root cause was some internal incompatibility between the ancient ansible I'm forced to use and python 3.9.</p>
<p>Simply switching the virtual environment on my machine to use <strong>python 3.7</strong> resolved the issue and now the task runs successfully.</p>

CC BY-SA 4.0
2024-02-23T09:24:50.940Z
2024-02-23T09:26:10.600Z
2024-02-23T09:26:10.600Z
adoring_ellis
<p>Minimal reproducible example:</p>
<p><code>role/defaults/main.yaml</code>:</p>
<pre class="lang-yaml prettyprint-override"><code>node_sysctl:
  kernel.shmall: 197951838
  kernel.shmmax: 810810728448
  kernel.shmmni: 4096
</code></pre>
<p><code>role/tasks/main.yaml</code>:</p>
<pre class="lang-yaml prettyprint-override"><code>- name: Tune sysctl
  sysctl:
    name: &quot;{{ item.key }}&quot;
    value: &quot;{{ item.value }}&quot;
    reload: true
  loop: &quot;{{ lookup('dict', node_sysctl, wantlist=True) }}&quot;
  become: true
</code></pre>
<p>I'm trying to run this task against an Ubuntu 18.04 host. When I do, I get the following ansible error:</p>
<pre><code>TASK [../../../../ansible/roles/test-role : Tune sysctl] *********************************************************************************************************
fatal: [coordinator]: FAILED! =&gt; {&quot;msg&quot;: &quot;Invalid data passed to 'loop', it requires a list, got this instead:
 [{'key': 'kernel.shmall', 'value': 197951838}, {'key': 'kernel.shmmax', 'value': 810810728448}, {'key': 'kernel.shmmni', 'value': 4096}, {'key': 'vm.overcommit_memory', 'value': 2}, {'key': 'vm.overcommit_ratio', 'value': 95}, {'key': 'net.ipv4.ip_local_port_range', 'value': '10000 65535'}, {'key': 'kernel.sem', 'value': '250 2048000 200 8192'}, {'key': 'kernel.sysrq', 'value': 1}]. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup.&quot;}
</code></pre>
<p><code>loop</code> is clearly receiving a list here, and I don't understand why it won't work.</p>
<p>Running with python 3.9 on the local machine, and ansible:</p>
<pre><code>ansible --version

  import pkg_resources
ansible 2.7.10
  config file = None
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/.local/share/virtualenvs/linux-p5PCkeXK/lib/python3.9/site-packages/ansible
  executable location = /home/user/.local/share/virtualenvs/linux-p5PCkeXK/bin/ansible
  python version = 3.9.18 (main, Nov 28 2023, 14:57:43) [GCC 13.2.1 20231011 (Red Hat 13.2.1-4)]
</code></pre>
<p>I also tried using <code>with_items</code> instead of <code>loop</code>, which also produces an error:</p>
<pre><code>FAILED! =&gt; {&quot;msg&quot;: &quot;The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'key'
</code></pre>

<ansible><linux>
Ansible - 'loop' requires a list and got a list, but doesn't work
adoring_ellis
# Ansible - 'loop' requires a list and got a list, but doesn't work

(Asked by: username_0 on 2024-02-22)

Minimal reproducible example:
role/defaults/main.yaml:
node_sysctl:
  kernel.shmall: 197951838
  kernel.shmmax: 810810728448
  kernel.shmmni: 4096

role/tasks/main.yaml:
- name: Tune sysctl
  sysctl:
    name: "{{ item.key }}"
    value: "{{ item.value }}"
    reload: true
  loop: "{{ lookup('dict', node_sysctl, wantlist=True) }}"
  become: true

I'm trying to run this task against an Ubuntu 18.04 host. When I do, I get the following ansible error:
TASK [../../../../ansible/roles/test-role : Tune sysctl] *********************************************************************************************************
fatal: [coordinator]: FAILED! => {"msg": "Invalid data passed to 'loop', it requires a list, got this instead:
 [{'key': 'kernel.shmall', 'value': 197951838}, {'key': 'kernel.shmmax', 'value': 810810728448}, {'key': 'kernel.shmmni', 'value': 4096}, {'key': 'vm.overcommit_memory', 'value': 2}, {'key': 'vm.overcommit_ratio', 'value': 95}, {'key': 'net.ipv4.ip_local_port_range', 'value': '10000 65535'}, {'key': 'kernel.sem', 'value': '250 2048000 200 8192'}, {'key': 'kernel.sysrq', 'value': 1}]. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup."}

loop is clearly receiving a list here, and I don't understand why it won't work.
Running with python 3.9 on the local machine, and ansible:
ansible --version

  import pkg_resources
ansible 2.7.10
  config file = None
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/.local/share/virtualenvs/linux-p5PCkeXK/lib/python3.9/site-packages/ansible
  executable location = /home/user/.local/share/virtualenvs/linux-p5PCkeXK/bin/ansible
  python version = 3.9.18 (main, Nov 28 2023, 14:57:43) [GCC 13.2.1 20231011 (Red Hat 13.2.1-4)]

I also tried using with_items instead of loop, which also produces an error:
FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'key'

**Tags:** ansible, linux


---

## 1 answers

### Answer by username_0 on 2024-02-23. Score: 0

It appears that the root cause was some internal incompatibility between the ancient ansible I'm forced to use and python 3.9.

Simply switching the virtual environment on my machine to use **python 3.7** resolved the issue and now the task runs successfully.


---

