You are here

Learning DevOps: Automated setup and cloud VM provisioning with Ansible

public://pictures/Steven-Lowe-Principal-Consultant-Developer-ThoughtWorks.jpg
Steven A. Lowe, Product Technology Manager, Google

As a software developer, you’ve probably had to do your share—fair or otherwise—of systems administration tasks, which today are also sometimes referred to as DevOps tasks: installing operating systems, configuring servers and desktop machines, installing software packages and development tools, and so on. For some of us, sysadmin tasks are unenjoyable, tedious, and error-prone. Unfortunately, however, some level of sysadmin work is unavoidable. If you want to develop software, someone (usually you) has to set up the development machine at the very least.

The good news is, developers no longer have to do this kind of work manually. There are excellent open source tools that can automate a lot of these tedious tasks. I'm going to share a few examples from my experience using a configuration management tool called Ansible, which actually makes system setups enjoyable and led me down the path to DevOps. Ansible, and other tools like it, provide a declarative, idempotent approach to machine administration, which is enormously beneficial—and crucial—to the sane practice of DevOps. This is also known as treating infrastructure as code.

[ Get Report: The Forrester Wave: Continuous Delivery and Release Automation ]

Understanding configuration management tools

While writing scripts (typically shell scripts) to automate system setup tasks has been around for a long time, setup scripts are procedural and proscriptive—two things that continue to make the process tedious and error-prone. Wouldn’t it be great if you could just declare all the things you want to be on your machine using some simple syntax and then let a tool figure out the steps to install and configure it? Yes, yes it would.

Fortunately, there are several tools that can do this sort of thing now, one of which is Ansible. I'm not going to delve deep into the specifics of Ansible for this article, but you should read the Ansible documentation if you want to explore the tool further. The two most important characteristics of Ansible (and related tools, discussed later) are:

  • A simple, declarative syntax that describes the state you want to reach, rather than writing the steps required to reach that state 
  • Idempotence, which means that repeatedly running the same operation will yield the same end state

These two concepts are what make Ansible and other declarative configuration management tools so much more useful than mere scripts.

[ Get Report: Multicloud Monitoring: How to Ensure Success the First Time ]

Automating development configuration with Ansible

A while back I had to set up my laptop for development on a new team in a new environment with new tools, configurations, services, packages, and so on. I took this opportunity to automate the development configuration using Ansible, rather than just manually installing everything. I figured that at least once while I was on the project something would happen to my machine that would mess up the development configuration (in fact, something happened about once a month). When this occurred, I wanted to be able to simply delete everything and reinstall it rapidly instead of spending hours trying to fix the configuration. The initial Ansible playbook looked something like this:

- name: set up Mac dev tools

hosts: localhost

roles:

- homebrew

- git

- gradle

- npm

- grunt

- source-code 

This example uses Ansible roles, which are a convenient way to organize the playbook into reusable sections. Each role is defined in a separate directory and can support its own variables, tasks, and dependencies.

Running this playbook for the first time may install several things on your machine, while running it a second time may do nothing, as your machine is already in the desired state. This is an example of idempotence, which is the second critical concept of configuration management. 

Provisioning virtual machines

Ansible works on any machine, even cloud virtual machines. You can even use Ansible to create VMs and then provision them. For example, to create a Linux VM on Amazon EC2 you might use the following playbook: 

- name: Create ec2 vm instances

hosts: localhost

connection: local

gather_facts: False

vars:

how_many: 1

instance_type: c4.8xlarge

security_group: SecurityGroupIdGoesHere

image: ami-42908907

region: us-west-1

keypair: KeyPairName

groupname: crunchers

sudo: yes

tasks:

- name: create VMs

ec2:

key_name: "{{ keypair }}"

group_id: "{{ security_group }}"

instance_type: "{{ instance_type }}"

image: "{{ image }}"

wait: true

region: "{{ region }}"

exact_count: “{{ how_many }}”

count_tag:

Name: crunchy

instance_tags:

Name: crunchy

register: VMs

- name: add all instance public IPs to host group in memory

add_host: hostname={{ item.public_ip }} groups={{ groupname }}

with_items: VMs.instances

- name: Wait for SSH to come up

wait_for: host={{ item.public_dns_name }} port=22 delay=60 timeout=320 state=started

with_items: VMs.instances

This playbook will create one or more EC2 VMs and wait for them to boot up. Note the use of variables in this playbook so that you can easily change how many VMs to create, the underlying OS image, and so on.

The how_many variable determines the number of VMs that you want to produce. If you run this playbook twice, the first time it will create the VMs, and the second time it will count them and decide that it does not need to create any more VMs. That’s idempotence again. Once the VMs are created we can use a dynamic inventory module to access them, send them commands, shut them down, or remove them.

Other options for configuration management

With appropriate interface modules, you can use Ansible to create and manage networks of machines with varying levels of complexity, which is a crucial starting point for the technical side of DevOps—and all it takes to get started is a few lines of text in a YAML file.

Ansible is not the only player in the world of configuration management. In fact, it is not even the largest or most popular player, but it is extremely easy for beginners, and for me, it provided a shallow learning curve for configuration management.

Each tool has a slightly different attitude toward configuration management. Ansible, for example, talks to machines via a SSH connection, so it does not require an agent to run on the machines being provisioned. This makes it easy to get started experimenting but may make it inconvenient for larger environments, as SSH connections can be easily lost or closed (though there are ways to prevent this, of course).

As you gain confidence and excitement in configuration management and understand more of the possibilities, be sure to check out Chef, Puppet, and Salt. Each tool has its own strengths, weaknesses, and enthusiastic community. In some cases, you may want to use more than one.

Ansible is an easy way to dip your toes into the world of modern configuration management, which is a primary driver for the explosive growth of the DevOps movement. Once you’re hooked on the notion of infrastructure as code, you will never go back to finicky scripts or tedious manual setups! 

My recommended Ansible books:

Amazon.com: Ansible for DevOps: Server and configuration for humans

Ansible for DevOps

 

[ Webinar: IT Infrastructure in the Containers Era ]