Ansible Configuration Management: Infrastructure as Code Complete Guide
By Luca Berton · Published 2024-01-01 · Category: installation
How to use Ansible for configuration management. Manage servers, enforce desired state, drift detection, compliance.
Ansible Configuration Management: Infrastructure as Code Complete Guide
Ansible is the most widely used agentless configuration management tool. It ensures servers are in a desired state — installing packages, managing services, deploying configurations, and enforcing compliance — all defined as code in YAML playbooks.
See also: Ansible Development: Write Custom Modules, Plugins & Collections
What is Configuration Management?
Configuration management ensures every server in your infrastructure is configured consistently and correctly. Instead of manually SSHing into servers, you define the desired state in code and Ansible enforces it.
Without configuration management:
Admin SSHs into server → edits config → restarts service → hopes it works
Different servers end up with different configurations (drift)
With Ansible:
# Define desired state once, apply everywhere
- hosts: webservers
become: true
tasks:
- ansible.builtin.apt:
name: nginx
state: present # Ensure nginx is installed
- ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf # Ensure correct config
- ansible.builtin.systemd:
name: nginx
state: started
enabled: true # Ensure running and starts on boot
Why Ansible for Configuration Management?
Agentless — No software to install on managed hosts (SSH only) Idempotent — Run the same playbook 100 times, same result Human-readable — YAML playbooks anyone can understand Immediate — Push changes when you want, no waiting for agent pull Multi-platform — Linux, Windows, network devices, cloud APIsSee also: Ansible vs Terraform: Key Differences & When to Use Each (2026 Guide)
Core Configuration Management Tasks
Package Management
- name: Ensure required packages
ansible.builtin.apt:
name:
- nginx
- postgresql-client
- python3-pip
- htop
- tmux
state: present
update_cache: true
cache_valid_time: 3600
Service Management
- name: Ensure services are running
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
loop:
- nginx
- postgresql
- redis
- name: Ensure unnecessary services are stopped
ansible.builtin.systemd:
name: "{{ item }}"
state: stopped
enabled: false
loop:
- cups
- avahi-daemon
Configuration Files
- name: Deploy application config
ansible.builtin.template:
src: app.conf.j2
dest: /etc/myapp/app.conf
owner: appuser
group: appuser
mode: '0640'
validate: /opt/myapp/validate-config %s
notify: restart myapp
User Management
- name: Ensure deploy user exists
ansible.builtin.user:
name: deploy
groups: [sudo, docker]
shell: /bin/bash
create_home: true
- name: Deploy SSH authorized keys
ansible.builtin.authorized_key:
user: deploy
key: "{{ lookup('ansible.builtin.file', item) }}"
loop:
- files/keys/admin1.pub
- files/keys/admin2.pub
Security Hardening
- name: Security hardening
block:
- name: Disable root SSH login
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
notify: restart sshd
- name: Set SSH idle timeout
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?ClientAliveInterval'
line: 'ClientAliveInterval 300'
notify: restart sshd
- name: Configure firewall
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop: ['22', '80', '443']
- name: Enable firewall
community.general.ufw:
state: enabled
default: deny
Cron Jobs
- name: Schedule backup cron job
ansible.builtin.cron:
name: "Daily database backup"
hour: "2"
minute: "30"
job: "/opt/scripts/backup-db.sh >> /var/log/backup.log 2>&1"
user: postgres
Configuration Drift Detection
# Check mode — detect drift without making changes
ansible-playbook site.yml --check --diff
# Report drift without fixing
- name: Check if config has drifted
ansible.builtin.template:
src: app.conf.j2
dest: /etc/myapp/app.conf
check_mode: true
register: config_check
- name: Alert on drift
ansible.builtin.debug:
msg: "⚠️ Config drift detected on {{ inventory_hostname }}"
when: config_check.changed
See also: Ansible vs Terraform: Are They the Same? Key Differences Explained (2026)
Role-Based Organization
site.yml
roles/
├── common/ # Applied to ALL servers
│ ├── tasks/main.yml
│ ├── handlers/main.yml
│ ├── templates/
│ └── defaults/main.yml
├── webserver/ # Web server configuration
├── database/ # Database configuration
└── monitoring/ # Monitoring agents
# site.yml — apply roles to server groups
- hosts: all
roles:
- common
- hosts: webservers
roles:
- webserver
- monitoring
- hosts: databases
roles:
- database
- monitoring
FAQ
What is Ansible configuration management?
Ansible configuration management uses YAML playbooks to define the desired state of your infrastructure — packages, services, files, users, and settings. Ansible enforces this state across all managed hosts, ensuring consistency and preventing configuration drift.
Is Ansible free for configuration management?
Yes. Ansible (open source) and ansible-core are completely free. Red Hat Ansible Automation Platform (AAP) is a paid product that adds a web UI, RBAC, scheduling, and support on top of open-source Ansible.
How does Ansible compare to Puppet and Chef for configuration management?
Ansible is agentless (SSH-based), uses YAML (no custom DSL), and is push-based. Puppet and Chef require agents on managed hosts and use their own languages (Puppet DSL, Ruby). Ansible has a lower learning curve and faster initial setup.
Can Ansible manage Windows for configuration management?
Yes. Ansible manages Windows hosts via WinRM or SSH using Windows-specific modules like win_package, win_service, win_template, and win_user. No agent is needed on Windows.
How do I detect configuration drift with Ansible?
Run ansible-playbook site.yml --check --diff to see what would change without making changes. Use check_mode: true on individual tasks and register the result to programmatically detect and alert on drift.
Conclusion
Ansible makes configuration management accessible with its agentless architecture, YAML syntax, and idempotent design. Define your infrastructure as code, enforce desired state across all servers, and detect drift with check mode.
Related Articles
• Getting Started with Ansible • Ansible for Beginners: Complete Guide • Ansible Best Practices • Ansible vs Puppet vs ChefCategory: installation