Introduction to Ansible - Part 4

Created May 4, 2020


Welcome to part 4 of my Introduction to Ansible blog post series! If you have not read previous parts  of the Introduction to Ansible series, you can find them here:

    - Part 1: Here I cover what Ansible is and how to find your way around the Ansible documentation

    - Part 2: Here I cover how to install Ansible on Ubuntu on DigitalOcean and some of the main configuration files that you need to keep in mind

    - Part 3Here I covered what Ansible Ad-hoc commands are and we will introduce a few basic commands

In this part we will focus on what Ansible playbooks are, we create and run a few playbooks as well so make sure to have your 3 servers up and running and be able to follow along!

To make things even better you can use my referral link to get a free $100 credit that you could use to deploy your virtual machines and test the guide yourself on a few DigitalOcean servers:

Digital Ocean $100 Free Credit

What are Ansible Playbooks

As you might remember from the previous post the Ansible Ad-hoc commands are just like bash commands that you run via your terminal, on the other side the Ansible playbooks are like bash scripts, they take many steps and can be executed on many hosts.

Simply put, playbooks are the basis for really simple configuration management and multi-machine deployment system, unlike any that already exist, and one that is very well suited to deploying complex applications.

The Ansible playbooks are written in yaml format. If you are not familiar with yaml I would suggest that you go through a few courses to get your self up to speed as yaml is basically used everywhere nowadays. 

One thing to keep in mind is that the spacing in yaml is really important, even if you have one extra space the playbook would not work.

Ansible Playbook Example

To run a playbook we would use the ansible-playbook command followed by the playbook yaml file. Example:

ansible-playbook install.yml

The playbooks consist of a number of so-called plays. What a single play is just a task that has to be executed on a certain host.

Here's a very simple Ansible playbook:

# Example playbook

- hosts: webservers
  become: yes

  - name: Install Apache2 Latest
      name: apache2
      state: latest

  - name: create test.html
      name: /var/www/html/test.html
      state: touch

  - name: Add some content to the test.html file
      line: "Bobby Iliev Ansible"
      path: /var/www/html/test.html

  - name: Start Apache2
      name: apache2
      state: started

- hosts: dbservers
  become: yes

  - name: Latest MySQL
      name: mysql-server
      state: latest

  - name: Start MySQL
      name: mysql
      state: started

Side note: as a good practice I would recommend using version control for your playbooks. I would use git for example.

A quick rundown of the playbook:

#  - This is how we add comments in our playbooks
---  - Specifies the beginning of our playbook
- hosts - specifies the hosts that we would like to run the commands against
become: yes  - this means that we would run all commands as root
tasks: - specifies a list of the commands that we would be executing
-name - specifies the name of the task

You can copy and paste this to a install.yml file and run the playbook with this command:

ansible-playbook install.yml

You should get a similar output:

After that verify that your apache2 was installed and started and also that the test.html file was updated by visiting your IP address via your browser or run:

curl http://your_server_ip/test.html


Note: you should write your playbooks in a way that it is safe to run the playbook multiple times against one and the same target without any negative impact.

Ansible variables

You can use letters, numbers, and underscores for your variable naming conversion.

 You can pass your variables as an argument using the -e flag or you could specify the variables directly in your playbook.

In your playbook you would have something like this after the start of the playbook before our tasks:


- hosts: webservers
    my_service: apache2
    desired_state: started


  - name: Apache started
      name:  "{{ my_service }}"
      state: "{{ desired_state }}"

Or we could skip the vars part and specify it in our command directly:

ansible-playbook start.yml -e "my_service=apache2 desired_state=started"


Knowledge check

Once you've read this post, make sure to test your knowledge with this Ansible Playbooks Quiz:


For more information you can visit the official Ansible Playbooks documentation:

That's pretty much it for the Ansible Playbooks. We can now move to the ansible handlers and some useful tips:

Feel free to reach out to me in case you have any questions!