How to write an Ansible playbook to configure servers
Build an inventory and an idempotent Ansible playbook to install and configure a web server across multiple hosts. Covers modules, handlers, and idempotency.
What and why
Ansible is an agentless configuration-management tool. It connects to servers over SSH and runs tasks defined in YAML playbooks. Tasks are idempotent, so running a playbook twice leaves the system in the same desired state. This tutorial installs and configures a web server.
Prerequisites
- Ansible installed on a control machine.
- SSH access to one or more target hosts.
- Basic Linux administration knowledge.
Steps
1. Create an inventory
List your hosts in inventory.ini:
[web]
10.0.1.10
10.0.1.11
Groups like [web] let you target sets of hosts.
2. Test connectivity
ansible -i inventory.ini web -m ping
The ping module confirms Ansible can reach and authenticate to each host.
3. Write the playbook
Create site.yml:
- name: Configure web servers
hosts: web
become: true
tasks: []
become: true runs tasks with privilege escalation (sudo).
4. Add tasks with modules
tasks:
- name: Install nginx
ansible.builtin.package:
name: nginx
state: present
- name: Deploy config
ansible.builtin.copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: Restart nginx
Modules describe desired state; Ansible decides what to change.
5. Use handlers for restarts
handlers:
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
A handler runs only when notified, so the service restarts only if its config changed.
Verification
Run ansible-playbook -i inventory.ini site.yml. The first run reports changes. Run it again: the recap should show changed=0, proving idempotency. Visit a host to confirm the web server responds.
Next Steps
Organize tasks into roles for reuse. Store secrets in Ansible Vault. Use variables and templates to render host-specific configuration from one source.
Prerequisites
- Ansible installed on a control node
- SSH access to target hosts
- Basic Linux administration
Steps
- 1Create an inventory
- 2Test connectivity
- 3Write the playbook
- 4Add tasks with modules
- 5Use handlers for restarts
- 6Run and verify idempotency