<p>Q: <em>&quot;<strong>How can I iterate over each zone?</strong>&quot;</em></p>
<p>A: Convert the dictionary to a list, .e.g. given the data in the variable <em>result</em></p>
<pre class="lang-yaml prettyprint-override"><code>    - debug:
        var: item
      loop: &quot;{{ result.firewalld_info.zones.public|dict2items }}&quot;
</code></pre>
<p>gives (abridged)</p>
<pre class="lang-yaml prettyprint-override"><code>  item:
    key: forward
    value: false

  item:
    key: forward_ports
    value: []

  item:
    key: icmp_block_inversion
    value: false

  ...
</code></pre>
<p>See <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#with-dict" rel="nofollow noreferrer">with_dict</a></p>

CC BY-SA 4.0
2021-12-04T21:00:32.317Z
Thanks. Great answer
Bryon
CC BY-SA 4.0
2021-12-04T06:37:53.510Z
2021-12-04T06:37:53.510Z
Vladimir Botka
<p>Since Vladimir answered this in the ansible context I'm going to give you a way to process this in the shell.</p>
<p>As a one liner:</p>
<pre><code>for zone in public work; do echo &quot;another iteration&quot;; cat fw.json | jq &quot;.firewalld_info.zones.$zone&quot;; done
</code></pre>
<p>Or as prettier code:</p>
<pre><code>for zone in public work
do 
        echo &quot;another iteration&quot;
        cat fw.json | jq &quot;.firewalld_info.zones.$zone&quot;
        # save it in a variable or pass it through another round of jq to extract details into variables
done
</code></pre>
<p>You're using <code>jq</code> to extract the subsections you want.  The biggest limitation of these examples is that the zones are hard-coded.  You can pull <a href="https://stackoverflow.com/a/23118607/2002471">the keys out with jq</a> to make this more flexible.</p>

CC BY-SA 4.0
2021-12-04T16:56:49.777Z
2021-12-04T16:56:49.777Z
chicks
<p>I am trying to work out how to iterate over some JSON that has repeated structures but have not used a list.</p>
<p>I am using the <code>ansible.posix.firewalld_info</code> module and it returns a dictionary for each zone:</p>
<pre><code>{
&quot;active_zones&quot;: true,
    &quot;changed&quot;: false,
    &quot;collected_zones&quot;: [
        &quot;public&quot;,
        &quot;work&quot;
    ],
    &quot;firewalld_info&quot;: {
        &quot;default_zone&quot;: &quot;public&quot;,
        &quot;version&quot;: &quot;0.9.3&quot;,
        &quot;zones&quot;: {
            &quot;public&quot;: {
                &quot;forward&quot;: false,
                &quot;forward_ports&quot;: [],
                &quot;icmp_block_inversion&quot;: false,
                &quot;icmp_blocks&quot;: [],
                &quot;interfaces&quot;: [
                    &quot;ens22&quot;,
                    &quot;ens20&quot;,
                    &quot;ens19&quot;,
                    &quot;ens18&quot;
                ],
                &quot;masquerade&quot;: true,
                &quot;ports&quot;: [
                    [
                        &quot;9090&quot;,
                        &quot;tcp&quot;
                    ]
                ],
                &quot;protocols&quot;: [],
                &quot;rich_rules&quot;: [],
                &quot;services&quot;: [
                    &quot;ssh&quot;,
                    &quot;cockpit&quot;,
                    &quot;MyCustomService&quot;
                ],
                &quot;source_ports&quot;: [],
                &quot;sources&quot;: [],
                &quot;target&quot;: &quot;DROP&quot;
            },
            &quot;work&quot;: {
                &quot;forward&quot;: false,
                &quot;forward_ports&quot;: [],
                &quot;icmp_block_inversion&quot;: false,
                &quot;icmp_blocks&quot;: [],
                &quot;interfaces&quot;: [
                    &quot;ens21&quot;
                ],
                &quot;masquerade&quot;: false,
                &quot;ports&quot;: [],
                &quot;protocols&quot;: [],
                &quot;rich_rules&quot;: [],
                &quot;services&quot;: [
                    &quot;ssh&quot;,
                    &quot;dhcpv6-client&quot;,
                    &quot;cockpit&quot;
                ],
                &quot;source_ports&quot;: [],
                &quot;sources&quot;: [],
                &quot;target&quot;: &quot;default&quot;
            }
        }
    },
    &quot;invocation&quot;: {
        &quot;module_args&quot;: {
            &quot;active_zones&quot;: true,
            &quot;zones&quot;: null
        }
    },
    &quot;undefined_zones&quot;: []
}
</code></pre>
<p><code>public</code> and <code>work</code> are dictionaries. How can I iterate over each zone under <code>firewalld_info</code> in this JSON?</p>

<ansible>
How to loop through json without an array
Bryon
# How to loop through json without an array

(Asked by: username_0 on 2021-12-04)

I am trying to work out how to iterate over some JSON that has repeated structures but have not used a list.
I am using the ansible.posix.firewalld_info module and it returns a dictionary for each zone:
{
"active_zones": true,
    "changed": false,
    "collected_zones": [
        "public",
        "work"
    ],
    "firewalld_info": {
        "default_zone": "public",
        "version": "0.9.3",
        "zones": {
            "public": {
                "forward": false,
                "forward_ports": [],
                "icmp_block_inversion": false,
                "icmp_blocks": [],
                "interfaces": [
                    "ens22",
                    "ens20",
                    "ens19",
                    "ens18"
                ],
                "masquerade": true,
                "ports": [
                    [
                        "9090",
                        "tcp"
                    ]
                ],
                "protocols": [],
                "rich_rules": [],
                "services": [
                    "ssh",
                    "cockpit",
                    "MyCustomService"
                ],
                "source_ports": [],
                "sources": [],
                "target": "DROP"
            },
            "work": {
                "forward": false,
                "forward_ports": [],
                "icmp_block_inversion": false,
                "icmp_blocks": [],
                "interfaces": [
                    "ens21"
                ],
                "masquerade": false,
                "ports": [],
                "protocols": [],
                "rich_rules": [],
                "services": [
                    "ssh",
                    "dhcpv6-client",
                    "cockpit"
                ],
                "source_ports": [],
                "sources": [],
                "target": "default"
            }
        }
    },
    "invocation": {
        "module_args": {
            "active_zones": true,
            "zones": null
        }
    },
    "undefined_zones": []
}

public and work are dictionaries. How can I iterate over each zone under firewalld_info in this JSON?

**Tags:** ansible


---

## 2 answers

### Answer by username_1 on 2021-12-04. Score: 4 | Accepted answer

Q: "How can I iterate over each zone?"
A: Convert the dictionary to a list, .e.g. given the data in the variable result
    - debug:
        var: item
      loop: "{{ result.firewalld_info.zones.public|dict2items }}"

gives (abridged)
  item:
    key: forward
    value: false

  item:
    key: forward_ports
    value: []

  item:
    key: icmp_block_inversion
    value: false

  ...

See with_dict

> **Comments:**
> **username_0**: Thanks. Great answer  

---

### Answer by username_2 on 2021-12-04. Score: 1

Since Vladimir answered this in the ansible context I'm going to give you a way to process this in the shell.
As a one liner:
for zone in public work; do echo "another iteration"; cat fw.json | jq ".firewalld_info.zones.$zone"; done

Or as prettier code:
for zone in public work
do 
        echo "another iteration"
        cat fw.json | jq ".firewalld_info.zones.$zone"
        # save it in a variable or pass it through another round of jq to extract details into variables
done

You're using jq to extract the subsections you want.  The biggest limitation of these examples is that the zones are hard-coded.  You can pull the keys out with jq to make this more flexible.


---

