Automated Deployments with Ansible and Fabric

Center for Open Science March 2014


Matt Makai | @mattmakai | makaimc on GitHub | Twilio Developer Evangelist

Back in the day...

My first sys admin

Picture reference

#!/bin/bash

What starts as this...

Original script reference

...usually ends like this

Original picture reference

Fabric

Fabric Scripting

Gist

Deployments

Deployment Tasks

  • Configure servers
  • Set up [Python] environment
  • Deploy code
  • Migrate database schema & data
  • Perform ad hoc tasks

What is Ansible?

  • Multinode orchestration framework
  • Configuration management
  • Application deployment
  • Ad hoc tasks

Ansible technology

  • YAML syntax
  • Jinja2 templates
  • SSH (no remote agents)
  • Ansible module library
  • Django manage.py commands module

Modules

user module

Ad hoc commands



$ ansible webservers -m user -a   \
  "name=cville state=present     \
  uid=1040 group=meetup" -u deployer

                    

Playbooks



- name: ensure user "cville" exists
  user: name=cville state=present 
        uid=1040 group=meetup

                    

Playbook on GitHub

https://github.com/makaimc/sf-django

Organization

deploy
  |---- deploy.yml
  |---- hosts
  |---- group_vars/
          |---- all
          |---- dbservers
          |---- webservers
  |---- roles/
          |---- all
          |---- db
              |---- handlers
              |---- tasks
              |---- templates
          |---- web
                    

Variables

  • Letters, numbers, underscores are valid names
  • Always start with a letter
  • Valid: port_number
  • {{ ansible_env }} pulls from environment
  • Precedence rules exist

Roles

  • Allow multinode orchestration
  • Define behavior for server type
  • Enable reuse and organization

Deployment Tasks

  • Configure servers
  • Set up [Python] environment
  • Deploy code
  • Migrate database schema & data
  • Perform ad hoc tasks

Configure servers

Configure servers

- name: install latest version of Apache
  yum: name=httpd state=latest

- name: check if apache conf.d dir exists
  stat: path=/etc/httpd/conf.d/
  register: apache_dir

- debug: msg="conf.d exists and is dir"
  when: apache_dir.stat.isdir is defined 
        and apache_dir.stat.isdir
                    

Set up environment

Set up environment

- name: check if virtualenv already exists
  stat: path={{virtualenv_dir}}
  register: venv_dir

- name: create virtualenv for Django web app
  shell: virtualenv {{virtualenv_dir}}
  when: venv_dir.stat.isdir is not defined

- name: install web application dependencies
  pip: requirements={{app_dir}}/reqs.txt
       virtualenv={{virtualenv_dir}}
                    

Deploy code

Deploy code

- name: install known_hosts file for GitHub
  copy: src={{ ssh_dir }}/known_hosts 
        dest=/home/{{ deploy_user }}/.ssh

- name: checkout latest web app code
  git: repo={{code_repo}} dest={{app_dir}}
                    

Migrate DB schema & data

Migrate DB schema & data

- name: Django syncdb
  django_manage: command=syncdb
                 app_path={{app_code_dir}}
                 virtualenv={{venv_dir}}
  environment: django_env_vars


- name: Django migrate
  django_manage: command=migrate
                 app_path={{app_code_dir}}
                 virtualenv={{venv_dir}}
  environment: django_env_vars
  when: django_use_south
                    

Perform ad hoc tasks

Perform ad hoc tasks

# playbook
- name: Django collectstatic
  django_manage: command=collectstatic 
                 app_path={{app_code_dir}}
                 virtualenv={{venv_dir}}
  environment: django_env_vars

# command line
$ ansible-playbook django-stack.yml --step \
  --start-at-task="Django collectstatic"   \
  -u deployer -K
                    

Ansible downsides

  • No Windows support
  • Lack of testing tools
  • Reuse ambiguity

Django deployment dream

  • pip install deploy-tool
  • INSTALLED_APPS += 'deploy_tool'
  • vim deploy-params.yml
  • python manage.py deploy

Underwear

Underwear

  • pip install underwear
  • INSTALLED_APPS += 'underwear'
  • wget underwear.yml
  • wget hosts
  • vim deploy/underwear.yml
  • vim deploy/hosts
  • python manage.py deploy

Underwear Repository

https://github.com/makaimc/underwear

Resources

Contact Information