Ansible playbooks have become one of the most popular standard for automating IT infrastructure, application deployments and cloud provisioning. This comprehensive guide will cover the basics of playbooks and how they can help streamline operations.
A Brief History of Ansible Playbooks
Ansible was created by Michael DeHaan in 2012 and acquired by Red Hat in 2015. It was designed to be lightweight and agentless configuration management, compared to existing heavy-weight tools like Puppet or Chef that required agents on each node.
Playbooks were introduced to create reusable definitions for automating multi-step deployments. For example, deploying a web application might involve installing packages, creating users, configuring firewall rules – each step is defined as a playbook task that uses Ansible modules.
Over the years, Ansible Inc. focused on augmenting enterprise capabilities like role-based access control, secure credential management and Tower dashboard. These features made Ansible ready for large scale production usage.
The recent Ansible 2.9 release includes network automation functionality, candidate releases to test roles & collections and performance profiling for troubleshooting.
Now managed by Red Hat and backed by a strong open-source community, Ansible delivers a simple yet powerful way to standardize IT operations and remove manual work through automation using playbooks.
Ansible Playbook Language
Playbooks are written using YAML syntax. YAML stands for "YAML Ain‘t Markup Language" and provides an easy human readable data serialization standard.
Here is an example YAML playbook:
---
- name: Check web server status
hosts: web_servers
vars:
http_port: 8080
tasks:
- name: Ensure apache is running
ansible.builtin.service:
name: httpd
state: started
- name: Open firewall port
community.general.ufw:
rule: allow
port: "{{ http_port }}"
Compared to XML or JSON, YAML does not require enclosing all data structures within hierarchy of nested tags or braces. This makes YAML more compact and easier to work with.
Ansible also supports Jinja2 templating within YAML data structures. This allows parameterizing configuration files and generating them dynamically during playbook runtime.
Some common playbook components written in YAML:
Hosts: Inventory of target servers
Vars: Variables that can be referenced
Tasks: Action statements for using modules
Handlers: Event triggers for taking actions
Templates: File templates that can generate configs
This design allows you to orchestrate multi-step workflows declaratively, instead of having to write low level code.
Next, we‘ll see how to organize key parts of an Ansible playbook.
Components of Playbooks
Ansible playbooks contain plays, handlers, tasks, modules along with inventory and variables. Let‘s understand the purpose of each component:
Inventory: List of target hosts via IP, FQDNs or group names. Stored in INI or YAML formats. Dynamic inventory scripts can also be used.
Variables: Stores values like package names, file paths, user creds etc. Can be passed at run time or loaded from var files.
Plays: Logical group of tasks mapped to sets of hosts and user privileges.
Tasks: The actual units of work. Execute modules with arguments.
Handlers: Tasks that can be notified by other tasks and run once.
Modules: Supplied out of the box or custom written. Performs system actions.
Templates: Jinja2 template files rendered with vars during execution.
By combining these modules, Ansible allows you to model even highly complex provisioning and deployment workflows in a procedural manner. Let‘s take an example.
Writing Your First Playbook
Consider a scenario where you need to setup reverse proxy servers to load balance a web application. We can automate the installation and configuration of Nginx automatically using a playbook.
Here is what the playbook would look like:
---
- hosts: proxy_servers
become: true
vars:
proxy_port: 80
tasks:
- name: Install Nginx
yum:
name: nginx
state: latest
- name: Generate config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
- name: Start Nginx
service:
name: nginx
state: started
notify:
- Restart Nginx
handlers:
- name: Restart Nginx
service:
name: nginx
state: restarted
This playbook will:
- Install latest Nginx on hosts listed in inventory group
proxy_servers
- Generate Nginx config from a template
- Start Nginx service and trigger restart if config changes
Ansible modules carry out each step, while notify
triggers the handler. Very powerful!
Executing Playbooks
To run the above Nginx playbook:
ansible-playbook load_balancer.yml
We can also test/debug playbooks using --check
mode instead of making changes directly:
ansible-playbook --check load_balancer.yml
The output will display the execution status and changes on each host.
Monitoring Ansible Jobs
Ansible provides a console based UI to track execution of playbooks in real-time:
ansible-playbook load_balancer.yml --ask-become -C
The -C
displays consolidated stdout, without showing host by host output.
We can also integrate Ansible with monitoring tools like Datadog to track deployment status and other metrics.
Organizing Playbooks, Roles & Inventories
For larger projects, Ansible code can be organized similar to:
inventories/
production
staging
playbooks/
common.yml
webservers.yml
databases.yml
roles/
nginx/
tasks/
templates/
postgresql/
tasks/
The root playbooks
import sub-playbooks and roles that can be reused between projects.
Roles package together operations that can be shared, like having an Nginx or PostgreSQL role instead of repeating those tasks in multiple playbooks.
Inventories provide environment level groupings of target hosts.
Additional Playbook Features
Ansible offers many advanced capabilities through various modules & plugins:
Templates: Jinja2 templates render files with variables
Lookups: Query external data within playbook
Vault: Encrypt sensitive data like passwords
Tags: Selectively run specific tasks
Blocks: Exception handling within playbooks
And many more!
For example the set_facts
module can be used to define new variables, while loop
can iterate a task over a list.
By combining such features, very sophisticated provisioning code can be authored as playbooks.
Next, let‘s explore some tips on running playbooks reliabily in production.
Troubleshooting Ansible Playbooks
Like any automation tool, Ansible can also run into issues like:
- Hosts reporting as UNREACHABLE
- Play recap showing multiple failures
- Variable lookups failing unexpectedly
Some ways to troubleshoot Ansible issues:
- Use
-v
option multiple times to enable verbose output - Check host access and firewall rules
- Review errors for incorrect syntax or vars
- Trace execution line by line using debugger
- Analyze performance bottlenecks
Tuning parameters like default timeouts, host key checks might help in certain cases.
Being cloud infrastructure, possible that transient network issues cause blips. So retry mechanisms help to handle them.
Thorough validation on dev environments before promoting playbooks to production is highly recommended. Testing each task individually makes troubleshooting easier.
Integrating Ansible into CI/CD Pipelines
A key benefit of Ansible playbooks is ability to integrate them into application development lifecycles. Some ways you can trigger automation:
Through SCM commits: Hooks on code repositories to run playbooks directly on code changes.
Via Jenkins Job: Widely used open source automation server. Many ways to invoke Ansible behaviours based on job success/failures.
Using Ansible Tower: Dashboard by Red Hat focused on enterprise scale automation, RBAC and workflows.
Kubernetes Operators: Custom resources that wrap Operators can provide self-healing automation abilities.
As Custom CLI Tool: Package up playbook code to expose as command line tool for others. Streamline sharing.
By modeling infrastructure requirements in code review friendly playbook format, Ops and Developers can collaborate better on the delivery pipelines with visibility.
These integrations allow teams to apply principles of CI/CD into system administration activities as well using Ansible as the automation glue.
Why Ansible Playbooks for Configuration Management?
Some key aspects that make Ansible playbooks a great choice for system automation:
Minimal & Agentless – Leverages SSH, no agents needed
Easily readable Syntax – YAML playbooks like english!
Idempotent – Repeated runs make no changes if system state correct.
Push Based – Initiated from control node vs pull by agents
Thorough Module Library – 1700+ modules for all environments
Community Extensions – Collections allow custom and partner modules
Encrypted Secrets – Vault and credential plugins enable secret management
FlexibleInventory – Wide range of inventory sources supported
Scaling Down & Up – Handles small to extremely large environments
Reusable Abstractions – Roles, blocks and imports facilitate reuse
Procedural over Code – Operations modeled as playbooks vs scripts
Universal Deployment – Host agnostic – bare metal, VMs, containers, clouds
Free and Open Source – Supported by Red Hat and community
These capabilities make Ansible a very versatile tool for everything from simple configuration tasks to full-fledged orchestration of complex multi-tier enterprise applications.
Final Thoughts
This comprehensive guide covered the basics of Ansible playbooks as well how to practically apply automation for common sysadmin tasks.
We walked through the components of a playbook,execution, troubleshooting and best practices around version control and reusability constructs like roles.
Hopefully this provides a great starting point for both developers and operations engineers to collaborate better by embedding infrastructure requirements directly in code.
To take your Ansible skills to the next level, do check out the official documentation site and best practices guide for writing production grade playbooks.
The active Ansible community is also a great source for hints and howtos when working through complex automation challenges.
Happy automating with Ansible playbooks!