Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2021-12-04T21:00:32.317Z
Answers: Thanks. Great answer
Answers: Bryon
Answers: CC BY-SA 4.0
Answers: 2021-12-04T06:37:53.510Z
Answers: 2021-12-04T06:37:53.510Z
Answers: Vladimir Botka
Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2021-12-04T16:56:49.777Z
Answers: 2021-12-04T16:56:49.777Z
Answers: chicks
Body: <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>
  
Tags: <ansible>
Title: How to loop through json without an array
UserDisplayName: Bryon
ThreadText: # 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*
  
  ```yaml
      - debug:
          var: item
        loop: "{{ result.firewalld_info.zones.public|dict2items }}"
  
  ```
  
  gives (abridged)
  
  ```yaml
    item:
      key: forward
      value: false
  
    item:
      key: forward_ports
      value: []
  
    item:
      key: icmp_block_inversion
      value: false
  
    ...
  
  ```
  
  See [with\_dict](https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#with-dict)
  
  > **Comments:**
  > **username_0**: Thanks. Great answer  
  
  ---
  
  ### Answer by username_2 on 2021-12-04. Score: 1
  
  Since username_1 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](https://stackoverflow.com/a/23118607/2002471) to make this more flexible.
  
  
  ---
  
  