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