How do you test and debug Ansible playbooks?
Test and debug Ansible playbooks with ansible-lint, syntax-check, check mode, verbosity levels, the debug module, and Molecule for repeatable role testing.
Expected Interview Answer
You test and debug Ansible playbooks with a layered approach: static checks (ansible-lint, --syntax-check), a dry run (--check with --diff), verbose output (-v to -vvvv), the debug module, and dedicated tooling like Molecule for role testing.
Start with ansible-playbook --syntax-check and ansible-lint to catch YAML and best-practice issues before running anything. Use --check (check mode) with --diff to preview changes without applying them, and --start-at-task or --step to run incrementally. During execution, add -vvv for detailed output, use the debug module to print variables, register results and inspect them, and drop into the interactive debugger via the debugger keyword. For repeatable role testing, Molecule spins up containers to converge and verify.
- Catches errors before they hit production
- Check mode previews changes without applying them
- Verbosity levels expose exactly what Ansible is doing
- The debug module reveals variable and fact values
- Molecule enables automated, repeatable role testing
AI Mentor Explanation
Debugging a playbook is like a batter using net practice, slow-motion replays, and a coach's notes before facing a real match. The syntax check is inspecting your bat for cracks, check mode is a shadow-practice without a live ball, and verbose output is the replay showing exactly where your footwork went wrong before it costs a wicket.
Step-by-Step Explanation
Step 1
Lint and syntax-check
Run ansible-lint and ansible-playbook site.yml --syntax-check to catch YAML errors and anti-patterns early.
Step 2
Dry run with check mode
Use --check with --diff to preview what would change without applying it.
Step 3
Increase verbosity
Add -v, -vv, or -vvvv to reveal task arguments, connection details, and module output.
Step 4
Print with the debug module
Insert debug tasks with msg or var to inspect variables, facts, and registered results.
Step 5
Run incrementally
Use --start-at-task, --step, or tags to isolate the failing task instead of rerunning everything.
Step 6
Automate with Molecule
For roles, use Molecule to converge in a container and run verify assertions repeatably.
What Interviewer Expects
- Mentioning --syntax-check and ansible-lint for static analysis
- Explaining check mode (--check) and --diff
- Knowing verbosity levels -v through -vvvv
- Using the debug module and register to inspect state
- Awareness of Molecule for role testing and the debugger keyword
Common Mistakes
- Assuming check mode is fully accurate — some modules do not support it
- Debugging only in production instead of a staging inventory
- Overusing -vvvv and drowning in noise instead of targeting the failing task
- Forgetting that command/shell tasks skip in check mode unless check_mode is set
- Not using register + debug to see what a task actually returned
Best Answer (HR Friendly)
“To test Ansible playbooks I check them for mistakes first, then do a practice run that shows what would change without actually changing anything. If something breaks, I turn up the detail in the output and print the values I care about to find the problem, and for reusable pieces I use a tool called Molecule to test them automatically.”
Code Example
# Lint for best practices
ansible-lint site.yml
# Validate YAML/syntax without running
ansible-playbook site.yml --syntax-check
# Dry run: preview changes without applying them
ansible-playbook site.yml --check --diff
# Verbose run to see task details
ansible-playbook site.yml -vvv
# Start at a specific task or step through interactively
ansible-playbook site.yml --start-at-task="Install packages"
ansible-playbook site.yml --step- name: Inspect a command result
hosts: web
tasks:
- name: Gather disk usage
ansible.builtin.command: df -h /
register: disk
- name: Show the captured output
ansible.builtin.debug:
var: disk.stdout_lines
- name: Print a variable with a message
ansible.builtin.debug:
msg: "App version is {{ app_version }}"Follow-up Questions
- What is the difference between --check and --diff?
- Which modules do not support check mode and why?
- How does Molecule test an Ansible role end to end?
- How do you use the debugger keyword to pause on a failed task?
- How would you debug an undefined variable error in a template?
MCQ Practice
1. Which flag previews changes without applying them?
--check runs in check (dry-run) mode; pair it with --diff to see the actual differences that would be made.
2. What is the primary use of the debug module?
The debug module prints messages or variable values to help you inspect state while a playbook runs.
3. Which tool is purpose-built for automated Ansible role testing?
Molecule provisions test instances (often containers), converges the role, and runs verification steps for repeatable role testing.
Flash Cards
Static check commands — ansible-lint for best practices and ansible-playbook --syntax-check for YAML/syntax validation.
Check mode — --check does a dry run predicting changes; add --diff to see the exact differences.
Verbosity levels — -v to -vvvv increase detail; -vvvv includes connection debugging.
Molecule — A framework that provisions instances, converges a role, and verifies it for repeatable testing.