YAML Multiline String While Retaining Indentation and Newlines
Asked Answered
I

2

18

Background:

This is an Ansible playbook using templates to CONSTRUCT a yaml file from a template. So basically I have a jinja2 template file with a line as such:

private_key: {{ myvar }}

Ansible uses yaml to define the variables. So I will fill in the myvar value something like this. Here I am using the | special character to define a multiline string:

myvar: |

        - "-----BEGIN PRIVATE KEY-----"
        - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
        - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
        - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
        - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
        - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
        - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
        - "zzzzzzzzzzzzzzzzzz="
        - "-----END PRIVATE KEY-----"

However the output trims off the indentation:

  private_key:
- "-----BEGIN PRIVATE KEY-----"
- "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
- "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
- "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
- "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
- "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
- "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
- "zzzzzzzzzzzzzzzzzz="
- "-----END PRIVATE KEY-----"

Since the output file is a yaml itself, I need to retain the indentation. It seems no matter what I'll lose the indent.

I need the end result to look EXACTLY like this:

  private_key:
    - "-----BEGIN PRIVATE KEY-----"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "zzzzzzzzzzzzzzzzzz="
    - "-----END PRIVATE KEY-----"
Ingram answered 29/3, 2019 at 5:34 Comment(0)
I
31

I found the answer in a Google search right after posting the question.

Essentially the yaml string will strip indents, so in this case we have to use Jinja to insert spaces where they were stripped. Luckily this is super easy to do:

In the template file, I replaced this:

private_key: {{ myvar }}

With this:

private_key: {{ myvar | indent( width=4, indentfirst=True) }}

The width field can be adjusted for how many spaces of indentation are needed.

The actual variable declaration is done exactly like I posted in the question. However now with the indent added in the template, I now have the desired output with indentation:

  private_key:
    - "-----BEGIN PRIVATE KEY-----"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "asdfasdfasdfasdfasdfasdfadfasdfasdfasdfasdfasdfssadf"
    - "zzzzzzzzzzzzzzzzzz="
    - "-----END PRIVATE KEY-----"
Ingram answered 29/3, 2019 at 5:41 Comment(1)
Since Jinja 2.10, the parameter indentfirst has been renamed to just first: jinja.palletsprojects.com/en/3.0.x/templates/…Cailly
D
0

Kinda late, but because this is a high-ranked answer on google, you don't need any extra tools, you can just use an indentation indicator. Making indentation |2 will say "there's two spaces of indent compared to the key, and anything extra is content."

This will define a text block where the first two spaces are stripped, and anything after that is content:

myvar: |2
        - "foo"
  - "bar"

The content of the string is now:

      - "foo"
  - "bar"
Domino answered 21/7, 2024 at 17:49 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.