Deployments with Ansible



Deploying application code to servers is one of the hardest, but most rewarding, tasks of any
development team. Most shops using traditional deployment techniques (manual steps, shell scripts,
and prayers) dread deployments, especially for complex, monolithic apps.

Deployments are less daunting when you adopt modern deployment processes and use the right
amount of automation. In the best case, deployments become so boring and routine they barely
register as a blip on your team’s radar.

Consider Etsy, a company whose engineers are deploying code to production up to 40 times per
day¹¹³, with no manual intervention from the operations team. The operations team is free to work
on more creative endeavors, and the developers see their code go live in near-real-time!
Etsy’s production deployment schedule is enabled by a strong DevOps-oriented culture (with robust
code repository management, continuous integration, well-tested code, feature flags, etc.). While it
may not be immediately possible to start deploying your application to production 20 times a day,
you can move a long way towards effortless deployments by automating deployments with Ansible.

Deployment strategies

There are dozens of ways to deploy code to servers. For the most basic applications, you may only
need to switch to a new tag in a code repository on the server and restarting a service.
For more complex applications, you might do a full Blue-Green deployment, where you build an
entire new infrastructure alongside your current production infrastructure, run tests on the new
infrastructure, then automatically cut over to the new instances. This may be overkill for many
applications (especially if <100% uptime is acceptable), but it is becoming more and more common—
and Ansible automates the entire process.

In this chapter, we will be covering the following deployment strategies:
1. Single-server deployments.
2. Zero-downtime multi-server deployments.
3. Capistrano-style and blue-green deployments.

These are three of the most common deployment techniques, and they cover many common use
cases. There are other ways to strengthen your deployment processes, often involving the application
level and organizational change, but those deployment aspects are out of the scope of this book. 

Simple single-server deployments

The vast majority of small applications and websites are easily run on a single virtual machine or
dedicated server. Using Ansible to provision and manage the configuration on the server is a no
brainer. Even though you only have to manage one server, it’s better to encapsulate all the setup so
you don’t end up with a snowflake server.
In this instance, we are managing a Ruby on Rails site that allows users to perform CRUD operations
on articles (database records with a title and body).
The code repository for this app is located on GitHub at https://github.com/geerlingguy/demo
rails-app.
Begin by creating a new Vagrant VM for local testing using the following Vagrantfile:

1 # -*- mode: ruby -*-
2 # vi: set ft=ruby :
3
4 Vagrant.configure(2) do |config|
5 config.vm.box = "geerlingguy/ubuntu1404"
6
7 config.vm.provider "virtualbox" do |v|
8 v.name = "rails-demo"
9 v.memory = 1024
10 v.cpus = 2
11 end
12
13 config.vm.hostname = "rails-demo"
14 config.vm.network :private_network, ip: "192.168.33.7"
15
16 config.vm.provision "ansible" do |ansible|
17 ansible.playbook = "playbooks/main.yml"
18 ansible.sudo = true
19 end
20
21 end

In this case, we have a VM at the IP address 192.168.33.7. When provisioned, it will run the Ansible
playbook defined in playbooks/main.yml on the VM. 



Comments