Ansible debug Module: Print Variables & Debug Messages (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
How to print variables and debug messages with Ansible debug module (ansible.builtin.debug). Display var, msg, verbosity levels, register output.
The ansible.builtin.debug module prints variables, messages, and data structures during playbook execution. It's your primary tool for troubleshooting and understanding what Ansible is doing.
Print a Variable
- name: Print a variable
ansible.builtin.debug:
var: ansible_hostname
Output:
ok: [webserver1] => {
"ansible_hostname": "webserver1"
}
See also: Ansible Debug Module: Print Variables & Messages During Playbook Execution
Print a Message with Variables
- name: Print message with embedded variables
ansible.builtin.debug:
msg: "Host {{ inventory_hostname }} is running {{ ansible_distribution }} {{ ansible_distribution_version }}"
Print Multiple Variables
# Method 1: Multiple msg lines
- name: Print multiple vars
ansible.builtin.debug:
msg:
- "Hostname: {{ ansible_hostname }}"
- "IP: {{ ansible_default_ipv4.address }}"
- "OS: {{ ansible_os_family }}"
- "Memory: {{ ansible_memtotal_mb }}MB"
# Method 2: One task per variable
- name: Show hostname
ansible.builtin.debug:
var: ansible_hostname
- name: Show IP
ansible.builtin.debug:
var: ansible_default_ipv4.address
See also: Ansible Multi-Line Strings: Literal (|) & Folded (>) Block Scalars Guide
Print Multiline Output
# List format (each item on its own line)
- name: Multiline message
ansible.builtin.debug:
msg:
- "=== Server Report ==="
- "Host: {{ ansible_hostname }}"
- "Uptime: {{ ansible_uptime_seconds | int // 86400 }} days"
- "Load: {{ ansible_loadavg['1m'] }}"
- "===================="
Print Registered Command Output
- name: Get disk space
ansible.builtin.command: df -h
register: disk_output
changed_when: false
- name: Show disk space
ansible.builtin.debug:
var: disk_output.stdout_lines
- name: Show just stdout
ansible.builtin.debug:
msg: "{{ disk_output.stdout }}"
See also: Ansible ansible.builtin vs ansible.legacy: Collection Namespaces Explained
Print Complex Data Structures
Dictionary
- name: Show full dict
ansible.builtin.debug:
var: ansible_default_ipv4
- name: Show specific dict key
ansible.builtin.debug:
msg: "Gateway: {{ ansible_default_ipv4.gateway }}"
- name: Pretty-print as YAML
ansible.builtin.debug:
msg: "{{ my_dict | to_nice_yaml }}"
- name: Pretty-print as JSON
ansible.builtin.debug:
msg: "{{ my_dict | to_nice_json }}"
List
- name: Show full list
ansible.builtin.debug:
var: ansible_interfaces
- name: Show each item
ansible.builtin.debug:
msg: "Interface: {{ item }}"
loop: "{{ ansible_interfaces }}"
msg vs var
# msg — for formatted strings with embedded variables
- ansible.builtin.debug:
msg: "The server {{ inventory_hostname }} has {{ ansible_memtotal_mb }}MB RAM"
# var — for raw variable inspection (no quotes, no {{ }})
- ansible.builtin.debug:
var: ansible_memtotal_mb
# var with expression
- ansible.builtin.debug:
var: ansible_all_ipv4_addresses | length
Key difference: var shows the variable name and value as-is. msg lets you format a human-readable string.
Verbosity Control
Control when debug output appears with -v flags:
# Always shown (default)
- ansible.builtin.debug:
msg: "This always prints"
# Only with -v
- ansible.builtin.debug:
msg: "Verbose details"
verbosity: 1
# Only with -vv
- ansible.builtin.debug:
msg: "Very verbose details"
verbosity: 2
# Only with -vvv
- ansible.builtin.debug:
msg: "Debug-level details"
verbosity: 3
ansible-playbook site.yml # verbosity 0 (default tasks only)
ansible-playbook site.yml -v # verbosity 1+
ansible-playbook site.yml -vvv # verbosity 3+
Conditional Printing
- name: Warn if low disk space
ansible.builtin.debug:
msg: "WARNING: Disk usage above 90% on {{ inventory_hostname }}"
when: disk_percent | int > 90
- name: Show only on specific hosts
ansible.builtin.debug:
msg: "Production server detected"
when: "'production' in group_names"
Print All Facts
# Print ALL gathered facts (very verbose)
- name: Show all facts
ansible.builtin.debug:
var: ansible_facts
# Print specific fact categories
- name: Show network facts
ansible.builtin.debug:
var: ansible_default_ipv4
- name: Show OS facts
ansible.builtin.debug:
msg:
- "Distribution: {{ ansible_distribution }}"
- "Version: {{ ansible_distribution_version }}"
- "Family: {{ ansible_os_family }}"
- "Kernel: {{ ansible_kernel }}"
Print Variable Type
- name: Check variable type
ansible.builtin.debug:
msg: "Variable type: {{ my_var | type_debug }}"
Common Debugging Pattern
- name: Run command and debug if failed
ansible.builtin.command: /opt/app/healthcheck
register: health
ignore_errors: true
- name: Debug on failure
ansible.builtin.debug:
msg:
- "Health check FAILED"
- "Return code: {{ health.rc }}"
- "stdout: {{ health.stdout }}"
- "stderr: {{ health.stderr }}"
when: health.rc != 0
FAQ
How do I print a variable in Ansible?
Use ansible.builtin.debug with either var: variable_name (raw output) or msg: "Value is {{ variable_name }}" (formatted). The var parameter shows the variable name and value; msg lets you embed variables in strings.
How do I print multiple lines with debug?
Use a list for msg: msg: ["Line 1", "Line 2", "Line 3"]. Each list item appears on its own line in the output.
Why does my debug task show "VARIABLE IS NOT DEFINED"?
The variable isn't set at that point in execution. Common causes: fact gathering is disabled (gather_facts: false), the variable is defined in a different play/host, or there's a typo. Use | default('undefined') as a safe fallback.
Conclusion
Use debug with var for raw variable inspection and msg for formatted output. Use verbosity to control noise levels, and when for conditional debugging. For production playbooks, set verbosity: 1 or higher so debug output only appears when explicitly requested with -v.
Related Articles
• Ansible debug Module Guide • Ansible debug vs assert • Ansible Facts GuideCategory: troubleshooting