Writing Your First Playbook + Understanding YAML ✍️📘
Up to now, I’ve been flexing my Ansible muscles with ad-hoc commands. Handy for quick fixes, but let’s be honest—typing them over and over? Not ideal. This is where playbooks step in to save the day. Think of them like scripts: reusable, organized, and a lot more powerful. If ad-hoc commands are like Post-it notes, playbooks are your bullet journal. 🗂️
📖 What is a Playbook?
A playbook is a YAML file that tells Ansible what to do. It’s a list of plays, and each play targets a group of hosts and runs a series of tasks on them. Whether you’re installing packages, creating users, or spinning up services—playbooks are how you automate it.
If you're familiar with pubspec.yaml
from Flutter or any YAML-based config (like GitHub Actions), this will feel comfortably familiar. 💡
A basic playbook contains:
- Name – A human-friendly label 🏷️
- Hosts – The machines you want to affect 🧑💻
- Tasks – The step-by-step jobs for Ansible to run ✅
🔧 Using ansible.cfg
to Simplify Things ⚙️
One of the first things I did when starting out was to simplify my workflow. Typing -i inventory
and setting the key file every time gets old fast. Let’s fix that.
Create an ansible.cfg
file in your project folder with the following:
[defaults]
inventory = ./inventory
private_key_file = ./ansible
Now you don’t need to add -i inventory
or --private-key
to every command—Ansible will automatically know where to look. 🔍 It’s one of those tiny wins that make your life way easier.
🏁 First Playbook: Ping All Nodes 🛎️
Let’s ease into playbooks with a classic: the ping. This checks if our managed nodes are reachable.
Create a file named ping-nodes.yml
:
- name: Ping all nodes
hosts: all
tasks:
- name: Check connectivity
ansible.builtin.ping:
Run it with:
ansible-playbook ping-nodes.yml
Simple, right? 🎉 You’ve just written and executed your first Ansible playbook!
🛠 Second Playbook: Perform Multiple Tasks 🧰
Let’s get a little fancier. I wanted to try something a bit more involved—so I created a playbook that updates the system, installs a package, and creates a directory. Here’s how you can do it too.
Create multi-task.yml
:
- name: Multi-task playbook
hosts: all
become: true
tasks:
- name: Update APT cache
apt:
update_cache: yes
- name: Install curl
apt:
name: curl
state: present
- name: Create a directory
file:
path: /home/devuser/mydir
state: directory
mode: '0755'
owner: devuser
group: devuser
What this playbook does:
- 🌀 Updates the package index
- 📦 Installs
curl
if it's not already installed - 📁 Creates a directory at
/home/devuser/mydir
To run it:
ansible-playbook multi-task.yml --ask-become-pass
What’s that flag? ❓
-
become: true
: Tells Ansible to run the tasks with elevated privileges (likesudo
) -
--ask-become-pass
: Prompts you to enter the password for privilege escalation 🔐
Pro tip: I always like to include --ask-become-pass
for these early setups—it keeps things secure and makes sure you’re aware when privilege escalation is in play.
📦 Explore Other Modules 🧭
We’ve only scratched the surface. Here are some modules we used—and where you can learn more:
- 🟢 Ping: Test connectivity
- 📦 APT: Manage packages on Debian-based systems
- 📁 File: Create/remove files and directories
Whenever I'm unsure what a module can do—or what options it supports—the documentation is my go-to. Don’t hesitate to explore and experiment. 🧑🏫
⚠ Common Pitfalls 🪤
- YAML indentation: Always use spaces (not tabs), and make sure things are aligned properly
-
Forgetting
become: true
: Some actions (like installing packages) need elevated privileges. If they silently fail, this is likely why 😅 - Over-engineering too early: Start simple. Grow later. 🌱
💡 Try dry runs with --check
to preview what will happen:
ansible-playbook multi-task.yml --check
⏭ What’s Next? 🚀
With basic playbooks under your belt, the doors to automation are officially open. You can now replicate tasks, share them, version them—welcome to scalable DevOps! 🤖
In the next part, we’ll look at variables, conditionals, and handlers—making your playbooks even more powerful and dynamic.
Stay tuned. It only gets better from here ✨