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 to_yaml & to_nice_yaml Filters: Format Data as YAML (Guide)

By Luca Berton · Published 2026-04-03 · Category: database-automation

How to format data as YAML in Ansible with to_yaml, to_nice_yaml, from_yaml filters. Convert dicts and lists to YAML strings. Practical Jinja2 YAML examples.

The to_nice_yaml and to_yaml filters convert Ansible variables into YAML-formatted strings. They're essential for generating configuration files and debugging complex data structures.

to_yaml: Compact YAML

- name: Convert to compact YAML
  ansible.builtin.debug:
    msg: "{{ my_dict | to_yaml }}"

Output: {key1: value1, key2: value2}

See also: Ansible from_json & to_json Filters: Parse & Convert JSON (Guide)

to_nice_yaml: Human-Readable YAML

- name: Convert to readable YAML
  ansible.builtin.debug:
    msg: "{{ my_dict | to_nice_yaml }}"

Output:

key1: value1
key2: value2

Control Indentation

- name: Custom indent
  ansible.builtin.debug:
    msg: "{{ complex_data | to_nice_yaml(indent=4) }}"

See also: Ansible map Filter: Extract Attributes from Lists (Complete Guide)

Generate Configuration Files

- name: Write YAML config file
  ansible.builtin.copy:
    content: "{{ app_config | to_nice_yaml }}"
    dest: /etc/myapp/config.yml
    mode: '0644'

With a header comment

- name: Write config with header
  ansible.builtin.copy:
    content: |
      # Auto-generated by Ansible - DO NOT EDIT
      # Generated on {{ ansible_date_time.iso8601 }}
      {{ app_config | to_nice_yaml }}
    dest: /etc/myapp/config.yml

Practical Examples

Generate Docker Compose file

- name: Define compose config
  ansible.builtin.set_fact:
    compose_config:
      version: "3.8"
      services:
        web:
          image: "nginx:latest"
          ports:
            - "80:80"
          volumes:
            - "./html:/usr/share/nginx/html"

- name: Write docker-compose.yml ansible.builtin.copy: content: "{{ compose_config | to_nice_yaml }}" dest: /opt/app/docker-compose.yml

Debug complex variables

- name: Pretty-print all host facts
  ansible.builtin.debug:
    msg: "{{ ansible_mounts | to_nice_yaml }}"

Generate Kubernetes manifests

- name: Create K8s deployment
  ansible.builtin.copy:
    content: "{{ k8s_deployment | to_nice_yaml }}"
    dest: "/opt/k8s/deployment-{{ app_name }}.yml"

See also: Ansible map vs selectattr vs json_query: Filter Data the Right Way

to_nice_yaml vs to_yaml vs to_json

| Filter | Format | Human Readable | Use Case | |--------|--------|---------------|----------| | to_yaml | Compact YAML | No | Inline values | | to_nice_yaml | Indented YAML | Yes | Config files | | to_json | Compact JSON | No | API payloads | | to_nice_json | Indented JSON | Yes | JSON config files |

Handle Special Characters

# to_nice_yaml handles quoting automatically
- set_fact:
    config:
      password: "p@ss:word{special}"
      path: "/opt/my app/config"

- copy: content: "{{ config | to_nice_yaml }}" dest: /tmp/config.yml # Output properly quotes strings with special characters

Width Control

# Prevent line wrapping for long strings
- debug:
    msg: "{{ data | to_nice_yaml(width=1000) }}"

FAQ

Why does to_nice_yaml add quotes around some values?

YAML has special characters (:, #, {, etc.). The filter adds quotes when values contain characters that could be misinterpreted.

Can I control the YAML version output?

The filter uses PyYAML defaults (YAML 1.1). For YAML 1.2 compliance, post-process the output or use custom Jinja2 filters.

How do I handle boolean values?

PyYAML may represent booleans as true/false. If you need yes/no or True/False, convert with string filters before serialization.

Basic Usage

- vars:
    config:
      server:
        host: 0.0.0.0
        port: 8080
      database:
        host: db.example.com
        port: 5432
        name: myapp
  debug:
    msg: "{{ config | to_nice_yaml }}"

Output:

database:
  host: db.example.com
  name: myapp
  port: 5432
server:
  host: 0.0.0.0
  port: 8080

Control Indentation

- debug:
    msg: "{{ config | to_nice_yaml(indent=4) }}"

Write YAML Config Files

- name: Generate app config
  ansible.builtin.copy:
    content: "{{ app_config | to_nice_yaml }}"
    dest: /etc/myapp/config.yml
    mode: '0644'
  become: true

to_yaml vs to_nice_yaml

- vars:
    data: { a: 1, b: [1, 2, 3] }
  debug:
    msg:
      - "Compact: {{ data | to_yaml }}"
      # {a: 1, b: [1, 2, 3]}
      - "Nice: {{ data | to_nice_yaml }}"
      # a: 1
      # b:
      # - 1
      # - 2
      # - 3

YAML Filters Reference

| Filter | Output | |--------|--------| | to_yaml | Compact single-line YAML | | to_nice_yaml | Human-readable indented YAML | | from_yaml | Parse YAML string to data | | to_json | Compact JSON | | to_nice_json | Pretty-printed JSON |

Generate Kubernetes Manifests

- vars:
    deployment:
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: myapp
        labels:
          app: myapp
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: myapp
  ansible.builtin.copy:
    content: "{{ deployment | to_nice_yaml }}"
    dest: /opt/k8s/deployment.yml

In Templates

# config.yml.j2
---
{{ app_settings | to_nice_yaml }}

FAQ

Why does to_nice_yaml add quotes around some strings?

YAML auto-quotes values that look like booleans (yes, no, true), numbers, or contain special characters. This is correct YAML behavior.

How do I prevent sorting keys?

As of Ansible 2.14+, keys maintain insertion order by default in Python 3.7+.

Can I use to_nice_yaml with Ansible Vault encrypted values?

No — encrypted values must stay as !vault tagged strings. Use to_nice_yaml only for unencrypted data.

Basic Usage

- vars:
    config:
      database:
        host: db.internal
        port: 5432
      cache:
        enabled: true
        ttl: 3600
  debug:
    msg: "{{ config | to_nice_yaml }}"

Output:

cache:
  enabled: true
  ttl: 3600
database:
  host: db.internal
  port: 5432

to_yaml vs to_nice_yaml

- debug:
    msg: "{{ config | to_yaml }}"
    # Compact: {cache: {enabled: true, ttl: 3600}, database: {host: db.internal, port: 5432}}

- debug: msg: "{{ config | to_nice_yaml }}" # Human-readable with proper indentation

Control Indentation

- debug:
    msg: "{{ config | to_nice_yaml(indent=4) }}"

# With custom width (line wrap) - debug: msg: "{{ config | to_nice_yaml(indent=2, width=120) }}"

Write YAML to File

- copy:
    content: "{{ app_config | to_nice_yaml }}"
    dest: /etc/myapp/config.yml
  become: true

# With header comment - copy: content: | # Managed by Ansible - DO NOT EDIT {{ app_config | to_nice_yaml }} dest: /etc/myapp/config.yml

Generate Config Files

- vars:
    nginx_config:
      worker_processes: auto
      events:
        worker_connections: 1024
      http:
        sendfile: true
        keepalive_timeout: 65
        gzip: true
  copy:
    content: "{{ nginx_config | to_nice_yaml }}"
    dest: /opt/myapp/nginx-config.yml

from_yaml + to_nice_yaml (Reformat)

# Read messy YAML, write clean YAML
- slurp: { src: /etc/myapp/config.yml }
  register: raw

- copy: content: "{{ raw.content | b64decode | from_yaml | to_nice_yaml }}" dest: /etc/myapp/config.yml

In Templates

{# config.yml.j2 #}
# Auto-generated by Ansible
{{ config_data | to_nice_yaml }}

Combine and Output

- vars:
    defaults:
      log_level: info
      port: 8080
    overrides:
      log_level: debug
  set_fact:
    final: "{{ defaults | combine(overrides) }}"

- copy: content: "{{ final | to_nice_yaml }}" dest: /etc/myapp/config.yml

YAML Filter Reference

| Filter | Output | |--------|--------| | to_yaml | Compact single-line YAML | | to_nice_yaml | Formatted multi-line YAML | | to_nice_yaml(indent=4) | Custom indentation | | from_yaml | Parse YAML string to object | | to_json | Compact JSON | | to_nice_json | Formatted JSON |

FAQ

Why does to_nice_yaml sort keys?

YAML dumper sorts keys alphabetically by default. This is normal and doesn't affect functionality.

How do I preserve key order?

You can't with to_nice_yaml — it uses Python's YAML dumper which sorts keys. Use template with Jinja2 for exact control.

Strings with special characters?

to_nice_yaml automatically quotes strings that contain YAML special characters (:, #, {, etc.).

Related Articles

rendering Jinja2 templates with AnsibleAnsible JSON Conversion Guidecontainer lifecycle with Ansibleargv form of Ansible commandNginx deployment with Ansible

Category: database-automation

Browse all Ansible tutorials · AnsiblePilot Home