Getting Started with Ansible


When working on devops or system administration, one of the main tools you need to keep your eyes on is the configure management. Either be it a set of complex orchestrations or simply automated task, a configuration management tool can make your day easier.
Let’s be honest, we are living in the times of automation. If you have to do a task twice, it’s time to consider automating it. For this post we have decided to go with Ansible.

Ansible is an open source configuration management tool. What makes ansible so famous is its agent-less and push approach. In a nutshell, other solution like Chef or Puppet, work by installing an agent on the hosts that you manage. The agent is responsible for pulling changes from a master host. Usually they use their own channels, not ssh.
The advantage of Ansible is the simplicity on which it operates. Pushes are applied through SSH service, basically is the same as you would connect to your machines and run a set of commands, but instead you use a script to do the whole thing automatically, and with the bonus of having a lot of modules to make it even easier to write the script.

In this post we will show you how to install ansible, run some simple starting scripts and get started using it.

Installing Ansible

Installing ansible is also very simple. You can follow the instruction here depending on you machine. If you use pip, you can install it running this command:

$ sudo pip install ansible

Make sure to check that everything went ok by checking the ansible version

$ ansible --version

Adding hosts to inventory

Once you have Ansible installed, the first thing to do before running your tasks, is to specify the hosts that will be managed by Ansible.
Ansible uses a file called hosts, inside of ansible configuration files( for linux should be /etc/ansible/hosts) were you define instances of your hosts. You can add single hosts, or group of hosts like web servers or database servers, were you can run the same task on multiple hosts.
Let’s start by adding one host in a group of webservers. To do so, modify the file and add two lines like this:


[webservers] is the then name of the group or the group header. is the name of the host. You can use also IP’s.

Save the file and close it.
Now that we have at least one host configured, lets run some simple tasks with ansible.

$ ansible webservers -m ping -u root

This should return: | SUCCESS => {
"changed": false,
"ping": "pong"

As you can see, the ping command worked.

Running Ansible playbooks

In this part, we will start using Ansible Playbooks.
Playbooks combines task to be runned against a hosts when executed. For this demo, we will provision a LAMP stack. The playbook will install the LAMP components, Apache, PHP, MySQL. It will start Apache and then show a “Hello World” page.

First that start by writing simple web server with only php and apache.

The playbook.yml should look like this:

- hosts: all
- name: Install Apache
apt: name=apache2 state=present

- name: Install PHP module for Apache
apt: name=libapache2-mod-php5 state=present

- name: Start Apache
service: name=apache2 state=running enabled=yes

- name: Install Hello World PHP script
copy: src=index.php dest=/var/www/index.php mode=0664

The playbooks use YAML language. First is the hosts entry. This tell the playbook were the tasks will be runned. Then it’s the task session. Here you define the tasks that will the script will run. For each of them we set a name, so it’s more easy to understand what is going on during the playbook execution. For this playbooks we will use this modules: apt, service, copy. You can find more detailed information for each of them and more on the ansible docs pages.
Since in the last task, we are using the copy modolu, we need to have the index.php file that will be copied at the host.

echo “Hello World”;

A simple Hello World will do for the purpose of this post.

To run the playbook, you need to run the following:

$ ansible-playbook playbook.yml -u root

(for this demo am using root user, you can use also non root users)

After the playbook has been executed we will have a simple web server running on our hosts.

Ansible Roles

What did in the previous step, is that we wrote a simple ansible playbook which installs a web server using apache,php and runs a Hello World page.Now, what if our application needs also a database. Normally, we would include another task on the playbook which installs the database. But, in our production environments, databases are located in different servers. We don’t want to install apache on the database server, as we dont want a database installed in the web servers. So including everything in one playbook wont work in this case. Here is where we need Ansible Roles.

A role is a set of tasks and configuration grouped by a common functionality. For instance, a web server could be a role, a database server could be another role.
Before starting with writing the roles we need to understand the project directory structure

At the end, this the directory structure we will have for the project. First is the hosts file, were we will define the web servers and the database servers.Then, is the playbook.yml which will route how the roles will be runned.
The roles directory is were the tasks and the files will be stored. All the task will be writen within the main.yml file in their corresponding folder.
We already have the webserver main.yml file ready, all we need to do is remove the hosts entry and copy the rest.
Now we need to write the main playbook.yml. It should look like this:

- name: Apply web server configuration
hosts: webserver
- webserver

- name: Apply database server configuration
hosts: database
- database

By doing so, we are sure that the webserver tasks will be runned only on the webservers and the database tasks only on the database servers.

Now we need to write the last one, the database main.yml.
It should look like this:

- name: Add APT GPG signing key
apt_key: url= state=present

- name: Add APT repository
apt_repository: repo='deb $ansible_distribution_release main' state=present update_cache=yes

- name: Install MariaDB
apt: name=mariadb-server state=present

- name: Start Mysql Service
service: name=mysql state=started enabled=true

- name: Install python Mysql package #required for mysql_db tasks
apt: name=python-mysqldb state=present

- name: Create a new database
mysql_db: name=demo state=present collation=utf8_general_ci

- name: Create a database user
mysql_user: name=demo password=demo priv=*.*:ALL host=localhost state=present

- name: Copy sample data
copy: src=dump.sql dest=/tmp/dump.sql

- name: Insert sample data
shell: cat /tmp/dump.sql | mysql -u demo -p demo

- name: Install MySQL extension for PHP
apt: name=php5-mysql state=present

The above task will install and configure our database.
We add a simple db.php file with the connection string and a simple query to get the database data:

$connection = new PDO('mysql:host=localhost;dbname=demo', 'demo', 'demo');
$statement  = $connection->query('SELECT message FROM demo');
echo $statement->fetchColumn();

Also, to have the data stored in the first place in the database, we can set up a simple dump.sql file:

  message varchar(255) NOT NULL
INSERT INTO demo (message) VALUES('Hello World!');

After we have all the files ready, you run again the playbook:

$ ansible-playbook -i hosts playbook.yml -u root

This again will start up a web server, showing a Hello World page, but this time, the web server is using a database to fetch the data.


Ansible is really easy and simple to set up and use. The YAML syntax is simple and easy to understand with a wide documentation and examples. The more structured your projects will be, the more easier to understand and less complex they will be. Ansible can be used to handle small task, or large automation processes, even orchestration.

Leave a Reply

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

Scroll to top