# How to save a list of dictionaries to a file with a correct indentation

**URL:** <https://forum.ansible.com/t/how-to-save-a-list-of-dictionaries-to-a-file-with-a-correct-indentation/36911>\
**Category:** Ansible Project\
**Created:** [July 27, 2022, 5:19pm UTC](https://forum.ansible.com/t/how-to-save-a-list-of-dictionaries-to-a-file-with-a-correct-indentation/36911 "2022-07-27T17:19:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![actionmystique](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/actionmystique/32/1678_2.png) [@actionmystique](https://forum.ansible.com/u/actionmystique)\
**Post date:** [July 27, 2022, 5:19pm UTC](https://forum.ansible.com/t/how-to-save-a-list-of-dictionaries-to-a-file-with-a-correct-indentation/36911/1 "2022-07-27T17:19:29Z")

</div>

The goal seems to be simple, but I cannot manage to get the indentation right.

**Playbook** :

- name: Saving a list of dictionaries to a file  
gather\_facts: false  
hosts:
- localhost  
strategy: debug  
tasks:
- name: Saving a list of dictionaries to a file  
vars:  
volumes:
- class: ‘data’  
id: ‘a61b96e7-427e-493a-993c-c3efc8a16aa1’  
size: ‘500GB’  
type: ‘ssd’  
template:  
src: “volumes.j2”  
dest: “…/files/volumes.yml”

**Template** :  
volumes:  
{{ volumes | to\_nice\_yaml(indent=10) }}

**Result** :  
volumes:

- class: data  
id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
size: 500GB  
type: ssd

**Expected result** :  
volumes:

- class: data  
id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
size: 500GB  
type: ssd

What is strange is that the indent value has no effect on the result.  
Am I doing something wrong or is this an issue with ansible?

---

<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:** [July 27, 2022, 6:02pm UTC](https://forum.ansible.com/t/how-to-save-a-list-of-dictionaries-to-a-file-with-a-correct-indentation/36911/2 "2022-07-27T18:02:05Z")

</div>

You’ve misunderstood what the indent parameter of `to_nice_yaml does`. It doesn’t shift everything to the right by that much. Rather, it tells how much to indent those things which must be indented, like dictionaries within dictionaries. You don’t have any so it has no effect.

Use the `indent` filter instead.

```auto
volumes:
    {{ volumes | to_nice_yaml() | indent(width=4, first=false) }}

```

> The goal seems to be simple, but I cannot manage to get the indentation right.
> 
> **Playbook** :
> 
> - name: Saving a list of dictionaries to a file  
> gather\_facts: false  
> hosts:
> - localhost  
> strategy: debug  
> tasks:
> - name: Saving a list of dictionaries to a file  
> vars:  
> volumes:
> - class: ‘data’  
> id: ‘a61b96e7-427e-493a-993c-c3efc8a16aa1’  
> size: ‘500GB’  
> type: ‘ssd’  
> template:  
> src: “volumes.j2”  
> dest: “…/files/volumes.yml”
> 
> **Template** :  
> volumes:  
> {{ volumes | to\_nice\_yaml(indent=10) }}
> 
> **Result** :  
> volumes:
> 
> - class: data  
> id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
> size: 500GB  
> type: ssd
> 
> **Expected result** :  
> volumes:
> 
> - class: data  
> id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
> size: 500GB  
> type: ssd
> 
> ## What is strange is that the indent value has no effect on the result. Am I doing something wrong or is this an issue with ansible?
> 
> 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-project+unsubscribe@googlegroups.com](mailto:ansible-project+unsubscribe@googlegroups.com).  
> To view this discussion on the web visit [https://groups.google.com/d/msgid/ansible-project/9147b9cf-c1ab-4102-905c-7f720c4401c0n%40googlegroups.com](https://groups.google.com/d/msgid/ansible-project/9147b9cf-c1ab-4102-905c-7f720c4401c0n%40googlegroups.com?utm_medium=email&utm_source=footer).

​

---

<div class="post-metadata">

**Author:** ![actionmystique](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/actionmystique/32/1678_2.png) [@actionmystique](https://forum.ansible.com/u/actionmystique)\
**Post date:** [July 28, 2022, 8:04am UTC](https://forum.ansible.com/t/how-to-save-a-list-of-dictionaries-to-a-file-with-a-correct-indentation/36911/3 "2022-07-28T08:04:25Z")

</div>

@Todd Lewis  
Thanks for pointing me to the right direction. 🙂  
Your suggestion is a bit too short:  
volumes:

- class: data  
id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
size: 500GB  
type: ssd

Strangely, it indents the first attribute of the list despite ‘first=false’.  
With:  
volumes:  
{{ volumes | to\_nice\_yaml | indent(width=8, first=false) }}

we get a correct result:  
volumes:

- class: data  
id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
size: 500GB  
type: ssd

which is close enough, although I don’t understand why we can’t get the original expected result.

---

<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:** [July 28, 2022, 11:11am UTC](https://forum.ansible.com/t/how-to-save-a-list-of-dictionaries-to-a-file-with-a-correct-indentation/36911/4 "2022-07-28T11:11:00Z")

</div>

It doesn’t help at all that googlegroups uses varying width fonts, especially since whitespace is so important in both YAML and Python.

The docs, as far as I’ve found, never define what `to_nice_yaml`’s `indent` parameter controls, but the experiment below shows it only affects the indentation of mapping keys, with the first position in an indentation being either a space or, if this is the first mapping of a list, a dash. The other unfortunate side effect of `to_nice_yaml` is that it sorts dictionary keys. Both `to_yaml` and `to_nice_yaml` are wrappers around calls to `yaml.dump()` with slightly different parameters. (Particularly, `default_flow_style` being `None` and `False`, respectively, and `to_nice_yaml` having a default `indent` of 4, both of which you can override with either `to_yaml` or `to_nice_yaml`.)

The `indent` filter does not indent “the first attribute of the list despite `first=false`.” The whitespace you see in your output before `- class` is the literal spaces before the `{{`.

Save the following as `indent.yml` and run  
`ansible-playbook indent.yml && cat ./indent.yml`  
to see exactly what “it only affects the indentation of mapping keys” means. It’s a lot more subtle than I expected.

```auto
- name: Saving a list of dictionaries to a file
  gather_facts: false
  hosts:
  - localhost
  tasks:
  - name: Saving a list of dictionaries to a file
    vars:
      topvar:
        volumes:
        - class: 'data'
          id: 'a61b96e7-427e-493a-993c-c3efc8a16aa1'
          size: '500GB'
          type: 'ssd'
          dict:
            dictd:
              dictd1: 1
              dictd2: 2
            dictc:
            - 111
            - 222
            - dictcdict:
                able: a
                baker: b
                charlie:
                - c1
                - c2
            dictb: beta
            dicta: alpha
    copy:
      content: |
         topvar_indent_2:
         {{ topvar | to_nice_yaml(indent=2) | indent(width=2, first=true) }}
         topvar_no_indent_defaults_to_4:
         {{ topvar | to_nice_yaml( ) | indent(width=4, first=true) }}
         topvar_indent_8:
         {{ topvar | to_nice_yaml(indent=4) | indent(width=8, first=true) }}
      dest: "./indent_output.yml"

```

The output is rather long, but I’ll post it here to save you the trouble:

```auto
topvar_indent_2:
  volumes:
  - class: data
    dict:
      dicta: alpha
      dictb: beta
      dictc:
      - 111
      - 222
      - dictcdict:
          able: a
          baker: b
          charlie:
          - c1
          - c2
      dictd:
        dictd1: 1
        dictd2: 2
    id: a61b96e7-427e-493a-993c-c3efc8a16aa1
    size: 500GB
    type: ssd

topvar_no_indent_defaults_to_4:
    volumes:
    - class: data
        dict:
            dicta: alpha
            dictb: beta
            dictc:
            - 111
            - 222
            - dictcdict:
                    able: a
                    baker: b
                    charlie:
                    - c1
                    - c2
            dictd:
                dictd1: 1
                dictd2: 2
        id: a61b96e7-427e-493a-993c-c3efc8a16aa1
        size: 500GB
        type: ssd

topvar_indent_8:
        volumes:
        - class: data
            dict:
                dicta: alpha
                dictb: beta
                dictc:
                - 111
                - 222
                - dictcdict:
                        able: a
                        baker: b
                        charlie:
                        - c1
                        - c2
                dictd:
                    dictd1: 1
                    dictd2: 2
            id: a61b96e7-427e-493a-993c-c3efc8a16aa1
            size: 500GB
            type: ssd

```

> @Todd Lewis  
> Thanks for pointing me to the right direction. 🙂  
> Your suggestion is a bit too short:  
> volumes:
> 
> - class: data  
> id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
> size: 500GB  
> type: ssd
> 
> Strangely, it indents the first attribute of the list despite ‘first=false’.  
> With:  
> volumes:  
> {{ volumes | to\_nice\_yaml | indent(width=8, first=false) }}
> 
> we get a correct result:  
> volumes:
> 
> - class: data  
> id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
> size: 500GB  
> type: ssd
> 
> which is close enough, although I don’t understand why we can’t get the original expected result.
> 
> > You’ve misunderstoodwhat the indent parameter of `to_nice_yaml does`.It doesn’t shift everything to the right by that much. Rather,it tells how much to indent those things which must be indented,like dictionaries within dictionaries. You don’t have any so ithas no effect.
> > 
> > Use the `indent`filter instead.
> > 
> > ```auto
> > volumes:{{ volumes | to_nice_yaml() | indent(width=4, first=false) }}
> > 
> > ```
> > 
> > > The goal seems to be simple, but I cannot manage to get theindentation right.
> > > 
> > > **Playbook** :
> > > 
> > > - name: Saving a list ofdictionaries to a file  
> > > gather\_facts: false  
> > > hosts:
> > > - localhost  
> > > strategy: debug  
> > > tasks:
> > > - name: Saving a list of dictionaries to a file  
> > > vars:  
> > > volumes:
> > > - class: ‘data’  
> > > id:‘a61b96e7-427e-493a-993c-c3efc8a16aa1’  
> > > size: ‘500GB’  
> > > type: ‘ssd’  
> > > template:  
> > > src: “volumes.j2”  
> > > dest: “…/files/volumes.yml”
> > > 
> > > **Template** :  
> > > volumes:  
> > > {{ volumes | to\_nice\_yaml(indent=10) }}
> > > 
> > > **Result** :  
> > > volumes:
> > > 
> > > - class: data  
> > > id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
> > > size: 500GB  
> > > type: ssd
> > > 
> > > **Expected result** :  
> > > volumes:
> > > 
> > > - class: data  
> > > id: a61b96e7-427e-493a-993c-c3efc8a16aa1  
> > > size: 500GB  
> > > type: ssd
> > > 
> > > What is strange is that the indent value has no effect onthe result.  
> > > Am I doing something wrong or is this an issue withansible?

​

---

<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:** [July 28, 2022, 1:44pm UTC](https://forum.ansible.com/t/how-to-save-a-list-of-dictionaries-to-a-file-with-a-correct-indentation/36911/5 "2022-07-28T13:44:35Z")

</div>

…and of course I screwed up my own example. That last bit was supposed to have `indent=8`, but I had `indent=4` instead. Fixed below (maybe).

Also, no idea why googlegroups split my yaml into blocks like it did either. [sigh] I’ve tried to fix that below, too, but I’m not counting on it.
