Ansible III (Running playbooks)

Alex Izuka
5 min readOct 23, 2023

I started a series discussing the major things you need to know about Ansible, you can check this for the first and this for the second. In this series, I will explain how to create and run playbooks.

Create and run playbooks

Creating, organizing, and running Ansible playbooks involves defining the automation tasks, structuring the playbook in YAML format, and executing it to automate actions on target hosts. Here’s how to do it:

1. Creating Playbooks:

  • Create a new file with a .yml extension to serve as your playbook, e.g., my_playbook.yml.
  • Define the playbook structure:
  • Begin with --- to indicate the start of a YAML document.
  • Specify the playbook name using the name field.
  • Define the target hosts using the hosts field.
  • List the tasks to be executed within the tasks section.

Here’s an example of a simple playbook:

---
- name: My First Playbook
hosts: web
tasks:
- name: Ensure Nginx is installed
apt:
name: nginx
state: present
- name: Start Nginx service
service:
name: nginx
state: started

2. Running Playbooks: Execute a playbook using the ansible-playbook command followed by the playbook filename.

ansible-playbook my_playbook.yml
  • You can specify extra variables with -e and limit playbooks to specific hosts or groups with -l.
  • To check a playbook without making changes, use the --check option:
ansible-playbook --check my_playbook.yml
  • To view the changes that would be made, use the --diff option:
ansible-playbook --diff my_playbook.yml

Ansible will execute the tasks defined in the playbook against the specified target hosts, applying the desired configurations and changes.

Using Ansible modules for various task

Ansible provides a wide range of modules for various tasks, such as package management, file operations, services, and user management. I will explain them below.

  1. Package Management (apt/yum): We can use Ansible to install or update a package using the apt module (Debian/Ubuntu) or yum module (RHEL/CentOS). See the usage below.
---
- name: Install Apache on Ubuntu
hosts: webserver
tasks:
- name: Install Apache
apt:
name: apache2
state: present

We can also equally remove package managers. We use the example below to explain that.

---
- name: Remove Apache on CentOS
hosts: webserver
tasks:
- name: Remove Apache
yum:
name: httpd
state: absent

2. File Operations (copy/template): Another operation we can perform with Ansible is the copying of files from one environment to another, we show the usage below.

---
- name: Copy Config File
hosts: webserver
tasks:
- name: Copy nginx.conf
copy:
src: /path/to/local/nginx.conf
dest: /etc/nginx/nginx.conf

In the example above, we copied a file from the control machine to remote hosts using the copy module. We can also use the template module to copy a template file and replace variables. See its usage below.

---
- name: Copy Template
hosts: webserver
tasks:
- name: Deploy Apache Virtual Host
template:
src: templates/vhost.conf.j2
dest: /etc/apache2/sites-available/mywebsite.conf

3. Services Management (service/systemd): We can also use Ansible modules to start or restart a service using the service module (for SysVinit) or systemd module (for systemd-based systems). See its usage below.

---
- name: Start Apache Service
hosts: webserver
tasks:
- name: Start Apache
service:
name: apache2
state: started

4. User Management (user/group): Ansible modules can be used to create a user or group. See usage below.

  • To create a user;
---
- name: Create User
hosts: webserver
tasks:
- name: Create a new user
user:
name: alex
state: present
  • To create a group;
---
- name: Add User to Group
hosts: webserver
tasks:
- name: Add user to 'developers' group
user:
name: alex
groups: developers
append: yes

These are just a few examples of the many Ansible modules available for various tasks. Ansible modules are versatile and can be combined in playbooks to automate complex workflows.

Installing & starting Nginx and Docker using Ansible

Below is a comprehensive Ansible playbook that installs Nginx, Docker, and starts both services. I’ll explain each component of the playbook afterward:

---
- name: Install Nginx and Docker
hosts: webserver
become: yes
vars:
packages_to_install:
- nginx
- docker.io
tasks:
- name: Update APT package cache
apt:
update_cache: yes
when: ansible_os_family == 'Debian'

- name: Update YUM package cache
yum:
name: "*"
state: latest
when: ansible_os_family == 'RedHat'

- name: Install required packages
package:
name: "{{ item }}"
state: present
loop: "{{ packages_to_install }}"

- name: Start and enable Nginx service
service:
name: nginx
state: started
enabled: yes

- name: Start and enable Docker service
service:
name: docker
state: started
enabled: yes

Explanation of the Playbook:

  • name: Install Nginx and Docker: This is a description of the playbook.
  • hosts: webserver: It specifies the target hosts or group (make sure to define webserver in your inventory).
  • become: yes: This instructs Ansible to become a superuser (usually by using sudo) to execute tasks that require elevated privileges.
  • vars:: Here, we define a variable called packages_to_install, which is a list of packages to install.

tasks:: This is where you define the tasks to be executed.

  • The first task updates the package cache using the apt module for Debian-based systems or the yum module for RedHat-based systems. It uses conditional execution based on the OS family.
  • The second task installs the required packages listed in the packages_to_install variable using the package module.
  • The next two tasks start and enable the Nginx and Docker services using the service module, ensuring that both services are running and configured to start at boot.

To run the playbook, use the ansible command below.

ansible-playbook playbook.yml

Replace playbook.yml with your file name.

Using dependencies like handlers and notify

In complex infrastructure setups, you may need to enforce certain conditions where one component must be installed or running before another. To achieve this, Ansible allows you to define dependencies and conditions using handlers and notify. Here's a playbook that installs Nginx and Docker while ensuring that Nginx is installed and running before Docker.

---
- name: Install Nginx and Docker with Dependencies
hosts: webserver
become: yes
vars:
packages_to_install:
- nginx
- docker.io
tasks:
- name: Update APT package cache
apt:
update_cache: yes
when: ansible_os_family == 'Debian'

- name: Update YUM package cache
yum:
name: "*"
state: latest
when: ansible_os_family == 'RedHat'

- name: Install Nginx
package:
name: nginx
state: present

- name: Ensure Nginx service is started and enabled
service:
name: nginx
state: started
enabled: yes
notify: Start Docker

- name: Install Docker
package:
name: docker.io
state: present
when: docker_status.stat.exists is not defined or docker_status.stat.exists == false
notify: Start Docker

handlers:
- name: Start Docker
service:
name: docker
state: started
enabled: yes

Explanation of the Playbook:

  • This playbook installs Nginx and Docker on a target host.
  • It first updates the package cache using the appropriate module for the OS family (Debian or RedHat).
  • It installs Nginx, ensuring that it is present on the system.
  • It checks if the Nginx service is already started and enabled. If not, it notifies the Start Docker handler to ensure Docker is only started once Nginx is running.
  • It then installs Docker but only if Docker is not already installed (checked using a condition in the when statement). It also notifies the Start Docker handler to ensure Docker is started after installation.
  • Finally, there’s a handlers section that defines the Start Docker handler. This handler will start and enable the Docker service when notified.

By using handlers and notify, you can define and enforce dependencies and conditions between tasks in your Ansible playbooks, ensuring that tasks are executed in the correct order.

Summarizing

In summary, we have looked at creating and running playbooks, using Ansible modules for various tasks, and using Ansible to install Nginx and Docker even with dependencies.

--

--