Ansible Tutorial – Creating a Simple Ansible Playbook

Following on from my previous post on installing and configuring Ansible, I wanted to do a quick follow up with a few more examples to show what Ansible can do. Ultimately, my aim is to get to doing some posts around using Ansible with AWS and vSphere, however for the purposes of this post I’ll be using Ansible to configure a Centos target machine. At the end of my last post, I was at the point where Ansible was installed, and I’d successfully ran a ‘ping’ to confirm that my Ansible machine could communicate with the linux target machine. The command I ran to test this specified the target to run against and the module, ping in this case, to run:

# ansible all -i 192.168.144.138, -m ping

Ansible Tutorial

In this post I want to get into using inventory files, and playbooks, which will show how powerful Ansible can be as an automation tool by using a few simple examples. To start with I’ll create a new host file, which lists and groups the hosts that I’ll be using Ansible to interact with and configure. Note that in the command shown above, I specified the IP address of the target system. Whilst this works fine if running against a single target system, it clearly doesn’t scale well. Instead of specifying the targets IPs or hostnames each time, we can use an Ansible host file.

Ansible Inventory Files

There is a default Ansible host file which can by found in /etc/ansible (along with the default anisible conf file, and default roles). This will be used if a hosts file isn’t present in the working directory. If Ansible sees a hosts file in the directory from where you are working it will use that instead of the default one. More info on Ansible hosts files here. So what does a simple hosts file look like?

[local]
localhost
[webfarm]
172.17.0.3
172.17.0.4
[webserver]
172.17.0.3

There are groups (for example Webfarm), which contain one or more hosts listed beneath, by IP address in the example above, though hostnames can also be used. This means that instead of specifying an IP address when running an Ansible command, we can ask it to run against a host group. Going back to the ‘ping’ example at the beginning of this post, we can run the same thing, this time against the multiple hosts defined in the [webfarm] group:

[root@7d2fcc1d3938 ansiblefiles]# ansible webfarm -m ping
172.17.0.4 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
172.17.0.3 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

Running the Ansible ping module against [webfarm] has resulted in the command being executed against both targets. Using host files allows us to scale running Ansible against many targets with a single command. For example, if we wanted to install Apache on all the web farm hosts, one way of doing so would be to use the ‘shell’ module against the [webfarm] group to issue the command to install the package using yum.

# ansible web -m shell -a 'yum install httpd -y'

Similarly we can check to see if a package is installed by running:

[root@7d2fcc1d3938 ansiblefiles]# ansible webfarm -m shell -a 'yum list installed | grep httpd'
172.17.0.3 | SUCCESS | rc=0 >>
httpd.x86_64                     2.2.15-60.el6.centos.6             @updates    
httpd-tools.x86_64               2.2.15-60.el6.centos.6             @updates    

172.17.0.4 | SUCCESS | rc=0 >>
httpd.x86_64                     2.2.15-60.el6.centos.6             @updates    
httpd-tools.x86_64               2.2.15-60.el6.centos.6             @updates    

As you can see the shell module allows you to issue shell commands against multiple targets very easily. However, done this way, we would have to run multiple Ansible commands if we wanted to install more than one software package. This is where playbooks come in. But before I move onto those, I should say that the recommended way to use Yum via Ansible is to use the yum module rather than call it via the shell. The syntax used when using the yum module is worth having a look at now as it is used in a similar way when putting playbooks together. So, to install PHP on the target system using the yum module rather than the shell, we can run:

# ansible webfarm -m yum -a 'name=httpd state=installed'

Note that ‘-m’ precedes the module name, and ‘-a’ precedes the arguments to be passed. You can find out what arguments can be used for a module by using the ansible-doc command.

# ansible-doc yum

You can also list all the modules available by running:

# ansible-doc -l

Ansible Playbooks

To finish off this post, I wanted to have a quick look at playbooks. Running Ansible commands works well, as shown above, but what if we want to run several different tasks against the same hosts? For example, if we wanted to install Apache and PHP? This is where playbooks come in. I’ll be using playbooks extensively in future posts around vSphere and AWS, but for now I’ll use a straight forward example to help give an idea of how they work.

To install Apache and PHP to my webfarm hosts I could run the following interactively:

# ansible webfarm -m yum -a 'name=httpd state=installed'
# ansible webfarm -m yum -a 'name=php state=installed'

We can achieve the same thing with a playbook that looks like this:

- hosts: webfarm
  tasks:
  - name: Install Apache and PHP
    yum: name=httpd,php state=installed

The syntax used in the playbook is very similar to what we used when running the commands interactively, and doesn’t need too much explanation. The hosts section references the ‘webfarm’ group from the hosts file, whilst the tasks section instructs the yum module to install httpd and php. For more information on the syntax here, check out this write up on YAML.
The playbook is run by using the ansible-playbook command:

# ansible-playbook apacheinstall.yml

That’s it for now, next time I’ll look at adding more functionality to the play book, using variables and handlers.

Related posts

Mastering the Linux ifconfig Command

Docker Exec Command With Practical Examples

Debugging with Git Bisect

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Read More