Ansible Playbooks
Describe the full desired state of a server in readable YAML β repeatable, shareable, version-controlled.
A playbook is a YAML file that describes the desired state of your servers as an ordered list of tasks. Unlike ad-hoc commands, playbooks are reusable, readable, and version-controlled β this is how Ansible is used in real projects.
π― Learning Objectives
By the end of this lesson you will:
- Read and write playbook YAML structure
- Use modules, variables, and handlers
- Run a playbook and read its output
- Understand idempotency in practice
Anatomy of a Playbook
Hereβs a complete playbook that installs and starts nginx on all web servers β webserver.yml:
---
- name: Configure web servers
hosts: web
become: true
tasks:
- name: Install nginx
apt:
name: nginx
state: present
update_cache: true
- name: Ensure nginx is running and enabled
service:
name: nginx
state: started
enabled: trueReading it top to bottom:
hosts: webβ target thewebgroup from the inventory.become: trueβ run with sudo.tasks:β an ordered list; each task calls a module (apt,service) with parameters.name:β a human-readable label shown in the output.
β YAML is whitespace-sensitive
Like Python, YAML uses indentation for structure β always spaces, never tabs. A single misaligned line will cause a parse error. Keep indentation consistent (2 spaces per level is the convention).
Run the Playbook
ansible-playbook -i inventory.ini webserver.ymlRun it again and watch changed drop to 0 β everything is already in the desired state. Thatβs idempotency in action.
Variables and Handlers
Variables keep playbooks flexible:
- name: Configure web servers
hosts: web
become: true
vars:
package_name: nginx
tasks:
- name: Install the web server
apt:
name: "{{ package_name }}"
state: presentHandlers run only when notified by a changed task β ideal for restarting a service only when its config actually changed:
tasks:
- name: Copy nginx config
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: Restart nginx
handlers:
- name: Restart nginx
service:
name: nginx
state: restartedπ‘ Why handlers matter
Without a handler youβd restart nginx on every run. With one, nginx restarts only when the config file actually changed β no needless service disruptions. Thatβs the idempotent mindset applied to side effects.
π§ͺ Hands-on Lab
Write Your First Playbook
- Write
site.ymltargeting yourwebgroup (or localhost) that installs a package (e.g.gitorhtop). - Add a second task that ensures a service is
started. - Run it with
ansible-playbookand read the PLAY RECAP. - Run it a second time and confirm
changed=0β proving idempotency.
π§ Knowledge Check
In a playbook, when does a handler run?
On the second run of an unchanged playbook, what do you expect in the PLAY RECAP?
πΌ Interview Preparation
What makes a good, maintainable Ansible playbook?
π Youβve Completed the Core Curriculum
Congratulations β youβve worked through Linux, Git & GitHub, Python, AWS, Azure, and Ansible. You can now operate Linux servers, version and collaborate on code, script automation in Python, deploy across the two largest clouds, and configure fleets of servers with Ansible. Thatβs a genuinely strong DevOps foundation.
From the homepage roadmap, natural next steps are Docker, Kubernetes, Terraform, and CI/CD β all ready to be built in this same format whenever you are.
π‘ Make it real
Tie it all together in one project: write app code, version it in GitHub, script the setup in Python, provision a server on AWS or Azure, and use an Ansible playbook to configure it. Doing the full loop once teaches more than reading each topic separately.