Ansible Configuration Drift Detection and Remediation
Configuration drift occurs when servers gradually deviate from their intended state — manual changes, ad-hoc fixes, and untracked modifications accumulate until systems become unpredictable. Ansible is one of the best tools to detect and fix this.
What is Configuration Drift?
Day 1: All servers match desired state ✅
Day 30: Someone changed a config manually 🔧
Day 60: Emergency hotfix on 2 servers ⚡
Day 90: "Why is server-3 different from server-1?" 😱
Common causes:
- Manual SSH changes bypassing automation
- Emergency fixes applied inconsistently
- Partial playbook runs that failed midway
- Different team members making ad-hoc changes
Detect Drift with Check Mode
Ansible's --check (dry run) mode shows what would change without making modifications:
ansible-playbook site.yml --check --diff
If the output shows changes, those servers have drifted from the desired state.
---
- name: Detect configuration drift
hosts: webservers
tasks:
- name: Ensure nginx config matches template
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
- name: Ensure required packages installed
ansible.builtin.package:
name:
- nginx
- python3
- htop
state: present
- name: Ensure unwanted packages removed
ansible.builtin.package:
name:
- telnet
- rsh
state: absent
Run with --check --diff to see drift without fixing it.
Automated Drift Detection Playbook
---
- name: Configuration drift audit
hosts: all
gather_facts: true
tasks:
- name: Check SSH config
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^PermitRootLogin'
line: 'PermitRootLogin no'
check_mode: true
register: ssh_drift
- name: Check firewall rules
ansible.builtin.command:
cmd: iptables -L -n
register: firewall_output
changed_when: false
- name: Check NTP configuration
ansible.builtin.lineinfile:
path: /etc/chrony.conf
regexp: '^server'
line: 'server ntp.company.com iburst'
check_mode: true
register: ntp_drift
- name: Report drift
ansible.builtin.debug:
msg: |
Drift detected on {{ inventory_hostname }}:
SSH config: {{ 'DRIFTED' if ssh_drift.changed else 'OK' }}
NTP config: {{ 'DRIFTED' if ntp_drift.changed else 'OK' }}
Remediation Strategies
1. Idempotent Playbooks (Recommended)
Write playbooks that describe the desired state, not steps. Run them regularly:
# GOOD — declarative, idempotent
- name: Ensure nginx is running and enabled
ansible.builtin.service:
name: nginx
state: started
enabled: true
# AVOID — imperative, not idempotent
- name: Start nginx
ansible.builtin.command: systemctl start nginx
2. Scheduled Runs
Run playbooks on a schedule via cron or Ansible Automation Platform:
# Crontab: enforce state every 4 hours
0 */4 * * * cd /opt/ansible && ansible-playbook site.yml --diff 2>&1 | mail -s "Ansible drift remediation" ops@company.com
3. Compliance Reporting with Tags
---
- name: Compliance check
hosts: all
tasks:
- name: CIS benchmark - SSH protocol version
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^Protocol'
line: 'Protocol 2'
tags: [compliance, cis, ssh]
- name: CIS benchmark - password max days
ansible.builtin.lineinfile:
path: /etc/login.defs
regexp: '^PASS_MAX_DAYS'
line: 'PASS_MAX_DAYS 90'
tags: [compliance, cis, password]
Run compliance checks only:
ansible-playbook site.yml --tags compliance --check --diff
Tools for Drift Detection
| Tool | Description |
|---|---|
ansible-playbook --check --diff | Built-in dry run with diff output |
| ARA Records Ansible | Web dashboard for playbook history |
| Ansible Automation Platform | Enterprise drift management |
| InSpec/OpenSCAP | Compliance frameworks that integrate with Ansible |
Best Practices
- Run playbooks regularly — Don't let drift accumulate
- Use
--diffmode — See exactly what changed - Lock down manual access — Minimize SSH access to production
- Version control everything — All playbooks in Git
- Alert on drift — Integrate check mode output with monitoring
- Document exceptions — If a server intentionally differs, document why
Related Articles
- Ansible Dry Run — Check and diff mode explained
- Ansible assert Module — Validate conditions
- Ansible Best Practices — Linting and best practices
- Ansible Error Handling — Handle failures
- Ansible Training — Courses and certifications
Conclusion
Configuration drift is inevitable without automation. Ansible's idempotent design makes it the ideal tool for both detection (check mode) and remediation (regular playbook runs). Start by running your existing playbooks with --check --diff to see how much drift exists today.