How to write Ansible playbooks.

In this blog, we are going to learn the basics of Ansible playbooks the important commands used, the syntax, the different modules and how to write a sample playbook including all these.
This blog is a continuation of our previous blog The Ultimate Guide For Learning Ansible From Scratch. Visit our previous blog to get some basics about Ansible and its working.
So let’s get started.

What is an Ansible playbook?

Ansible Playbook is a way to write automation procedures in Ansible using YAML syntax. It is a simple and efficient way to define and organize automation tasks, allowing you to manage and automate multiple systems at the same time. Playbooks can include one or more plays and each play maps to a set of tasks that are executed against a specific set of hosts.

So simply playbook is a text file in Ansible where we define codes for various tasks to execute.
But there is a proper syntax and format to write the playbook and execute tasks in it.

As you know ansible is written in YAML so we need to take extra care for the proper syntax while writing in YAML.

Various options defined in a playbook

  1. hosts: Specifies the hosts or group of hosts that the playbook will run against.
  2. vars: Allows you to define variables and their values that can be used throughout the playbook. Either we can define the variables with the playbook or else we can use a separate file and call the file in the playbook.
  3. tasks: The list of actions that the playbook will perform on the specified hosts. We can include multiple tasks in the same play.
  4. name: The name of the task, which is used for output and logging purposes.
  5. module: The Ansible module that will be executed in the task. Each module has a different purpose, for example, apt module, service module, docker module etc.
  6. args: The arguments that will be passed to the module when it is executed.
  7. register: Allows you to capture the output of a task and assign it to a variable for later use.
  8. condition: Allows you to specify a conditional statement that must be true for a task to be executed.
  9. notify: Allows you to trigger a handler when a certain task is executed.
  10. handlers: A list of tasks that can be triggered by notify a keyword
  11. include_tasks,import_playbook : Allows to include other playbooks or tasks in the current playbook.

Getting started with playbooks

These are just the common options in the playbook there are much more used, Just learning the theory about this option will not help you to write a playbook so let’s start with a basic example.

Consider a normal scenario in a Ubuntu server if got a requirement to install the Nginx web server we will run these commands

apt install nginx
systemctl start nginx.service
systemctl enable nginx.service

But here in Ansible, we need to call different modules for each task to execute,

In the below example, we are using the apt module which is used to install the Nginx web server and the service module to start and enable the service.

apt module: The apt module in Ansible is used to manage packages on systems that use the Advanced Package Tool (APT) package manager, such as Debian and Ubuntu. This module can be used to install, upgrade, or remove packages, as well as to update the package list and perform other actions related to package management.

Service module: The service module in Ansible is used to manage services on a remote host. It can be used to start, stop, restart, and check the status of a service. This module is platform-agnostic and can be used on various operating systems such as Linux, Windows and BSD

Here is an example of an Ansible playbook that can be used to install and configure the Nginx web server on a host.

---
- name: Install and configure nginx
  hosts: all
  become: true
  vars:
    nginx_version: latest
  tasks:
  - name: Install nginx webserver
    apt:
      name: nginx
      state: present
      version: "{{ nginx_version }}"
  - name: Start the nginx service
    service:
      name: nginx
      state: started
  - name: Enable nginx service on reboot
    service:
      name: nginx
      enabled: yes

So let’s break down the playbook.

name: This is used to just give an understandable name to the play and the tasks inside it This is different from the names used as arguments in the modules.

host: Here the host is given as all which means this playbook will execute on all the hosts. Ie it will install the Nginx web server on all the managed nodes configured.

become: The become line tells Ansible to run the tasks with superuser privileges (sudo).

vars: This section defines a variable called nginx_version the value “latest“, which can be used in the module later.

tasks: Here we are defining 3 tasks in the playbook let’s explain them one by one separately

First task: Install Nginx.

Here the first task is defined to install the Nginx web server using the module apt module. The name is used as just a naming for the task,apt module to install the nginx package, by looking at the name parameter, desired state (present) which means the package should be installed and the version ({{ nginx_version }}) which is a variable that is set to “latest” and can be changed to a specific version if needed.

Second task: Start the Nginx service

The second task is to start the Nginx service using the service module’s name parameter must match the exact service name as it is named on the target machine in order to work correctly
state parameter is used to specify the desired state of the service. The possible values for this parameter include “started”, “stopped”, “restarted”, and “reloaded”.

Third task: to enable the Nginx service

The third task is to enable the Nginx service using the same service module using the name parameter and enabled parameter. The name determines which service to be enabled and the enabled parameter indicated whether the service should be automatically started at boot time or not possible values are yes or no.

This is a perfect example of an ansible-playbook with a single play and multiple task

How to configure the host for Ansible

Ansible uses an inventory file to define the hosts and groups of hosts that it will manage. The inventory file is usually located at /etc/ansible/hosts or you can specify the path to the inventory file with -I option when running ansible commands.

Here’s an example of how you could set up a webservers and appservers group in an inventory file:

[webservers]
web1 ansible_host=192.168.1.10 ansible_user=ubuntu
web2 ansible_host=192.168.1.11 ansible_user=ubuntu


[appservers]
app1 ansible_host=192.168.1.20 ansible_user=ubuntu
app2 ansible_host=192.168.1.21 ansible_user=ubuntu

Kindly note that we need to setup ssh connection to these hosts for ansible to execute commands on these hosts visit our blog to learn how to add servers to the ansible control node
How to install and Configure Ansible on ubuntu 20.04

How to run ansible-playbook

To execute this playbook we can run the command

ansible-playbook playbookname.yml

To check the syntax of the playbook we can run the command

ansible-playbook –syntax-check playbookname.yml

To debug the playbook we can use the -v (verbose) flag to increase the verbosity of the output

ansible-playbook playbookname.yml -vvv

So that’s it you have learned how to write an ansible playbook now let’s dive deeper into it.

Ansible play’s vs playbook

We have learned about the ansible-playbook now so what is ansible play?

Play is a collection of tasks that are executed together to achieve a specific goal. Each play is associated with a group of hosts, and the tasks in the play are executed on these hosts. Plays allow you to organize tasks in a logical way and apply them to specific groups of hosts. So play’s are just the collection of task that executes in a specific host.
So is it possible to write multiple play’s in a single playbook? The answer is yes let’s learn how to do it.

Multiple play and multiple hosts

We can run multiple plays in a single playbook to multiple hosts, Check the below playbook the first play is targeted to the webserver host and it is responsible for the installation and configuration of Nginx on the host.

The second play targets appservers which are responsible for the installation and configuration of PHP in the host.

---
- name: Install and configure nginx
  hosts: webserver
  become: true
  vars:
    nginx_version: latest
  tasks:
  - name: Install nginx webserver
    apt:
      name: nginx
      state: present
      version: "{{ nginx_version }}"
  - name: Start the nginx service
    service:
      name: nginx
      state: started
  - name: Enable nginx service on reboot
    service:
      name: nginx
      enabled: yes

- name: Install PHP
  hosts: appservers
  become: true
  tasks:
  - name: Install PHP
    apt:
      name: php-fpm
      state: present
  - name: Start the PHP-FPM service
    service:
      name: php7.4-fpm
      state: started
  - name: Enable PHP-FPM service on reboot
    service:
      name: php7.4-fpm
      enabled: yes

This is how we can run multiple plays in the single playbook to multiple hosts.

Summary:
So that’s it we have covered the basic of the ansible-playbook and its structure.
Visit our other ansible blog to get a detailed understanding Ansible.

Leave a Reply

Your email address will not be published. Required fields are marked *