What is the Ansible debug Module?

The ansible.builtin.debug module prints messages, variables, and facts during playbook execution. It's the primary tool for troubleshooting and understanding what your playbook is doing.

- name: Hello world
  ansible.builtin.debug:
    msg: "Hello, World!"

Output:

ok: [server1] => {
    "msg": "Hello, World!"
}

If you omit msg, it defaults to "Hello world!".

Use var to display a variable's full value:

- name: Show a variable
  ansible.builtin.debug:
    var: ansible_distribution

# Output:
# ok: [server1] => {
#     "ansible_distribution": "Ubuntu"
# }

Use msg to combine text and variables:

- name: Show text with variable
  ansible.builtin.debug:
    msg: "OS is {{ ansible_distribution }} {{ ansible_distribution_version }}"
- name: Check disk space
  ansible.builtin.command: df -h /
  register: disk_output

- name: Show disk usage
  ansible.builtin.debug:
    var: disk_output.stdout_lines
- name: Show all mount points
  ansible.builtin.debug:
    var: ansible_mounts

- name: Show first mount point
  ansible.builtin.debug:
    msg: "Root mount: {{ ansible_mounts | selectattr('mount', 'equalto', '/') | first }}"
- name: Show user config
  ansible.builtin.debug:
    msg: |
      Username: {{ user_config.name }}
      Email: {{ user_config.email }}
      Role: {{ user_config.role }}
  vars:
    user_config:
      name: "admin"
      email: "admin@example.com"
      role: "superuser"

Verbosity Levels

Control when debug output appears using verbosity:

- name: Always shown (default, verbosity 0)
  ansible.builtin.debug:
    msg: "This always prints"

- name: Only with -v
  ansible.builtin.debug:
    msg: "Verbose output"
    verbosity: 1

- name: Only with -vv
  ansible.builtin.debug:
    msg: "Very verbose output"
    verbosity: 2

- name: Only with -vvv
  ansible.builtin.debug:
    msg: "Debug-level output"
    verbosity: 3

Run with verbosity:

ansible-playbook site.yml -v    # Shows verbosity: 1
ansible-playbook site.yml -vv   # Shows verbosity: 1 and 2
ansible-playbook site.yml -vvv  # Shows all

Parameters Reference

ParameterTypeDefaultDescription
msgstring"Hello world!"Message to print (supports Jinja2)
varstring—Variable name to display (no {{ }} needed)
verbosityinteger0Minimum verbosity level to show output

Important: Don't use msg and var together — they're mutually exclusive. Use msg when you want to format output; use var for raw variable inspection.

Loop with debug

- name: Show all users
  ansible.builtin.debug:
    msg: "User: {{ item.name }} ({{ item.role }})"
  loop:
    - { name: "alice", role: "admin" }
    - { name: "bob", role: "developer" }
    - { name: "carol", role: "viewer" }

Conditional Debug

- name: Warn about low memory
  ansible.builtin.debug:
    msg: "WARNING: Only {{ ansible_memtotal_mb }}MB RAM — minimum recommended is 2048MB"
  when: ansible_memtotal_mb < 2048

Full Troubleshooting Playbook

---
- name: Debug and inspect system
  hosts: all
  gather_facts: true
  tasks:
    - name: Show OS info
      ansible.builtin.debug:
        msg: "{{ ansible_distribution }} {{ ansible_distribution_version }} ({{ ansible_os_family }})"

    - name: Show Python version
      ansible.builtin.debug:
        var: ansible_python_version

    - name: Show total memory
      ansible.builtin.debug:
        msg: "RAM: {{ ansible_memtotal_mb }}MB ({{ (ansible_memtotal_mb / 1024) | round(1) }}GB)"

    - name: Show all IP addresses
      ansible.builtin.debug:
        msg: "{{ ansible_all_ipv4_addresses }}"

    - name: Show environment variable
      ansible.builtin.debug:
        msg: "PATH = {{ lookup('env', 'PATH') }}"

Common Mistakes

# ❌ Wrong — don't use {{ }} with var
- ansible.builtin.debug:
    var: "{{ my_variable }}"

# ✅ Correct — var takes the variable name directly
- ansible.builtin.debug:
    var: my_variable

# ❌ Wrong — can't use msg and var together
- ansible.builtin.debug:
    msg: "Value is:"
    var: my_variable

# ✅ Correct — use msg with inline variable
- ansible.builtin.debug:
    msg: "Value is: {{ my_variable }}"

Conclusion

The debug module is your best friend for troubleshooting Ansible playbooks. Use msg for formatted output, var for raw inspection, and verbosity to keep debug output out of production runs.

code with ❤️ in GitHub