close up photo of programming of codes

Playing with Ansible – making deployments predictable

I had heard about Ansible several years ago but never got a chance to work with it. The idea around automating your IT really resonated with me.
Over the course of several years I have setup several dozens of servers. Everytime I have to scratch my head and think about all the steps.
I started creating a document containing all the commands, even with that you run into special cases due to different versions of the tools, some new quirks etc. Failing to document the special cases would mean going through some of the misery of finding the fix again.

Ansible Overview

Ansible solves this problem by using a concept of playbooks. A playbook is a YAML (devops is never complete without it) file that contains the lists of tasks that you want to perform on a remote machine.

It doesn’t need to be a single remote machine; you can have several machines, and organize them into groups too just in case you have some special needs for each of the groups.

A task is the specific action that you want to take – for example you might want to install an apt package before continuing, or would want to checkout a git repository in a certain location.

A question that comes to mind is, why would you use something like this? You can do this by using good old bash scripting. If you do then you again need to deal with all the nuances of the underlying machine manually and include that in your bash script.

Instead, Ansible provides you with many built-in or community built modules. A module is a utility that helps you perform actions around a utility/tool, while abstracting the underlying detail and allowing us to do it in a declarative way.
E.g. Run a command inside a container named ‘my-certbot’

- name: Remove the dummy certificate before requesting new one
  community.docker.docker_container_exec:
    container: my-certbot
    command: rm -rf /etc/letsencrypt/live/{{ server_name }}
  register: result

- name: Print stdout
  debug:
    var: result

To me something simple like above would require some work in a bash script, especially to make it generic with variables like {{ server_name }}. A good example are these two gists that do the same thing but one with bash and another with Anisible.

There are a good deal of these modules available and you can find many recipes(playbooks) to do some of the most common taks.

Learning Ansible

For not so advanced things(like what I did) I think if you pick up a couple of tutorials on Youtube or a few blogs you can be up and running.
For individal modules you can find examples in the docs,for example you can find how to use the docker_container module here.

It is also quite simple to practice as well, based on how comfortable you get with understanding its working. There are 3 ways to practice:

  1. Local.
    Doing it locally on your own machine has the advantage of being really fast, doesn’t need any additional setup and easy to verify results. The biggest downside is that you might end up doing something on your local machine that you don’t want to do.
  2. VM inside VirtualBox.
    This one is reasonably fast and it doesn’t have the downside of accidentally messing up your machine. I usually create a base image and then can run any task worry free. Downside is of course you will need to set up VBox and a Guest OS if you don’t already have it.
  3. Throwaway VM on a service like Digital Ocean.
    This one gives you the taste of the real deal and also helpful when you want to do something which needs the machine to be accessible on the internet. For example, I wanted to set up LetsEncrypt certificate on the server, for which I needed a server accessible on the internet. Downsides can be a few dollars in cost and a little bit of network latency.

A Sample Playbook

I put together a bunch of tasks that

  1. Setup a user and create a group for docker
  2. Setup docker
  3. Checkout a git repository- containing wordpress code
  4. Do some changes in the code
  5. Setup LetsEncrypt certificate
  6. Fires the container

The code can be found in https://github.com/codisfy/code_snips/tree/master/ansible

Thoughts

It took me atleast 3 times more time to run and set up the server while using Ansible, but I still believe it was worth it. Worth, because I see myself reusing a lot of these tasks readily when I am about to setup another machine.

Also while going through this whole learning ordeal it made me much more familiar about where to look for things in the documentation and pick up some of the concepts that will make me go faster the next time.

There are still more things like roles and handlers etc. that I haven’t explored yet, but I think I will start looking into those as I use Ansible more.

Leave a Reply

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