Ansible — Playbooks

Avishek Roy
teckdevops
Published in
6 min readMar 1, 2020
Ansible Playbook

Playbooks: Orchestration and simplifying configuration management and deployments

Ansible ad-hoc commands (supported by ansible modules) is a good way to start off as it provides an option to perform many useful operations on managed hosts, though it is not best suited for a multiplex of tasks, complex configuration management, and deployments.

Playbook takes ansible to the next level via orchestrating a set of manual tasks and bundle them into a single piece of code. It can be correlated as a set of play/s(operations) that got invoked(act) in a procedural manner to perform specific tasks.

It uses the YAML language that itself follows human-readable syntax and is quite user-friendly.

Let’s write some playbooks now to have the real-world feel and to understand it better.

Pre-requisites

To go along further my advice you to have a test setup i.e. a control node & a couple of target nodes to test the playbooks that we develop. If you already have your own ansible setup (a master node and 1 or more target hosts) then you can use the same Or follow the below links to setup it quickly Else you can also opt to do it later 😉.

  1. Docker Installation
  2. Ansible test setup (Refer to Example2).

Playbooks

To start off let’s refer to one of the below basic of playbooks that are used to check connectivity to all target hosts using ping module

1_ping.yaml

---
- hosts: all
tasks:
- name: ping all
ping:
  • A playbook(YAML) always start with three dashes designating metadata(also called as front matter).
  • Next up is to define or tell ansible where this playbook should be executed/run and that is done via hosts (hosts: all means all the available hosts).
  • tasks section basically tells ansible what action/s to be performed on available hosts. In our above playbook, we just telling Ansible to connect to target hosts and check if we can ping them all.
  • Time to run the playbook? — To do the same we use ansible-playbook command and pass the YAML file as an argument.
teckdevOps-controlnode$ ansible-playbook 1_ping.yaml
1_ping.yaml

``Decoding the output``

  • Play[all] → It says that the playbook is going to run on all available hosts.
  • Task[Gathering Facts] → Gather facts about available hosts i.e. if its active, available and ready to be connected. If connect check fails for any of the hosts, ansible will skip task execution on those hosts and finally report an error. Refer below snapshot(app1_down) and see what happens if we intentionally stopped ssh daemon on the app01 host.
app1_down
  • Task[connectivity check] → Play or task execution i.e. the tasks as we defined in playbook. Here it reports ok as ping is fine for both app01 and app02. This section will be more informative as we go further.
  • Play Recap → Summary of task executions and their results(success/failed/etc.) for each target host.

2_apache.yaml(v0)

Next up let’s install some packages on our available hosts i.e. using the yum module. Also, we going to improve and extend our playbook as we progress.

---
- hosts: all
become: yes
tasks:
- name: Install Apache
yum:
name: httpd
state: present

our playbook will be going to check if apache is installed or present on target hosts and install it if missing.

  • become: yes has been used as a privilege escalations so as to provide ansible user to escalate it access to act as root and install packages on target hosts.
  • In addition to privilege escalation, we might need to add ansible user as a password-less sudoer via adding below line to /etc/sudoers file
ansible ALL=(ALL) NOPASSWD: ALL

Above is not a good practice though and ansible provides few other options like use of ansible vault / to pass password via command line while running playbooks/ store password in configuration file etc. we just going to use this method so that not to complicate our process at this point of time and will leverage more of these methods in later articles.

  • tasks section contain a single task that is using the yum module to install apache(name=apache) if not already present(state=present) on target hosts.

Now, we have an apache installed on target hosts but the same is still not running yet. So, let's add a second task to start the apache post-installation.

apache.yaml(v1)

---
- hosts: all
become: yes
tasks:
- name: Install Apache
yum:
name: httpd
state: present
- name: Start Apache
service:
name: httpd
state: started

Next, let's add another task to our playbook i.e. customize the apache index page to our apache webserver using template module.

--TEST PAGE
teckdevOps-controlnode$
cat templates/index.html
This is Apache test page

apache.yaml(v3)

---
- hosts: all
become: yes
tasks:
- name: Install Apache
yum:
name: httpd
state: present
- name: Start Apache
service:
name: httpd
state: started
- name: Copy Index Page
template:
src: templates/index.html
dest: /var/www/html
apache_v3
curl test

Cool, so we did with the installation of apache and setting up an index page for it but do you notice an issue with our apache playbook? 👇

If you notice task2 is going to start apache even in case no changes to apache and its a bit of extra overhead if we deal with complex playbooks and deployments. To overcome the above scenario ansible provides handlers to run a specific task only in case of changed status.

apache.yaml(v4)

---
- hosts: all
become: yes
tasks:
- name: Install Apache
yum:
name: httpd
state: present
notify: restart apache
- name: Copy Index Page
template:
src: templates/index.html
dest: /var/www/html
notify: restart apache
handlers:
- name: restart apache
service:
name: httpd
state: restarted
apache_v4

Nothing changed in the last execution so the handler section was not invoked. We can tweak the apache index page to see the handler in action so, let’s modify it and rerun the playbook.

--TEST PAGE
teckdevOps-controlnode$
cat templates/index.html
This is Apache test page
Index Page Tweak to invoke ansible handler section.
apache_handler
curl app 01/02

Nice! 👍 our handler section invoked and performed well as we expected.

Postscript

Congratulations! you just wrote down some of Ansible playbooks and made it live. It was quite simple and straightforward but this is only the entry point into the playbook world and there is a lot more other stuff to grasp and to master e.g. ansible vault, roles, loops, conditions, error handling, etc. and those will be upcoming topics in Ansible series.

Happy Reading!

— A blog by teckdevOps

--

--