This article was rewrite on December 23, 2024, to include advanced debugging techniques, common error scenarios, and their solutions based on my recent experiences with the latest version of Ansible.
TL;DR: What Is Ansible Debugging?โ
Ansible debugging is the process meant for finding and fixing specific bugs in executed Ansible playbooks and tasks that are not behaving as outlined.
Essential Ansible Debugging Commands You Needโ
Following are the debugging techniques I use daily:
-
Use verbose mode:
ansible-playbook playbook.yml -vvv
-
Utilize debug module:
debug: var=variable_name
-
Testing with check mode:
ansible-playbook playbook.yml --check
-
Check variables:
ansible-inventory --list
-
Run tasks step by step:
ansible-playbook playbook.yml --step
Why is Ansible Debugging So Important?โ
After years as a DevOps engineer, I am very confident in saying that debugging was probably the most tricky and difficult thing to perform on Ansible.
In this post, I'll share my field-tested methods for debugging Ansible playbooks, including the usual issues I face and how to get around them.
Here is what I'll cover:
- TL;DR: What Is Ansible Debugging?
- How to Use the Ansible Debug Module Effectively
- Getting the Most Out of Verbose Mode
- Real-World Ansible Debugging Examples
- Advanced Debugging Techniques That Actually Work
- Lessons From the Trenches: My Debugging Tips
- Ansible Debugging Reference Table
- Integrating Ansible debugging into CI/CD
- Conclusion
How to Use the Ansible Debug Module Effectivelyโ
The debug module is a module that I use to peek at variables and print messages during playbook execution. Here's how I use it:
- name: Show variable value
debug:
var: my_variable
- name: Display custom message
debug:
msg: "Current value: {{ my_variable }}"
Working with the debug module, following are some of the things that I have kept in mind:
- Specify the variable type correctly
- Use conditional debug messages
- Mask sensitive information
Getting the Most Out of Verbose Modeโ
Verbose mode is my go-to method for detailed information during playbook execution. I use three different verbosity levels depending on how much detail I need:
# Basic information
ansible-playbook playbook.yml -v
# More details
ansible-playbook playbook.yml -vv
# Maximum details - my preferred choice for tough debugging
ansible-playbook playbook.yml -vvv
Real-World Ansible Debugging Examplesโ
How to Debug Failed Tasks
When a task fails, here's my go-to debugging approach:
- name: Problematic task
command: /bin/false
register: result
ignore_errors: yes
- name: Debug output
debug:
var: result
when: result is failed
How to Verify Variable Values
I often need to verify whether variables set correctly. I do it the following way:
- name: Show all variables
debug:
var: hostvars[inventory_hostname]
Advanced Debugging Techniques That Actually Workโ
Running Playbooks Step by Step
When I need to look at each task closely, then I use step execution:
ansible-playbook playbook.yml --step
Testing Changes Safely with Check Mode
I always run my changes in check mode first. It has saved me from many potential issues:
ansible-playbook playbook.yml --check
Using Diff Mode to Track Changes
When I need to see exactly what changes will be made:
ansible-playbook playbook.yml --diff
Lessons From the Trenches: My Debugging Tipsโ
-
Name Your Tasks to Have Easy Debugging
- name: "[DEBUG] Check database connection"
debug:
msg: "DB Host: {{ db_host }}" -
Use Debug Mode Only When Needed
- debug:
msg: "{{ result }}"
when: debug_mode | default(false) | bool -
My Improved Debugging Process
- I start with always creating in verbose mode
- I always test the changes in check mode
- I check variables step by step
Ansible Debugging Reference Tableโ
Technique | Command | Use Case |
---|---|---|
Verbosity | ansible-playbook playbook.yml -vvv | Detailed playbook execution output |
Debug Module | debug: var=variable_name | Print variable values |
Check Mode | ansible-playbook playbook.yml --check | Test the changes without applying them |
Diff Mode | ansible-playbook playbook.yml --diff | See what changes would be made |
Step Execution | ansible-playbook playbook.yml --step | Execute the tasks one by one |
Limit Hosts | ansible-playbook playbook.yml --limit <hostname> | Run playbooks only on specific hosts |
Tags | ansible-playbook playbook.yml --tags <tag_name> | Run tasks with <tag_name> |
Skip Tags | ansible-playbook playbook.yml --skip-tags <tag_name> | Skip tasks tagged with <tag_name> |
List Tasks | ansible-playbook playbook.yml --list-tasks | Lists all the tasks in one's playbook without execution |
Syntax Check | ansible-playbook playbook.yml --syntax-check | Validating the syntax of playbook, but do not run |
Playbook Debugger | ANSIBLE_DEBUG=true ansible-playbook playbook.yml | Enable debug mode for detailed troubleshooting |
Variable Dump | ansible -m debug -a "var=hostvars[inventory_hostname]" <hostname> | Dump all variables for a host |
Inventory Check | ansible-inventory --list | Show details about inventory in JSON format |
Dry Run with Diff | ansible-playbook playbook.yml --check --diff | Preview changes with a detailed diff |
Integrating Ansible debugging into CI/CDโ
By integrating Ansible debugging into CI/CD, the results are smoother deployments, faster problem resolution, and increased confidence in automation processes.
Pre-Deployment Validations
Before making changes, validate your playbooks to catch errors early:
- Use Check Mode (--check): Make sure the playbook runs safely without making changes to target systems.
ansible-playbook playbook.yml --check
This step acts as a โdry run,โ showing what changes would be made.
Lint Your Playbooks (ansible-lint):
Automates syntax and best-practice checks. Integrate ansible-lint into your CI pipeline to catch potential issues:
ansible-lint playbook.yml
Inventory Testing and Variables:
Verify inventory and variables with the following commands:
ansible-inventory --list
ansible -m debug -a "var=hostvars[inventory_hostname]" all
Running Playbooks in Staging Environments
Always run your playbooks in a staging area before production:
Use tags to run specific debugging tasks in staging:
ansible-playbook playbook.yml --tags staging
Combine with --diff mode to see exact configuration changes:
ansible-playbook playbook.yml --diff
Automating Debug Logs
Capture detailed logs during pipeline execution for post-run analysis:
Enable verbosity in CI commands:
ansible-playbook playbook.yml -vvv
Save logs as artifacts to debug failed builds.
Redirect logs to files for easier troubleshooting:
ansible-playbook playbook.yml -vvv | tee ansible-debug.log
Configure centralized logging in ansible.cfg:
[defaults]
log_path = /var/log/ansible.log
Debugging Failed Tasks in Pipelines
Ansible provides tools to identify and fix root causes when tasks fail:
Register Results for Debugging:
Use the register keyword to capture task outputs and analyze failures:
- name: Debug failed task
command: /bin/false
register: result
ignore_errors: yes
- name: Print debug information
debug:
var: result
Fail Gracefully:
Use failed_when for clear error messages:
- name: Conditional failure
command: some_command
register: output
failed_when: "'ERROR' in output.stdout"
Post-Deployment Debugging and Verification
After deployment, automate validation steps:
Verify system states:
- name: Verify service is running
ansible.builtin.service:
name: nginx
state: started
register: service_status
- name: Debug service status
debug:
var: service_status
Integrate with monitoring tools (e.g., Prometheus, Datadog) to detect anomalies.
Incorporating Molecule Testing
Add Molecule to your CI/CD pipeline for role-based development:
- Test Ansible roles in isolated containers or VMs before production:**
molecule test
This automates linting, syntax checks, and functional tests.
Example CI/CD Pipeline Configuration
Below is an example of a CI/CD pipeline for debugging and deploying playbooks:
GitHub Actions Workflow:
name: Ansible CI/CD
on:
push:
branches:
- main
jobs:
ansible-debug:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Ansible
run: |
sudo apt update
sudo apt install ansible -y
- name: Validate Syntax
run: ansible-lint playbook.yml
- name: Dry Run
run: ansible-playbook playbook.yml --check
- name: Execute Playbook with Verbosity
run: |
ansible-playbook playbook.yml -vvv | tee ansible-debug.log
- name: Save Debug Logs
uses: actions/upload-artifact@v3
with:
name: ansible-logs
path: ansible-debug.log
Conclusionโ
Debugging Ansible can be a little intimidating at first; however, it is actually quite manageable with the right tools and techniques. The strategies that I shared in this guide have come from years of hands-on experience, often learning through difficult means.
I hope that these insights help you more effectively debug your Ansible playbooks. If you have any questions or want to share your own debugging experiences, feel free to reach out to me.