Monday, June 11, 2018

Introduction to Ansible and writing your first playbook

Well it's been way too long since I've written in this blog, so I thought I'd put out a quick how-to on getting started with Ansible.

Ansible is an automation tool for configuration management, similar to Puppet which I wrote about in my previous post.

It's written in python, which means whitespace is very important, which in turn means if you indent things wrong, you'll get errors that may not help you pinpoint the problem. But the main advantage of Ansible, over other similar tools like Puppet, is that it doesn't require a daemon to run. In fact all it requires is an ssh connection.

So let's get started. The ansible package only needs to be installed on the machine you plan to run it on. Beyond that, as long as you have ssh access to the rest of your servers, you can start automating. You don't even need a dedicated account to run ansible under(you can run it from your own user account if it has sufficient access on the remote machines), but it's a good idea to set one up.

In my setup, I used shared keys to make it easier to connect to the rest of the servers, and an ansible account with a passwordless sudo setup. Yes that's not the best security wise, but for an example it's good enough.

This means adding a single line in /etc/sudoers(or in a new file in /etc/sudoers.d if you prefer):

 ansible ALL=(ALL) NOPASSWD:ALL

Next important decision you need to make is where you want to store your playbooks. I went with /etc/ansible/playbooks, because /etc/ansible already exists in a default setup.

But before we get to actually writing a playbook, let's start with setting up our hosts. This is done in /etc/ansible/hosts, where there are already some examples. Basically you can define both hosts and then  groups of hosts. A group is defined like this:


[ansibletestservers]
lab-ansible-test-01
lab-ansible-test-02
 

The first line is the group name, the other two are servers that are in DNS. Or if they're not, you can use IP addresses. The first host in my case is actually the host I have running ansible on, but that doesn't have to be the case


Once you have that, you can write a basic playbook to push out a file. This looks something like this:


 ---
- hosts: ansibletestservers
  become: yes
  gather_facts: false
 
  tasks:
  - name: Copy a new "ntp.conf file into place, backing up the original if it differs from the copied version"
    copy:
      src: ntp.conf.ansible
      dest: /etc/ntp.conf
      owner: root
      group: root
      mode: 0644
      backup: yes

Save the above with a .yml extension, let's say ntp.yml and you're ready to run it. The above directives are essentially self-explanatory, except maybe for "become" which is a directive to tell it to sudo to root before running. "Gather_facts" it would do by default, which is basically to run an inventory of the hardware before it executed, so unless you're specifically trying to do that, it's best to set it to "false". The source file itself can be stored in the same directory.

So let's run it finally, and see what happens. Since I created the ansible accounts, I use that to run my playbooks. So I sudo to root, then su to ansible, then do:

  ansible-playbook /etc/ansible/playbooks/ntp.yml

You should see something like:


PLAY ***************************************************************************

TASK [Copy a new "ntp.conf file into place, backing up the original if it differs from the copied version"] ***
ok: [lab-ansible-test-02]
changed: [lab-ansible-test-01]

PLAY RECAP *********************************************************************
lab-ansible-test-01        : ok=1    changed=1    unreachable=0    failed=0  

lab-ansible-test-02        : ok=1    changed=1    unreachable=0    failed=0

If you don't see that, then check that your ansible account can ssh to the ansible user on all the machines you want to run it on. Also check after that, that it can sudo to root without a password. If that all works, but your playbook still doesn't, check the permissions on the files.

There's a lot more interesting things you can do with Ansible. I'll do some more advanced examples in my next post.