My new helper Ansible

Ansible Logo
Image source: wikipedia.org

For some weeks ago, I decided to use Ansible as my central configuration tool of choice. The following text should give you a short intro in how to deploy files with Ansible.

What exactly is Ansible?

Now, what exactly is Ansible? Ansible is an auto configuration tool, which helps you to keep your configuration files central managed. You will benefit from easier configuration and you will save a lot of time. For example, if you have 3 DNS servers and you want to ensure that all this systems have the same db and configuration files used, you could use either a network storage (which is obviously something over the top here) or keep them central and push them to all DNS servers.

And Ansible is exactly doing that. It pushes your configuration files on given hosts. Another really pro for Ansible is, that it uses SSH to do so. This means that you don’t have to install a service to get your machines configured. Ansible is agent-less.

How to install Ansible

For almost every distribution out there in the wild, Ansible is available in the system repositories. For Ubuntu / Debian you can easily do:

sudo apt-get install ansible

as well as for openSUSE you can just do:

sudo zypper install ansible

After this, you can find the standard Ansible configuration under /etc/ansible.

Make SSH ready for Ansible

Every host which will be managed via Ansible needs to have a Public Key and a user which is allowed to use this Public Key to connect to the Host.

For my personal purposes I created a user which is allowed to change the files which are coming from Ansible. This is of course optional. You could also do this with the user root even if that means a little bit more of a security risk. Anyway, you have to generate a Public Key which is done with the following command for the user ant:

ant@ansible:~$ ssh-keygen -t rsa -b 4096

For our scenario, you shouldn’t set a password for the key. The other questions can be confirmed with pressing ENTER without any changes. After this your SSH Key is ready and you can push them to your Host which will be configured with Ansible later. After the following command is issued, the user ant on your Ansible system will be able to login as user ant on the system target without entering a password. As described above, you could also do this with the user root here:

ant@ansible:~$ ssh-copy-id -i ~/.ssh/id_rsa.pub ant@target

Now you should be able to login via ssh as the user ant on the system target without entering a password.

Configure Ansible

Now that you have the target System fed with an Public Key, you are able to make the target System known in Ansible. The Ansible configuration files are located at /etc/ansible. First of all you should add the target system in the /etc/ansible/hosts file:

[testsystems]
target.local.dom

Let me explain this file a little bit. You could enter a hostname per line in this file. Ansible then knows them and will deploy the given files. To make it much easier configuration wise and for the human eye to read it, there are groups available. A group start with [ and ends with ]. So in this case the host target.local.dom would be in the group testsystems. It is possible to get one host into multiple groups.

So now the host is known for Ansible. As next we need to define the files which will be pushed and where their going to be deployed at the root filesystem of the target host.
For this, Ansible is using so called Playbooks. As its name implies, the Playbook is a collection of things which has to be done on the target system. You can do almost everything here which you also would be able to do by hand in the console. There a plenty of modules which can be used for e.g. Update your system, set file permission, and so on. And even if there is no module available which fits your needs, you can always use the bash module and write down what the system should do by yourself. A complete list of the modules and how to use them can be found at the official documentation of Ansible. In this example we will push files to the target system. So we have to define this in the Playbook. You can either use the copy or the synchronize function within the file module to push the wanted files to the target. The following example will use the synchronize function:

---
- hosts: testsystems
vars:
files: /etc/ansible/files/testsystems/
gather_facts: false
become: false

tasks:
- name: copy files
synchronize: src={{ files }} dest=/opt
notify: restart ssh

handlers:
- include: handlers.yml

So what does this Playbook do now? Let me explain this file step by step:

  • hosts: Here we insert the group(s) which has been declared in the /etc/ansible/hosts file. You can name here single hosts as well as groups. It’s always recommended to use groups here.
  • vars: In vars we can declare variables which are used within this Playbook configuration. There is actually one variable defined which is called files. This variable is used later in the tasks section.
  • gather_facts: This is true or false. The standard is true. gather_facts is collecting informations about your system which can be used within the modules. Here it is disabled because we know that this Playbook will running well with the settings we give Ansible.
  • become: In earlier versions of Ansible this was called sudo. Become decides wether this Playbook needs root /sudo privileges to run, or not. The way how the system will become the root is defined in the central ansible.cfg. If set to true, you have to ensure that the “become user”, is available on the target system and has sudo permissions.
  • tasks: In tasks we define what to do on the target system. In this case we have one task, which is named “copy files”. It uses synchronize which is provided by the file module. The source path is the path which is defined in the variable files at the beginning of the Playbook-file. The Destination is the absolute path on the target system. In this case “/opt”. At the end, we use a notifier. This notifier is calling “restart ssh” if a file has really changed on the target system. “restart ssh” is written down in the “handlers.yml” file. This file has to be in the same directory as this Playbook.

This is a really short and easy example of the capabilitys of Ansible. As I said earlier, you can do a lot of more stuff. For this you should consider to read the official documentation of Ansible.

You can now save the file where ever you want. I recommend a place like /etc/ansible/conf.d. The filename ending should be .yml. So for e.g. we could save the file “testservers.yml” under /etc/ansible/conf.d.

The handlers.yml file

As mentioned before, the handlers.yml file is just an addition to your existing Playbook. In the handlers file you can write down commands which can be reused a lot of more times. For example the “restart ssh” command, which has been called in our Playbook, can be also needed by other upcoming hosts. To prevent for writing down the same commands again and again, we use an external extra file, which holds all the reusable commands. This file is here called handlers.yml and has to be stored in the same directory as your Playbooks. An example handlers file looks like this:

---
- name: restart bind
service: name=named state=restarted

- name: restart ssh
service: name=ssh state=restarted

So as you can see, we use the module service to restart the services ssh and bind. The services are restarted on the target system, when they get called in a Playbook. In our Playbook-example above, the “restart ssh” command is triggered after copying files.

Testing our new configuration

We have a valid hosts and Playbook file and our target system has the needed Public Key. So we should be ready to go. To start or “call” a Playbook you have to issue the following command on your command line:

ant@ansible:~$ ansible-playbook /etc/ansible/conf.d/testservers.yml

NOTE: Don’t forget, that you have to issue the command on your Ansible system, with the user which has the Public Key stored on the target system.
Now your Ansible server system should start pushing the data to the target system. A output like this should be shown to you:

PLAY [testservers] ************************************************************

TASK: [copy files] **************************************************
changed: [target.dom.local -> 127.0.0.1]

NOTIFIED: [restart ssh] ******************************************************
changed: [target.dom.local]

PLAY RECAP ********************************************************************
target.dom.local : ok=2 changed=0 unreachable=0 failed=0

This means the files are successfully copied and the ssh service was restarted. This means your first Ansible Playbook is running fine without issues. Now you can go on in adding more tasks.
Don’t for get the official documentation to do so 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s