What are Ansible playbooks?
Ansible Playbooks
offer a repeatable, reusable, simple configuration management and multi-machine deployment system, one that is well suited to deploying complex applications. If you need to execute a task with Ansible more than once, write a playbook and put it under source control. Then you can use the playbook to push out new configuration or confirm the configuration of remote systems.
An Ansible playbook
can be defined as a configuration file written in YAML (Yet Another Markup Language) to provide instructions for things that need to be done to bring a managed node into the required state.
A playbook
is a list of plays
which runs in order from top to bottom. Within each play
, tasks also run in order from top to bottom. Playbooks with multiple ‘plays’ can orchestrate multi-machine deployments, running one play on your webservers, then another play on your database servers, then a third play on your network infrastructure, and so on. At a minimum, each play defines two things:
the managed nodes to target, using a pattern
at least one task to execute
Play: A Play is minimally a mapping between a set of hosts selected by a host specifier (usually chosen by groups but sometimes by hostname globs) and the tasks which run on those hosts to define the role that those systems will perform. There can be one or many plays in a playbook.
In other words, Play
refers to the set (one or more) of actions (tasks) you want to execute on a set (one of more) of hosts.
Features of Ansible Playbooks
Some of the key features of Ansible Playbooks include: -
Declarative Syntax
: Ansible playbooks use a simple YAML-based syntax, making them easy to read, write, and understand.Task Orchestration
: Playbooks allow you to define a sequence of tasks to be executed in a specific order, ensuring a consistent and controlled workflow.Idempotence
: Playbooks are designed to be idempotent, meaning they can be run multiple times without causing unintended changes. This ensures a predictable and reliable deployment process.Variables and Templating
: Playbooks support the use of variables and Jinja2 templating, enabling dynamic and customizable configurations.Conditionals and Loops
: Ansible playbooks offer conditionals and loop structures, allowing you to control task execution based on specific conditions or iterate over lists of values.Error Handling and Logging
: Playbooks provide mechanisms for handling errors gracefully and capturing detailed logs, aiding in troubleshooting and debugging.Reusability and Modularity
: Playbooks can be modularized into roles, allowing for the reuse of tasks across multiple projects, and promoting code organization and maintainability.
Ansible Playbook Components
Components of Ansible Playbook includes: -
Play
: A play is the fundamental building block of an Ansible playbook. It represents a set of tasks that are executed against a specific group of hosts defined in the inventory. Each play consists of two key components: thehosts
and thetasks
.Hosts
: Thehosts
section in a play defines the target hosts on which the tasks will be executed. Hosts can be specified using patterns, such as individual hostnames, IP addresses, or groups defined in the inventory.Tasks
: Thetasks
section contains a list of individual tasks that Ansible will perform on the target hosts. Tasks can be as simple as copying a file or more complex, involving multiple modules to achieve the desired state.Modules
: Ansible modules are the building blocks of tasks. They are pre-written scripts that abstract system commands and configurations. Modules handle tasks like installing software packages, managing files, configuring services, and more. Ansible provides a vast collection of modules, making automation tasks easier and platform-independent.Parameters
: Modules accept parameters to customize their behavior. Parameters are passed as key-value pairs within a task. These parameters vary depending on the module used and allow you to fine-tune the module's actions.Handlers
: Handlers are special tasks that are only executed when triggered by other tasks. They are used to respond to changes in the system state and perform actions like restarting services after a configuration change.Variables
: Ansible allows you to use variables to make your playbooks more dynamic and reusable. Variables can be defined at various levels, including playbook-level, host-level, and group-level. They can store values like configuration settings, file paths, or user-specific data.
How Do Ansible Playbooks Work?
Ansible playbooks
work by using YAML. A playbook
typically consists of one or more plays, which are a collection of tasks that are run in sequence. Each task is a single instruction that Ansible can execute, such as installing a package, configuring a service, or copying a file.
When you run an Ansible playbook
, Ansible first reads the playbook file and parses the YAML syntax. Then, Ansible connects to the remote hosts listed in the playbook and executes the tasks in sequence.
Ansible
uses a concept called modules to execute tasks. Modules are small, reusable programs that are written in Python. It has a large library of modules that are used to perform a range of tasks.
When Ansible
executes a task, it first looks for a module that matches the task's name. Ansible executes the module on the remote host if a matching module is found.
Ansible
will try to execute the task as a shell command if a matching module is not found. This means that you can use Ansible to execute any command that you can run from the command line.
Here are some of the steps involved in how Ansible playbooks
work:
The Ansible playbook is parsed and the tasks are executed in sequence.
For each task, Ansible looks for a matching module.
If a matching module is found, the module is executed on the remote host.
The task is executed as a shell command if a matching module is not found.
Ansible continues to execute the tasks in the playbook until all of the tasks have been completed.
How to Use Ansible Playbooks?
To use Ansible playbooks, follow these steps: -
Install Ansible
: Ensure that Ansible is installed on your control machine. Refer to the official Ansible documentation for installation instructions specific to your operating system.Inventory Configuration
: Create an inventory file that lists the target hosts or groups of hosts you want to manage with Ansible. The inventory file can be a simple text file or an INI/JSON/YAML file. Define hostnames, IP addresses, and any necessary connection parameters (such as SSH credentials) in the inventory file.Create a Playbook:
Create a YAML file with a .yaml or .yml extension to define your playbook. Playbooks consist of plays, which are sets of tasks to be executed on specific hosts or host groups.Define Plays and Tasks
: Within the playbook, define one or more plays, each with a set of tasks. Tasks represent individual units of work to be executed on the target hosts. Specify the modules to be used, along with their parameters, to perform the desired actions.Optional - Use Variables and Templates
: Leverage variables to make your playbook dynamic and reusable. Define variables within the playbook or in separate variable files. Use Jinja2 templates to generate configuration files or customize values based on variables dynamically.Run the Playbook
: Execute the playbook using the ansible-playbook command followed by the path to your playbook file. Ansible will read the playbook, connect to the target hosts specified in the inventory, and execute the defined tasks.Monitor and Verify
: During playbook execution, Ansible will provide feedback on each task's status. Monitor the output to ensure that the playbook runs without errors and performs the desired actions on the target hosts. Verify the changes made by the playbook on the target systems.Iterate and Refine
: Modify your playbook as needed to meet your specific requirements. Iterate, test, and refine your playbooks to automate additional tasks, manage different systems, or handle more complex scenarios.
How to Write Ansible Playbooks?
Every playbook breaks down into the same standard sections:
Playbooks begin with three hyphens. ---
Inventory
: Define the inventory file that lists the target hosts or groups where the playbook will be executed. Ensure the inventory is well-organized and up to date.Playbook Structure
: Organize your playbook into plays, which are units of work targeting specific hosts or groups. Each play consists of a set of tasks to be executed.- name: Deploy Web Application hosts: web_servers become: true tasks: # Defined Task
Tasks
: Define tasks within plays to specify the actions to be performed on the target hosts. Tasks should be atomic, idempotent, and focused on achieving a specific outcome.tasks: - name: Install required packages apt: name: ['apache2', 'php', 'mysql'] state: present
Variables and Templating
: Use variables to make playbooks flexible and reusable. Define variables in separate files or inventories and use Jinja2 templating for dynamic values.vars: app_name: MyWebApp app_port: 8080 tasks: - name: Configure Apache VirtualHost template: src: templates/virtualhost.conf.j2 dest: /etc/apache2/sites-available/{{ app_name }}.conf
Handlers
: Define handlers for tasks that need to be triggered conditionally. Handlers are actions that run only when notified by tasks and are typically used for service restarts or configuration reloads.tasks: - name: Restart Apache service service: name: apache2 state: restarted notify: Reload Apache Configuration handlers: - name: Reload Apache Configuration service: name: apache2 state: reloaded
Conditionals and Loops
: Utilize conditionals and loops to make playbooks more dynamic and adaptable. For example, conditionally execute a task based on the
presence of a file.tasks: - name: Copy configuration file if it doesn't exist copy: src: files/config.conf dest: /etc/app/config.conf when: not ansible_check_mode and not ansible_file_exists|bool
Error Handling and Logging
: Implement error-handling mechanisms to handle failures gracefully. Use thefailed_when
parameter to specify conditions that indicate task failure.tasks: - name: Ensure required packages are installed apt: name: ['package1', 'package2'] state: present failed_when: "'unable to locate' in result.msg"
Most playbooks end with three periods. …
A Practical Example of an Ansible Playbook
playbook.yml
---
- hosts: all
tasks:
- name: Install the Apache web server
apt:
name: apache2
state: present
- name: Configure the Apache web server
service:
name: apache2
state: started
enabled: yes
- name: Copy the index.html file to the web root
copy:
src: index.html
dest: /var/www/html/index.html
This playbook would install the Apache web server on all of the hosts listed in the hosts variable, and then configure it to start automatically when the system boots. It would also copy the index.html file to the web root.
The hosts variable specifies the hosts that the playbook will run on. In this case, the playbook will run on all of the hosts in the inventory file.
The tasks section of the playbook specifies the tasks that will be executed. Each task is a single instruction that Ansible can execute.
In this example, there are three tasks:
The first task installs the Apache web server using the apt module.
The second task configures the Apache web server using the service module.
The third task copies the index.html file to the web root using the copy module.
To run this playbook, you would need to save it as a file with a .yaml extension. Then, you would run the playbook using the ansible-playbook command. For example, to run the playbook on all of the hosts in the inventory file, you would run the following command: ansible-playbook playbook.yaml
TASKS
TASK 1: File Creation Ansible Playbook
Step 1: Login to AWS Console and connect your EC2 instance using SSH.
Step 2: Add all the server details in the inventory file on master server.
sudo vim /etc/ansible/hosts
[my-servers]
server1 ansible_host=<Server1_IPv4_Addr>
server2 ansible_host=<Server2_IPv4_Addr>
server3 ansible_host=<Server3_IPv4_Addr>
Step 3: Create an Ansible playbook on Master to create a file on a different servers( Node-1, Node-2 and Node-3).
sudo vim playbook.yml
---
- name: A playbook to create a file
hosts: all
become: true
tasks:
- name: Create a file
file:
path: /home/ubuntu/testfile.txt
state: touch
Step 4: Now to run this playbook use the command ansible-playbook
including the filename.
ansible-playbook playbook.yml
Step 5: Once the execution is finished, verify that the file has been created on different servers using the following command.
ansible all -a "ls /home/ubuntu"
TASK 2: User Creation Ansible Playbook
Step 1: Create an Ansible playbook for creating a new user on a different server.
- name: A playbook to create a new user
hosts: all
become: true
tasks:
- name: to create a user named <user_name>
user: name=<user_name>
Step 2: Run the playbook using the ansible-playbook command
ansible-playbook create_user.yml
Step 3: Once the execution is finished, to check if the user has been created, look for the user’s name in the /etc/passwd
file where all the user and system file details are stored on servers.
ansible server1 -a "cat /etc/passwd"
TASK 3: Docker Installation Ansible Playbook
Step 1: Create an Ansible playbook to install docker on a different server.
sudo vim install_docker.yml
- name: A Playbook to Install Docker
hosts: my-servers
become: yes
tasks:
- name: Add Docker GPG apt Key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: Add Docker Repository
apt_repository:
repo: deb https://download.docker.com/linux/ubuntu focal stable
state: present
- name: Update apt and install docker-ce
apt:
name: docker-ce
state: latest
update_cache: true
Step 2: Run the playbook using the ansible-playbook command.
ansible-playbook install_docker.yml
Step 3: Verify that Docker has been installed on multiple servers using the following command.
ansible all -a "docker --version"
Step 4: To get the Docker status of all the servers, use the following command:
ansible all -a "sudo systemctl status docker"
Conclusion
In Conclusion, An Ansible Playbook
is a script-like configuration file written in YAML that defines a set of tasks and roles to be executed by Ansible automation tool. Playbooks
are used for automating and orchestrating IT infrastructure tasks such as configuration management, application deployment, and system orchestration. They provide a declarative way to express desired states and configurations, allowing for consistent and repeatable automation across multiple servers.
A typical Ansible Playbook
consists of plays, which are sets of tasks, organized into roles, and associated with specific hosts or groups of hosts. Playbooks
leverage Ansible modules to perform actions on remote hosts, making it easy to manage diverse systems with minimal effort.
The simplicity of YAML syntax makes Ansible Playbooks
readable and accessible to both developers and system administrators.
In this blog, we have seen about Ansible Playbooks and how to write and execute the Playbooks.
Hope you find it helpful🤞 So I encourage you to try this on your own and let me know in the comment section👇 about your learning experience.✨
*👆The information presented above is based on my interpretation. Suggestions are always welcome.*😊
~Smriti Sharma✌