AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Multiline Strings: YAML Block Scalars | and > (Complete Guide)

By Luca Berton · Published 2026-04-03 · Category: installation

How to write multiline strings in Ansible YAML. Literal block (|), folded block (>), chomp indicators, and practical examples for shell commands and templates.

Working with multiline strings in Ansible playbooks is common but the YAML syntax can be confusing. This guide explains every multiline option with clear examples.

Literal Block Scalar: | (Keep Newlines)

The | character preserves newlines exactly as written:

- name: Run multi-line script
  ansible.builtin.shell: |
    echo "Step 1: Update packages"
    apt-get update
    apt-get upgrade -y
    echo "Step 2: Restart service"
    systemctl restart nginx

Each line becomes a separate line in the output. A trailing newline is added.

See also: Ansible troubleshooting - Error parser-error

Folded Block Scalar: > (Join Lines)

The > character joins lines with spaces (like a paragraph):

- name: Long description
  ansible.builtin.debug:
    msg: >
      This is a very long message that
      spans multiple lines in the YAML file
      but will be rendered as a single
      paragraph with spaces.

Output: This is a very long message that spans multiple lines in the YAML file but will be rendered as a single paragraph with spaces.\n

Chomp Indicators: Strip Trailing Newlines

|- Strip trailing newline

vars:
  greeting: |-
    Hello
    World
  # greeting = "Hello\nWorld" (no trailing newline)

|+ Keep all trailing newlines

vars:
  greeting: |+
    Hello
    World

# greeting = "Hello\nWorld\n\n" (keeps blank line)

>- Fold and strip

vars:
  query: >-
    SELECT *
    FROM users
    WHERE active = true
    ORDER BY name
  # query = "SELECT * FROM users WHERE active = true ORDER BY name"

>- is the most common for inline strings — folds to one line, no trailing newline.

See also: Ansible check_mode: Dry Run & Test Playbooks Without Making Changes

Summary Table

| Syntax | Newlines | Trailing | Use Case | |--------|----------|----------|----------| | | | Kept | Single \n | Shell scripts | | |+ | Kept | All kept | Preserving whitespace | | |- | Kept | Stripped | Clean multiline strings | | > | Folded | Single \n | Long descriptions | | >+ | Folded | All kept | Rare | | >- | Folded | Stripped | SQL queries, URLs, commands |

Common Use Cases

Shell scripts

- name: Deploy script
  ansible.builtin.shell: |
    set -euo pipefail
    cd /opt/app
    git pull origin main
    pip install -r requirements.txt
    systemctl restart myapp
  args:
    executable: /bin/bash

Long when conditions

- name: Complex condition
  ansible.builtin.debug:
    msg: "Conditions met"
  when: >-
    (ansible_os_family == 'Debian' and
     ansible_distribution_major_version | int >= 11) or
    (ansible_os_family == 'RedHat' and
     ansible_distribution_major_version | int >= 9)

SQL queries

- name: Run database query
  community.postgresql.postgresql_query:
    query: >-
      SELECT u.name, u.email, COUNT(o.id) as orders
      FROM users u
      LEFT JOIN orders o ON o.user_id = u.id
      WHERE u.active = true
      GROUP BY u.name, u.email
      ORDER BY orders DESC
      LIMIT 10

File content

- name: Create config file
  ansible.builtin.copy:
    content: |
      # Application Configuration
      app_name: MyApp
      debug: false
      database:
        host: db.example.com
        port: 5432
    dest: /etc/myapp/config.yml

Debug messages

- name: Multi-line debug message
  ansible.builtin.debug:
    msg: |-
      === Deployment Summary ===
      Host: {{ inventory_hostname }}
      Version: {{ app_version }}
      Environment: {{ env }}
      Status: SUCCESS

See also: Ansible when Conditional: Complete Guide with Examples

Jinja2 Multiline

- name: Template with multiline
  ansible.builtin.template:
    src: template.j2
    dest: /etc/myapp/hosts
  vars:
    servers:
      - 10.0.1.1
      - 10.0.1.2

# template.j2: # {% for server in servers %} # {{ server }} # {% endfor %}

FAQ

When should I use | vs >?

Use | (literal) when newlines matter (scripts, config files). Use > (folded) when you want one continuous string (messages, queries, conditions).

Why is my multiline string getting a trailing newline?

By default, both | and > add a trailing newline. Use |- or >- to strip it.

How do I indent content inside a literal block?

The first line's indentation sets the base. All subsequent lines are relative to that base:

content: |
  line 1 (base indent)
    indented line (2 extra spaces preserved)
  back to base

Literal Block (|) — Preserves Newlines

- name: Run multi-line script
  ansible.builtin.shell: |
    echo "Step 1: Update"
    apt update
    apt upgrade -y
    echo "Step 2: Install"
    apt install -y nginx
  become: true

Folded Block (>) — Joins Lines

- name: Long command on multiple lines
  ansible.builtin.debug:
    msg: >
      This is a very long message
      that spans multiple lines
      but will be joined into
      a single line with spaces.
  # Output: "This is a very long message that spans..."

Comparison

| Syntax | Newlines | Trailing Newline | |--------|----------|-----------------| | | | Preserved | Yes (one) | | > | Folded to spaces | Yes (one) | | |- | Preserved | No | | >- | Folded | No | | |+ | Preserved | All kept | | >+ | Folded | All kept |

Chomp Indicators

# Strip trailing newline
msg: |-
  line one
  line two
# Result: "line one\nline two" (no trailing \n)

# Keep trailing newline (default) msg: | line one line two # Result: "line one\nline two\n"

# Keep ALL trailing newlines msg: |+ line one line two

# Result: "line one\nline two\n\n\n"

Shell Commands

# Most common: | for multi-line shell
- shell: |
    cd /opt/myapp
    git pull origin main
    pip install -r requirements.txt
    systemctl restart myapp

# Folded for single long command - command: >- docker run --name myapp -p 8080:8080 -v /data:/data -e DB_HOST=localhost myapp:latest

Variables in Multiline

- copy:
    content: |
      [app]
      name={{ app_name }}
      port={{ app_port }}
      host={{ ansible_host }}
      env={{ app_env }}
    dest: /etc/myapp/config.ini

Template Content

- copy:
    content: |
      server {
          listen 80;
          server_name {{ domain }};
          root {{ document_root }};
      }
    dest: /etc/nginx/sites-available/{{ domain }}
  become: true

In Variables

vars:
  welcome_message: |
    Welcome to {{ inventory_hostname }}!
    Environment: {{ app_env }}
    Last deployed: {{ ansible_date_time.iso8601 }}

long_description: > This application provides a web interface for managing infrastructure automation tasks.

Jinja2 in Multiline

- debug:
    msg: |
      {% for host in groups['webservers'] %}
      Server: {{ host }} ({{ hostvars[host].ansible_host }})
      {% endfor %}

FAQ

When to use | vs >?

| (literal): Shell scripts, config files, any content where newlines matter • > (folded): Long sentences, descriptions, single-line commands split for readability

Why does my shell script fail with >?

> folds lines into one. Shell commands need | to preserve line breaks as separate commands.

How do I include empty lines in |?

Just leave blank lines — they're preserved:

msg: |
  First paragraph.

Second paragraph after blank line.

Related Articles

Jinja2 filters in Ansible templatesAnsible Multiline Strings Guideconditional execution with Ansible whenthe Ansible inventory deep-diveAnsible privilege escalation patterns

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home