Deployments shouldn't be scary. 

Deployments should be doable anytime. 

Deployments should be easy enough that Delivery can do them. 
(but we won't let them >:)

3 Different Types of Deployments

  1. Application level deploys 
  2. Puppet deployments
  3.  Server deployments

Server Deployments

In an ideal world provisioning a new server should be as easy as
salt-cloud -p ubuntu_ngrid web1 web2 db1 db2 -P
Where the new server that gets spun up is in the right environment. It provisions itself from puppet
using the right manifest files, it loads itself into all the "right" places.

Puppet Deployments

  1. Static Analysis
  2. Module Testing
  3. Catalog Testing
  4. Dynamic Analysis
  5. Integration Testing 
  6. Nightly Rebuilds
  7. Deployment

Static Analysis

Syntax Testing



We are doing this.

Module Testing

Using fixtures to test individual modules. 

We are doing this sometimes.

Catalog Testing

Compile a catalog against a set of Factor facts

We are not doing this.

Dynamic Analysis

This verifies that configuration and installed applications 
are working. 

  • supervisor config
  • apache config

We are not doing this

Integration Testing

This is testing that services running on one machine are accessible via other machines. 

Web servers can access MySQL on the DB servers.

We are not doing this.

Nightly rebuilds

This verifies that at any time we can provision new servers and they're guaranteed to work.

ie Updated package repositories

We are not doing this.


Finally deploy the puppet code to puppet master

We are doing this.

Application Deployments

On the surface, doing an application deployment should be as simple as upgrading the twitter application 
on your phone. 

Deployment Parts

  1. Packaging/Versioning
  2. Continuous Integration
  3. Package Testing (API Testing)
  4. Integration Testing
  5. Deployment

PAckaging and Versioning

Our deployments should be deploying "packaged" apps. Whether it's a .deb, .rpm, .tar.gz, what ever.. 
Doing an Rsync across all servers is messy and complicated. 

Python - Localshop
Javascript - NPM Private Registry
Scala - Nexus

CONTINUOUS Integration

Using Jenkins or Travis we should be testing every commit to github. 

Number of tests -- HIGH
Testing is cheap - can be run locally, requires no virtualization

Package Testing

The package testing would test that the apps we have decied to include for each deployment work when isolated 
from the others (or included with others). 

Number of tests -- Medium Low - Low
Testing is more espensive - requires some virtualization, but not a fully provisioned server and minimal dependencies

Integration Testing

This is the testing the interactions between packages. 

Web-App < - > API

API < - > Play API

Number of tests -- Low
Testing is expensive - requires fully provisioned servers, with dependencies installed.


At any time code in "master/develop" should be deployable. 

That doesn't mean it should be deployed. But once the 
go sign from the product/delivery team has been given the code is already ready to go. 

Deployments should not be manual. They should be scripted.
(ie fabric)

Server Cycling

*Props to John Curry*

Using the LB we can construct rules to "hide" prod servers

Hidden servers get deployed to then smoke tested then unhidden

Visible servers get hidden, get deployed to, and prepared for next deploy


Rollbacks - Our database is SO big that backups/restores take a LONG time



By Nick Lang


  • 2,108