Ansible is an open-source automation tool that allows you to manage and configure your infrastructure from a single, central location. It is written in Python and uses a simple, human-readable language to define the tasks that you want to automate. This makes it easy to use, even for those who are new to automation and scripting.

One of the key benefits of using Ansible is that it is agentless, meaning that it does not require you to install any additional software on the machines that you want to manage. Instead, it uses SSH to connect to the machines and run the tasks that you have defined in your playbooks. This means that you can easily manage a large number of machines without having to worry about installing and maintaining agents on each one.

In this blog post, we will introduce you to Ansible and show you how to get started with running your first Ansible playbook. We will cover the installation and setup process, as well as the basics of writing and running a playbook. We will also touch on some of the advanced features of Ansible, such as roles and variables, and show you how to use them in your playbooks.

Let’s start by looking at how to install and set up Ansible on your local machine.

How to install Ansible and run your first playbook

To use Ansible, you will first need to install it on your local machine. Ansible is available for all major operating systems, including Linux, macOS, and Windows. This tutorial will work on both Linux and macOS but the steps should not change wildly on Windows.

To install Ansible, you will need to have Python and pip installed on your machine. If you do not already have them, you can follow the instructions on the Python website to install them.

Once you have Python and pip installed, you can use the following command to install Ansible:

pip install ansible

This will install the latest version of Ansible and all of the necessary dependencies.

Once Ansible is installed, you will need to configure it to connect to the machines that you want to manage. This is done using an inventory file, which is a list of the machines and their connection details.

To create an inventory file, create a new file called hosts in the /etc/ansible directory. You can use any text editor to create this file, such as nano or vim.

The inventory file should contain a list of the machines that you want to manage, along with their connection details. For example, if you want to manage two machines with the hostnames web1 and web2, your inventory file would look like this:

web1 ansible_host=192.168.1.100 ansible_user=root
web2 ansible_host=192.168.1.101 ansible_user=root

In this example, we are specifying the IP address of each machine and the username that Ansible should use to connect to the machine. You can also specify other connection details, such as the port number and the private key file to use for authentication.

Once you have created your inventory file, you can test your connection to the machines using the ping module. The ping module is a simple Ansible module that sends a ping command to each of the machines in your inventory file and checks for a response. To run the ping module, use the following command:

ansible all -m ping

This will run the ping module on all of the machines in your inventory file. If the connection is successful, you should see a response like this:

web1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

This indicates that Ansible was able to connect to both of the machines and run the ping command successfully. If you do not see a response like this, it means that there was a problem with the connection. Check your inventory file and make sure that the connection details are correct.

Now that you have installed Ansible and set up your inventory file, you are ready to start writing and running your first Ansible playbook. Let’s move on to the next section to learn more about how playbooks work.

Understanding Ansible playbook structure

An Ansible playbook is a file that contains a list of tasks that you want to automate. The playbook and tasks are written in YAML, a human-readable language that is easy to read and write. A playbook can contain one or more tasks, and each task can be run on one or more machines in your inventory file.

A playbook is made up of several different sections, each with its own purpose. The basic structure of a playbook is as follows:

---
- hosts: web1
  tasks:
  - name: Install Apache
    apt:
      name: apache2
      state: present

The --- at the beginning of the file indicates that this is a YAML file. The next line, - hosts: web1, specifies which host or group of hosts the tasks in this playbook should be run on. In this example, the tasks will be run on the host web1.

The tasks section is where you define the tasks that you want to run on the host or group of hosts. In this example, there is only one task, which is to install Apache. The name field is used to give the task a human-readable name, and the apt field specifies the module that should be used to run the task. In this case, the apt module is used to install a package from the apt repository.

This is a very simple example of an Ansible playbook, but it demonstrates the basic structure of a playbook and how the different sections work together. In the next section, we will show you how to run this playbook and see it in action.

Running your first playbook

Now that you have a basic understanding of how Ansible playbooks work, let’s try running your first playbook. In this section, we will use the playbook that we created in the previous section to install Apache on the host web1.

To run a playbook, use the ansible-playbook command, followed by the path to the playbook file. For example, if your playbook is saved in a file called install-apache.yml, you would run the following command:

ansible-playbook install-apache.yml

This will run the playbook and execute the tasks that you have defined. If the playbook runs successfully, you should see a output like this:

PLAY [web1] **************************************************************

TASK [Gathering Facts] ****************************************************
ok: [web1]

TASK [Install Apache] *****************************************************
changed: [web1]

PLAY RECAP ****************************************************************
web1                      : ok=2    changed=1    unreachable=0    failed=0

This output shows you the progress of the playbook as it runs. The Gathering Facts task is a built-in task that is run before any other tasks in the playbook. It collects information about the host, such as its operating system and installed packages, and makes this information available to other tasks in the playbook.

The next task, Install Apache, is the task that we defined in the playbook. The changed status indicates that the task was run and made changes to the host. In this case, the apt module was used to install Apache, so the changed status indicates that Apache was installed successfully.

At the end of the playbook, you can see a summary of the playbook’s results. The ok and changed values indicate the number of tasks that ran successfully and made changes, respectively. In this case, both tasks ran successfully and the Install Apache task made a change, so the ok value is 2 and the changed value is 1.

If you log in to the host web1 and run the apache2 -v command, you should see the version number of Apache that was installed. This indicates that the playbook ran successfully and installed Apache on the host.

Congratulations! You have just run your first Ansible playbook. In the next section, we will look at some of the more advanced features of Ansible, such as roles and variables, and show you how to use them in your playbooks.

Advanced Ansible features

Ansible provides several advanced features that can help you write more powerful and flexible playbooks. In this section, we will introduce two of these features: roles and variables.

Ansible Roles

Roles are pre-defined sets of tasks that you can reuse in your playbooks. A role can contain multiple tasks and other elements, such as files and templates, that are used by the tasks. Roles allow you to organize your tasks into logical units and reuse them in different playbooks.

To use a role in a playbook, you first need to define it. Roles are typically defined in a directory called roles, which is located in the same directory as your playbook. Each role is stored in a separate subdirectory within the roles directory. For example, if you have a role called apache, it would be stored in the roles/apache directory.

Within the role directory, there are several subdirectories that contain the different elements of the role. The tasks directory contains the tasks that make up the role, the files directory contains any files that are used by the tasks, and the templates directory contains any templates that are used by the tasks.

To use a role in a playbook, you can use the roles keyword, followed by the name of the role. For example, if you have a role called apache, you can use it in a playbook like this:

---
- hosts: web1
  roles:
  - apache

This will run the tasks in the apache role on the host web1. You can also specify multiple roles in a playbook, and they will be run in the order that they are listed.

Ansible Variables

Variables are values that can be used in your playbooks and templates. They allow you to parameterize your playbooks and templates, so that you can use the same playbook or template with different values. For example, you can use variables to specify the version of a package that you want to install, or the name of a file that you want to copy.

To use a variable in a playbook or template, you first need to define it. Variables are typically defined in a file called vars.yml, which is located in the same directory as your playbook. The vars.yml file contains a list of the variables and their values. For example, if you have a variable called apache_version, it would be defined in the vars.yml file like this:

apache_version: 2.4

To use a variable in a playbook or template, you can use the {{ and }} brackets to enclose the variable name. For example, if you want to use the apache_version variable in a playbook, you can use it like this:

---
- hosts: web1
  tasks:
  - name: Install Apache
    apt:
      name: apache2={{ apache_version }}
      state: present

In this example, the {{ apache_version }} variable will be replaced with the value that is defined in the vars.yml file, which is 2.4. This allows you to use the same playbook to install different versions of Apache by simply changing the value of the apache_version variable in the variables file. This makes it easy to use the same playbook for different scenarios, without having to rewrite the playbook for each scenario.

Loops in Ansible

Loops allow you to repeat a task or set of tasks multiple times with different values. This is useful when you want to perform the same action on multiple items, such as installing multiple packages or copying multiple files.

To use a loop in a playbook, you can use the with_items keyword, followed by a list of values. For example, if you want to install multiple packages using the apt module, you can use a loop like this:

---
- hosts: web1
  tasks:
  - name: Install packages
    apt:
      name: "{{ item }}"
      state: present
    with_items:
    - apache2
    - mysql-server
    - php7.0

In this example, the apt module will be run once for each item in the list, with the {{ item }} variable being replaced with the corresponding value. In this case, the apt module will be run three times, once to install apache2, once to install mysql-server, and once to install php7.0.

Ansible conditionals

Conditionals allow you to run a task or set of tasks only if a certain condition is met. This is useful when you want to perform an action only under certain circumstances, such as installing a package only if it is not already installed.

To use a conditional in a playbook, you can use the when keyword, followed by a condition. For example, if you want to install a package only if it is not already installed, you can use a conditional like this:

---
- hosts: web1
  tasks:
  - name: Install Apache
    apt:
      name: apache2
      state: present
    when: "apache2 not in ansible_pkg_mgr"

In this example, the apt module will be run only if the when condition is met. The ansible_pkg_mgr variable is a built-in variable that contains a list of the installed packages on the host. The when condition checks if apache2 is not in the list of installed packages, and if it is not, the apt module will be run to install it.

This condition is a bit redundant, as Ansible is smart enough to only run the apt module if the package is not already installed, but it is useful to show how conditionals work.

Ansible Filters

Finally, Ansible provides filters, which are functions that can be used to transform or manipulate values in your playbooks and templates. Filters are often used in conjunction with variables to format or modify the value of a variable before it is used in a task or template.

To use a filter in a playbook or template, you can use the | character, followed by the name of the filter and any arguments. For example, if you want to convert a variable to upper-case, you can use the upper filter like this:

- hosts: web1
  vars:
    package_name: apache2
  tasks:
  - name: Install package
    apt:
      name: "{{ package_name | upper }}"

Conclusion

Ansible is a powerful and flexible automation tool that allows you to manage and configure your infrastructure from a single, central location. Its simple, human-readable language and agentless design make it easy to use, even for those who are new to automation and scripting. The advanced features of Ansible, such as roles, variables, loops, conditionals, and filters, make it possible to write highly modular and reusable playbooks that can be adapted to different scenarios. With Ansible, you can automate your infrastructure and save time and effort in managing and maintaining your systems.