Learning to Deploy Servers with Ansible

provisions

I’ve been wanting to learn how to use a configuration management tool for a long time. In the past I’ve attempted to learn Chef though I found myself getting lost amidst the domain language. Trying to use these tools made me feel extremely stupid simply because I was having a hard enough time grasping the concepts of the system.

A couple of weeks ago during our Dev Show and Tells, Nate Smith showed off Ansible. Ansible a configuration management tool but it’s goals are to be easier to use and understand. It’s written in python and uses YAML files for defining your provisioning tasks, called Playbooks in Ansible.

Before we can start using a Playbook we need to do a tiny bit of setup first. You’ll need to define your Server Inventory which is required before Ansible can go out and provision your servers for you.

# hosts
[webservers]
web1.example.com

[databases]
db2.example.com

Now let’s verify that our host configuration is correct:

/Users/csaunders/development/ansible [csaunders@outerhaven] [23:09]
> ansible all -i hosts -m ping
web1.example.com | success >> {
    "changed": false,
    "ping": "pong"
}

db1.example.com | success >> {
    "changed": false,
    "ping": "pong"
}

Now that we know that we are able to connect to our servers, let’s build a Playbook. A Playbook is simply a definition as to what kinds of tasks you’ll be running to setup the server. The simplest playbook you could have would be one where you install apache2 on a bunch of servers:

---
# Here we define the hosts we are going to run them on
- hosts: all
  user: root
  tasks:
    - name: Install Apache with php
      apt: pkg=apache2 state=present
    - name: Install mod PHP on Apache
      apt: pkg=libapache2-mod-php5 state=present
    - name: Install PHP
      apt: pkg=php5 state=present
    - name: Install the PHP MySQL Bindings
      apt: pkg=php5-mysql state=present
    - name: Restart Apache2
      service: name=apache2 state=restarted

What I really like about this is it’s very easy to understand what is going on. We have a little description that describes what the task is and the command that will be run. The name of the task will also be echoed into the terminal when you run the playbook so you have an idea of what task to look at if something goes wrong. And while you might be thinking that the above is pretty verbose, Ansible also provides the tools such that you can run the same command on a list of things. So you can shorten the above example into a single command.

- hosts: all
  user: root
  tasks:
    - name: Install Apache2 and the necessary PHP modules
      apt: pkg={{ item }} state=present
      with_items:
        - apache2
        - libapache2-mod-php5
        - php5
        - php5-mysql
    - name: Restart Apache2
      service: name=apache2 state=restarted

Often we want to be able to re-use a bunch of the code we write because many different kinds of servers use many of the same things. This is where we can define Roles which we can assign to various hosts or groups of hosts. A Role consists of a number of things though the major components are the tasks to run, templates to use and handlers that fire after a task.

Now with a few roles defined you can create Playbooks that leverage them:

---
- hosts: webservers
  user: ansible
  sudo: yes

  roles:
    - common
    - mysql
    - apache2

All the tasks contained in each role will be executed, and if all goes well you will have a server that’s ready to serve up some MySQL powered sites!

So far I have to say that I’m quite happy with Ansible. I’ve been meaning to migrate my systems around because they were somewhat out of date and I wanted to bring some costs down. The idea of doing it all manually was a massive deterrent from doing it whatsoever simply because of all the work that’s involved. While it might have taken me more time to get what I needed to do in Ansible; I know that if I ever need to do something like upgrade WordPress, it just requires changing a configuration value and running a command. It also makes it a lot easier for me to do things like change providers if I ever wanted. Learning to use this tool has also laid a base from which I can build upon. The process for creating a configuration to prepare a server for a Go or Ruby app should be far simpler! If you are looking to level up your dev ops knowledge, then I’d definitely consider looking into Ansible as a way to do that.


No responses yet

Leave a Reply