Continuous Delivery

Un caso de estudio

#nerdearla

Buenos Aires, 2015

aka

Technical Learnings of Continuous Delivery for Make Benefit Glorious Nation of Sysadmins

whoami

oficio: sysadmin

IRC: osvaldo at freenode #sysarmy

it all started with a ...

  • Codigo:
    • Trunk. Codigo en desarrollo
    • Branch. Versiones de Release (3.10,3.11,3.12,..)
    • Tag. Fixes, bugs, etc. (3.10.1,3.10.2 .., 3.10.18, 3.11.0,..)
  • 3 Ambientes:
    • DEV. Próximo release
    • QA. Release en produción
    • PROD. 

como era el desarrollo

codigo + deploy steps 

  • crear carpetas
  • ejecutar sql
  • deployar configuracion
  • rollback steps

Documentation:

JIRA Issues - code commits with jira_id on subject

tareas:

como era el deployment

Lunes: Code freeze

Miércoles: Deploy a producción

Cada 15 dias

08:00 Arrancaba el deploy

...

terminaba cuando terminaba

como eran los releases

Releases

Problemas?

  • Feriados
  • Rollbacks
  • Tiempo de implementación para nuevas funcionalidad

empecemos por el principio

follow the money

(en nuestro caso:)

follow the code

 

 

flujo de codigo

Developers -> commit code in SVN

 

Release Team -> Push/Tag Code -> Deploy Code

Coordinación via: IRC 

Problemas

  • Dependencia en el Release Team
  • Proceso manual

flujo de codigo

¿Qué hacer?

Departamento de Infrastructura

Release Team

  • Continuous Delivery

  • Continuous Integration

  • Continuous Deployment

Continuous Delivery

Estas haciendo continuous delivery cuando: 

  • Tu código es deployable a lo largo de su ciclo de vida.
  • Tu equipo prioriza mantener el código deployable por encima de trabajar en nuevas funcionalides.
  • Cualquiera puede obtener feedback instántaneo y automatizado de la disponibilidad para salir a producción de sus sistemas siempre que alguien haga un cambio sobre ellos.
  • Puedes deployar cualquier versión del software a cualquier ambiente en cualquier momento con solo apretar un botón.

Continuous Delivery

Para lograr continuous delivery usted necesita:

  • una relación de trabajo muy cercana y colaborativa entre todos los involucrados en el deployment (también conocido como "cultura DevOps".
  • la mas completa automatización de todos los elementos que componen el proceso de delivery, usualmente conocido como DeploymentPipeline.

Continuous Delivery se confunde a menudo con Continuous Deployment.

 

Continuous Deployment significa que cada cambio entra en el pipeline y automáticamente llega a producción, resultando muchos deployments a producción a diario.

Continuous Delivery solo significa que tienes la capacidad para hacer deploys frecuentes pero puedes elegir no hacerlos.

Continuous Integration se refiere por lo general a la capacidad de integrar, buildear y testear el código dentro de un ambiente de desarrollo.

 

  • Unit Testing
  • Automated Acceptance Tests
  • User Acceptance Tests

¿Por donde empezamos?

show me the code

aka

Source Code Versioning

Git

Ventajas

  • Branches
  • mejor interface web (github/gitlab)
  • repositorios distribuidos (oficinas distribuidas)
  • interface svn (facilita la migración)

problema adicional con SVN

oficinas distribuidas geograficamente

solucion:

  • comenzar migración a git
  • separar componentes
  • separar configuración del código
  • reescribir deployment scripts. separación del código y los datos de configuración

objetivos

Etapa 1

  • un grupo de proyectos empezo a utilizar git/github.
  • se logró separar en componentes funcionalidad de la aplicación (frontend mostly).
  • se paso la configuración a repositorios git (git-crypt).
  • se armó el pipeline de un componente desde el commit de codigo comenzando por testing hasta staging incluyendo unit testing, smoke tests y  automated acceptance tests.
  • nuevo set de scripts de deployments (bash). 

logros

primer pipeline: la prueba de concepto fue un exito

Etapa 1

  • disparar el deploy del componente automaticamente al comitear nuevo codigo (github webhooks + jenkins git plugin)
  • empaquetar los componentes
    • deployar paquetes -no source code- en ambientes
    • artifactory 
  • deployar paquetes automáticamente en ambientes de desarrollo: testing y staging
  • un solo set de scripts (bash) de deploy para todos los ambientes. configuracion de ambientes mediante includes

objetivos

Etapa 2

logros

Etapa 2

  • automatizar deploy de servidores de CI (aka jenkins)
  • infrastructura como código
  • utilizar paquetes nativos
  • utilizar ansible en vez de bash
  • desarrolladores con el boton para deployar en producción

objetivos

Etapa 3

  • deploys directo a producción
  • config flags: paquetes con la configuración de funcionalidades de la aplicación
  • tres paquetes por componente:
    • codigo (aplicación)
    • conf (configuración ambiente)
    • flags (funcionalidad aplicación)
  • pipeline de nuevo componente en un dia (hasta prod!)

logros

Etapa 3

  • Smoke tests
  • UAT (gnu parallel para acelerar casperjs)
  • Canary deployments
  • Blue/Green deployments
  • focused A/B testing (optimizely.com)

facilitando los deploys

Lecciones

  • Convention over configuration
  • treat servers like cattle not pets
  • automate everything
  • infrastructure as code
  • use dev/qa environments
  • have meaninful dev/qa environments
  • empower developers - with great power came great responsabilities 
  • blameless postmortems

Herramientas

logging

  • splunk
  • elk (logstash+kibana)

metricas

  • graphite
  • newrelic

repositories

  • artifactory
  • aptly

monitoreo

  • nagios
  • pagerduty

source code versioning

  • github

automatizacion

  • ansible / bash

server CI

  • jenkins

Chatops

  • IRC
  • hipchat
  • slack
  • lets-chat

Bots

  • hubot

Integracion

  • jenkins
  • gitlab/github
  • bash/curl

 

# check artifacts - Check artifacts versions in environment (available and deployed)
exec = require('child_process').exec;
module.exports = (robot)->
  robot.respond /check (.*)/i, (msg) ->
    env = msg.match[1]
    switch env
      when "prod"
        #server = "repos2-mng"
        server = "online-main-nms"
        script="ssh "+server+" /usr/local/acme/bin/check-artifacts-servers.sh"
      else
        #server = "testing-repos2"
        server = "staging-nms"
        env = "stage"
        script="ssh "+server+" /usr/local/acme/bin/check-artifacts-servers.sh"
    console.log(script)
    child = exec script, (error,stdout,stderr) ->
      msg.send "artifacts in "+env+"\n" + stdout + "\n" + stderr

CODE for hubot check prod

web panel

  • ansible
  • fpm
  • aptly

arquitectura modular

  • input
  • output

multi-ambiente

paquetes nativos

infrastructure as code: xcdc

Tips

  • vagrant (providers: lxc, vmware, azure)
  • vagrant plugins (hosts manager, package cache)
  • git push update (definir dos remotes, read-only via ssh, read-write via https, bonus: git credentials cache)
  • use rest. /api/ (slim framework, flask)
  • jenkins
    • nodes (using different remote user)
    • backup scripts (backup jenkins´ configuration in git)

Document everything

  • static blog tools
    • jekyll
    • octopress
    • hugo
    • pelycan
  • wysiwyg
    • ghost
  • static sites
    • mkdocs
    • gitbook
  • apidocjs.com

use markdown

gists

Gracias!

Continuous Delivery: A case study

By osvaldo

Continuous Delivery: A case study

  • 673