Palestra: Desenvolvimento de builds automizados com Jenkins – Em Busca do build Perfeito!

No último dia 4 de abril estivemos no evento de comemoração dos 10 anos do GUMA-RS, apresentando uma palestra sobre Continuous Integration. Após a apresentação, fizemos um tutorial mostrando em funcionamento um pipeline do ciclo de desenvolvimento, desde o build até o deploy em produção, utilizando Jenkins. Desta forma levamos aos presentes algumas ideias do que pode ser feito em termos de automação e entrega contínua.

Abaixo segue os slides da apresentação. Os projetos que utilizamos estão no Github, aqui e aqui.

 

Anúncios

Automatizando tarefas repetitivas utilizando Jenkins

Pare para pensar. Em seu trabalho existem tarefas que se repetem com certa frequencia, e que você faz sempre a mesma coisa para resolvê-las? Você provavelmente gostaria de não fazer mais essas tarefas, assim teria tempo para fazer tarefas mais importantes que necessitam do seu raciocínio lógico, ou até mais tempo para o seu lazer, porque não?

A solução para este tipo de problema pode ser a automação dessas tarefas. Ao se criar scripts que automatizem o trabalho antes feito manualmente, vários benefícios são obtidos como abstração do funcionamento, já que qualquer desenvolvedor pode executar o script mesmo sem saber como ele funciona internamente, e qualidade, já que não são mais necessários passos manuais diminuindo a chance de erros.

E é neste ponto que entra o Jenkins. Jenkins é uma ferramenta de integração contínua que fornece uma interface amigável para criação de tarefas que podem ser executadas manualmente, através de um clique, ou ainda agendadas para rodar em determinados horários.

Vale ressaltar que o Jenkins somente executa os scripts criados, então o conhecimento em alguma linguagem de script ainda é necessário. O foco deste post fica somente sobre o Jenkins.

Instalação
Vá na página oficial do Jenkins e selecione o link para o Java Web Archive (.war). Você pode fazer o deploy do Jenkins em um servidor de aplicação normalmente, mas para fins didáticos, vou inicializar como uma aplicação standalone. Para fazer isso, basta navegar pelo prompt de comando até o diretório onde se encontra o arquivo que foi baixado, e executar o seguinte comando: java -jar jenkins.war. Abra seu navegador e digite o seguinte endereço: http://localhost:8080/. Se você fez tudo corretamente a página principal do Jenkins será exibida.

Builds
O exemplo que irei mostrar a seguir, é de um job (tarefa), que irá, a cada commit em um repositório do GitHub, realizar o build da aplicação, inclusive rodando seus testes unitários. Isso possibilita que os desenvolvedores mantenham seu código constantemente integrado com o resto do sistema, e fornece um rápido feedback quando erros ocorrem. Mais sobre Continuos Integration (Integração Contínua) você pode conferir aqui.

Como iremos utilizar o Github, é necessário instalar o plugin que fará a conexão com o repositório. Para instalar o plugin vá em Gerenciar Jenkins -> Gerenciar Plugins -> Disponíveis, selecione o GitHub Plugin, e clique em Download now and install after restart.

Agora que temos o plugin instalado, o próximo passo é criar o job no Jenkins. Clique em Novo(a) Job, defina um nome para o mesmo, e marque a opção Construir um projeto de software free-style.

jenkins1

Clique em Ok. Será exibida uma tela para configuração do job. Existem várias opções de configuração, mas vamos fazer um exemplo bem simples. Em Gerenciamento de Código Fonte marque a opção Git, e insira a url de seu repositório. Em Disparadores de Construção selecione a opção Construir periodicamente e insira os seguintes valores */5 * * * *. Isso determina que o Jenkins faça o build do projeto a cada 5 minutos. Clique em salvar, e o seu job estará pronto para ser executado.

Sem títuloAlém do exemplo

Este foi um exemplo bem básico, com o objetivo de demonstrar a instalação e funcionamento, e ainda despertar o interesse pela ferramenta. Muitas outras coisas podem ser automatizadas via Jenkins, como deploys de aplicações ou até compilações de livros, sua utilidade é muito vasta. Pesquise mais sobre o assunto, e começe a criar o hábito de automatizar suas tarefas que são repetitivas e acabam consumindo seu tempo todos os dias.

Automatização utilizando Ant

Desenvolvedores que iniciaram seu aprendizado na linguagem Java utilizando alguma IDE, muitas vezes desconhecem como funcionam os processos responsáveis por transformar o código escrito, em software propriamente dito. Neste post irei mostrar um pouco sobre os conceitos por trás destes processos, como compilar e geração de arquivos .jar, e como automatizar estas tarefas utilizando o Ant.

Os arquivos .class

Quando desenvolvemos um software escrito em Java, não é nosso código em si que é utilizado para executar o programa. Antes de rodarmos o código que escrevemos, o mesmo deve ser compilado, etapa esta que a maioria das IDEs faz automaticamente. A compilação consiste em transformar o código fonte, legível para nós, em código de máquina ou bytecode, que é a forma que a JVM (Java Virtual Machine) compreende e sabe executar. Enquanto os arquivos que escrevemos possuem a extensão .java, este arquivos gerados, escritos em bytecode, são arquivos .class.

Os arquivos .jar e .war

A não ser que você esteja escrevendo seu primeiro Hello World, dificilmente seu programa em Java terá somente uma classe. O arquivo .jar é o executável do Java, nele se encontram os pacotes com todas as classes e arquivos do seu software. Os arquivos .war funcionam de forma semelhante, mas são criados para aplicações web, nele também se encontram todas as classes e arquivos do projeto. O arquivo .war é utilizado para instalar a aplicação no servidor web como Jboss ou TomCat.

Apache Ant

Apache Ant, ou somente Ant como é mais conhecido, é uma ferramenta que automatiza além dos processos mostrados anteriormente muitos outros. Você pode por exemplo criar e remover diretórios, mover arquivos entre eles, rodar seus testes unitários e gerar relatórios.

Instalação

Baixe o instalador do Ant aqui. Descompacte o arquivo no local de sua preferência. É necessário inserir o caminho da pasta “bin” do Ant às variáveis de ambiente do Windows. Copie o endereço da pasta bin que vai ser algo como “C:\Program Files\apache-ant-1.9.2\bin”. Vá nas propriedades do computador e acesse a opção variáveis de ambiente. Procure a variável Path e adicione no final de seu valor o caminho para o diretório copiado anteriormente. Isso é tudo que precisa ser feito, para conferir se a instalação ocorreu corretamente, apartir do prompt de comando digite: ant –version. Se tudo estiver certo, uma mensagem com a versão de seu Ant será exibida.

O arquivo build.xml

As operações do Ant, mais conhecidas como tasks, funcionam através de configurações escritas em um arquivo XML. Através de comandos simples as tarefas que vimos anteriormente podem ser automatizadas facilmente. Vou demonstrar isso através de um exemplo bem simples com o objetivo de demonstrar na prática como se monta um arquivo de build. Crie os arquivos build.xml e TesteAnt.java, e copie os trecho abaixo, ou baixe o exemplo pronto no meu GitHub.

public class TesteAnt {
public static void main(String[] args) {
System.out.println(“Hello Ant!”);
}
}

<project name=”teste” basedir=”.” default=”executar”>

<property name=”classes” location=”classes”/>
<property name=”arquivo” value=”TesteAnt” />

<target name=”diretorios”>
<mkdir dir=”classes” />
</target>

<target name=”apagar”>
<delete dir=”classes”/>
</target>

<target name=”compilar” depends=”diretorios”>
<javac srcdir=”${basedir}” classpath=”${classes}” destdir=”${classes}”/>
</target>

<target name=”empacotar” depends=”compilar”>
<mkdir dir=”build/jar”/>
<jar destfile=”build/jar/TestAnt.jar” basedir=”${basedir}/classes”>
<manifest>
<attribute name=”Main-Class” value=”main.TesteAnt”/>
</manifest>
</jar>
</target>

<target name=”executar” depends=”empacotar, apagar”>
<java jar=”build/jar/TestAnt.jar” fork=”true”/>
</target>

</project>

Por trás do exemplo

<project name=”teste” basedir=”.” default=”executar”>

Esta linha é o início do arquivo de build, onde é declarado o nome do projeto, o diretório base, e a task padrão que será executada pelo Ant.

<property name=”classes” location=”classes”/>
<property name=”arquivo” value=”TesteAnt” />

A tag property serve para declarar variáveis que podem ser utilizadas dentro do arquivo de build.

<target name=”diretorios”>
<mkdir dir=”classes” />
</target>

A tag target serve para definir um alvo para o Ant. Uma vez definido, você pode chamar o alvo dentro do arquivo, ou até de fora através do comando “ant nomeDoAlvo”. Mkdir cria um diretório com o nome recebido por parâmetro.

<target name=”apagar”>
<delete dir=”classes”/>
</target>

Delete apaga o diretório com o nome recebido. Não se preocupe não estamos criando e apagando em seguida o diretório, você já irá entender.

<target name=”compilar” depends=”diretorios”>
<javac srcdir=”${basedir}” classpath=”${classes}” destdir=”${classes}”/>
</target>

A tag javac, assim como o comando de mesmo nome, compila os arquivos .java gerando como saída os .class escritos em bytecode

<target name=”empacotar” depends=”compilar”>
<mkdir dir=”build/jar”/>
<jar destfile=”build/jar/TestAnt.jar” basedir=”${basedir}/classes”>
<manifest>
<attribute name=”Main-Class” value=”main.TesteAnt”/>
</manifest>
</jar>
</target>

A tag jar empacota os arquivos indicados gerando como saída um arquivo jar. Já a tag manifest cria o arquivo manifest necessário para criação do pacote jar.

<target name=”executar” depends=”empacotar, apagar”>
<java jar=”build/jar/TestAnt.jar” fork=”true”/>
</target>

E a tag java  executa um arquivo .jar. A tag depends indica que a iniciação do target depende da finalização de outro, por isso no exemplo anterior o alvo “apagar” não será executado após o “diretorios”, e sim antes do alvo “executar”. Cuidado ao montar seu arquivo, se um target não for dependência de outro, ele só será executado caso seja declarado como default na tag project.

Executando

Para executar o arquivo é simples, basta abrir o prompt de comando, navegar até a pasta onde se encontra o arquivo “build.xml”, e digitar o comando ant, se tudo ocorrer bem, você terá uma pasta com o arquivo .jar e a mensagem “Hello Ant!” será exibida no console. Também é possível executar um target específico executando o comando ant nomeTarget.

Como disse anteriormente, este foi apenas um exemplo didático, o Ant possibilita automatizar muitas outras tarefas de seu projeto. Abaixo seguem alguns links interessantes para se aprofundar no assunto.

Links

Ant: http://ant.apache.org/

Documentação: http://ant.apache.org/manual/index.html

Lista de tasks: http://ant.apache.org/manual/Tasks/ 

Análise de Código utilizando SonarQube

No meu último post falei sobre métricas de código e os benefícios que eles podem trazer para a boa saúde do código. Hoje irei apresentar uma ótima ferramenta para gerar automaticamente estas métricas, SonarQube.

SonarQube é um software open-source que se propõe a ser a central de qualidade do seu código-fonte, lhe possibilitando o controle sobre um grande número de métricas de software, e ainda apontando uma série de possíveis bugs. Tudo isso é gerado através de uma análise completa do código, e após isso os resultados obtidos são mostrados através de uma interface web, em forma de dashboards, e gráficos. Um exemplo do resultado disto pode ser visualizado nesta página.

Iniciando o SonarQube

Vejamos então como configurar o SonarQube. Para este exemplo irei utilizar um projeto Java do jogo FizzBuzz. Além de Java, mais de 25 linguagens são suportadas como C# e Python por exemplo. Uma lista completa pode ser conferida aqui.

Baixe o SonarQube 3.6.3. Descompacte o arquivo em uma pasta de sua escolha. Abra a pasta “sonar-3.6/bin” e entre na versão relativa ao seu sistema operacional. Execute o arquivo StartSonar.bat (no caso do Windows). Um console irá aparecer e executar o serviço do Sonar. Para verificar se tudo ocorreu corretamente acesse o seguinte endereço em seu navegador: http://localhost:9000/. A tela abaixo deve aparecer.

exemplo

Tela de apresentação do SonarQube

Configurando o projeto

O próximo passo será criar o arquivo de configuração. Crie um arquivo com o nome “sonar-project.properties” na raiz de seu projeto. Abaixo segue o arquivo com a configuração para o projeto exemplo, copie para o seu arquivo e faça as adaptações necessárias para o seu projeto.

# metadados requeridos

sonar.projectKey=FizzBuzzSonarExample

sonar.projectName=FizzBuzzSonarExample

sonar.projectVersion=0.1

# caminhos para os códigos fontes

# caminhos podem ser separados por vírgula

sonar.sources=src/main/java

sonar.tests=src/main/test

# A linguagem do projeto

sonar.language=java

# Formato

sonar.sourceEncoding=UTF-8

Analisando o código

Para fazer a análise do código iremos utilizar o SonarQube Runner. Baixe o arquivo SonarRunner 2.2.2, e extraia o conteúdo em uma pasta de sua escolha. Agora é necessário adicionar o caminho onde se encontra o arquivo “sonar-runner.bat” às variáveis de ambiente (no caso do Windows). Clique com o botão direito em Computador e escolha propriedades. Vá em Configurações avançadas do sistema e entre em variáveis de ambiente. Edite a variável Path, adicionando no final o caminho para o SonarQube Runner, que irá ser algo como: “suaPasta\sonar-runner-2.2.2\bin”

variaveis

Adicionando o SonarQube Runner às variáveis de ambiente

Feita a configuração, é hora de análisar o projeto. Se certifique que o SonarQube foi iniciado e que seu projeto tenha o arquivo “sonar-project.properties”. Através do Prompt de Comando, navegue até a pasta raiz de seu projeto e digite o comando: “sonar-runner”. Se tudo ocorrer bem a análise deve iniciar e o resto do trabalho é feito automaticamente. O tempo de duração irá variar de acordo com o tamanho de seu código, e no final uma mensagem de sucesso é exibida.

prompt

Mensagem de sucesso na execução do Sonar Runner

Agora você pode acessar novamente o endereço http://localhost:9000/ para conferir o resultado. Os dashboards com as métricas padrões serão exibidos. Você pode configurar os dashboards, efetuando login com usuário: admin, e senha: admin. 

Por fim acesse a documentação oficial para conhecer as diversas opções de métricas disponíveis, e escolha as que atenderem o seu projeto.

Escalando Horizontalmente – AWS Auto Scaling – Parte#1

Finalmente depois de alguns aprendizados e experiências chegou a hora de compartilharmos um pouco sobre Amazon Web Services. Vamos então falar sobre  escalar de forma horizontal utilizando o serviço Auto Scaling da AWS. Para aqueles que não conhecem o AWS Auto Scaling indico fortemente dar uma boa leitura na vasta documentação do serviço que aborda desde conceitos básicos de utilização até mesmo referencias da API.

Outra dica também é assistir a palestra realizada no uMov.Me Labs Summit realizado em Abril 🙂

Para interagirmos com os serviços web services da Amazon relacionados a política de Auto Scaling podemos escolher basicamente entre:

  • SDK – Utilizando a API de desenvolvimento da AWS disponível hoje para as principais linguagens de programação como Java, .Net, Ruby, PHP, Node.JS e também plataformas móveis como Android, iOS. Através da API de desenvolvimento é possível interagir diretamente com os web services da Amazon, manipulando grande parte dos serviços oferecidos via console de gerenciamento.
  • Command Line Tools – Grande amigo dos SysAdmins, o Command Line Tools, veio para facilitar a interação com os principais serviços disponíveis pela AWS, onde sem precisar desenvolver nenhuma linha de código ou instanciar nem objeto é possível gerenciar sua infraestrutura usando apenas o terminal.

Neste primeiro exemplo iremos adotar o Command Line Tools como ferramenta para criarmos uma política de auto scaling. Nesta abordagem iremos fazer com que nossa infraestrutura esteja preparada para escalar de forma horizontal. É possível utilizando o serviço Auto Scaling prever períodos de grande utilização de uma determinada aplicação ou serviço, mas também simplesmente reduzir o número de instancias durante os períodos de inatividade das mesmas, impactando diretamente assim nos custos com infraestrutura.

Através de alguns poucos passos utilizando o Command Line Tools você poderá obter significativa redução no seu bolso ao final do mês. Então chega de bla bla bla e vamos ao que interessa: Setup:

  1. Para iniciar realize o download da ferramenta Command Line Tools de Auto Scaling;
  2. Uma vez descompactado o arquivo, será criada a pasta ‘AutoScaling-xxx’. Iremos seguir os passos descritos na seção “Installation” do arquivo README.TXT situado dentro da pasta descompactada, setando assim todas as variáveis de ambiente necessárias para rodarmos os scripts;
  3. Agora é a vez de obter suas chaves de segurança da AWS para conseguirmos interagir com a API da AWS. Para obter as suas credenciais basta acessar as configurações da sua conta e obter as duas chaves(Chave de acesso, Chave de acesso secreta).
  4. Com as chaves em mãos, basta seguir a seção “Using AWS Keys” do arquivo README.TXT situado dentro da pasta descompactada.
  5. Para ter certeza de que tudo está funcionando corretamente digite no terminal o comando “as-cmd”. Se todos os passos foram seguidos corretamente você verá uma lista com os comando disponíveis da ferramente de auto scaling via Command Line Tools.
  6. Dúvidas?

Escalando:

  1. O primeiro passo a ser realizado basicamente irá identificar qual AMI(Amazon Machine Images) servirá de base para criar novas VMs quando necessário. Para isso basta executar o comando abaixo:  
    as-create-launch-config my_config --image-id ami-xxxxxxxx --instance-type m1.micro
  2. Uma vez criada a configuração de inicialização de novas VMs, precisamos informar agora através da criação de um novo grupo de auto scaling em quais zonas estas VMs devem ser criadas. Algumas outras informações importantes são número mínimo e máximo de VMs bem como para qual ELB(Elastic Load Balancer) estas VMs devem ser atribuídas. Crie um novo grupo executando:
    as-create-auto-scaling-group my_as_group --launch-configuration my_config --availability-zones us-east-1a us-east-1b --min-size 2 --max-size 20 --load-balancers MyLB
  3. Para que possamos iniciar uma nova VM e desta forma escalar horizontalmente é necessário a criação de políticas de auto scaling. Desta forma criaremos uma política para adicionar novas VMs respondendo ao load balancer associado. Para isso precisamos executar o comando:
    as-put-scaling-policy scale_up --auto-scaling-group my_as_group --adjustment=1 --type ChangeInCapacity --cooldown 300
  4. Uma vez incrementado o número de VMs e satisfeito o aumento na demanda das aplicações, você também pode ter uma política de auto scaling para desligar VMs uma vez identificado baixo tráfego de requisições através do ELB em questão. Semelhantemente ao passo 3 iremos criar uma nova política, porém agora estaremos subtraindo uma VM de modo a economizar recursos não utilizadas executando o comando:
    as-put-scaling-policy scale_down --auto-scaling-group my_as_group --adjustment=-1 --type ChangeInCapacity  --cooldown 300

    Você ainda pode resolver diminuir o número de VMs após o horário comercial onde o volume de acessos diminui consideravelmente e através do monitoramento de memória ou CPU indicam inatividade de algumas VMs. Mas este é um assunto para o próximo post, AWS Auto Scaling – Parte#2 🙂

  5. Vamos testar? Uma vez que não atrelamos nenhuma rotina de monitoramento onde poderíamos criar e remover instancias automáticamente, podemos criar e remover instancias manualmente através do comando “as-execute-policy“.
  • Baseado na política para criar VMs podemos executa-la assim:
    as-execute-policy --name scale_up --auto-scaling-group my_as_group
  • Baseado na política para remover VMs podemos executa-la assim:
    as-execute-policy --name scale_down --auto-scaling-group my_as_group

Desta forma temos uma primeira política de auto scaling! Em um próximo post estaremos explicando como automatizar a criação e remoção de VMs utilizando o serviço AWS CloudWatch. #ficadica

Continuous Delivery! Sua empresa está preparada?

Ainda depois de mais de 11 anos praticando agilidade, muitas são as equipes de desenvolvimento de software que sonham em realizar um deploy a partir de um simples click. O que geralmente ocorre é que as organizações e seus respectivos times/produtos muitas vezes não estão preparados para este grande passo. 

Para ilustrar e enriquecer este post, acompanhe algumas dicas e aprendizados adquiridos através de experiências e treinamentos como por exemplo com o autor do livro Continuous Delivery, @jezhumble.


O quão ágil é o seu time?

Hoje em dia não raros são os times de desenvolvimento de software que se consideram “ágeis”, ou que buscam nas praticas ágeis a base para seus ciclos de desenvolvimento. @Jezhumble costuma questionar o quão ágil um time de desenvolvimento é. E o mais importante, como chegar a uma métrica para mensurar tal informação. A reposta mais simples possível vem do mesmo @jezhumblee, onde ele sugere mensurar o quão rápido seu time consegue entregar software de qualidade a seus clientes. #ficaadica

Seu time está preparado para entregar software de forma contínua?

Ainda falando em desenvolvimento àgil de software, temos como premissa a entrega de software agregando valor ao negócio do cliente. Desta forma muitas equipes pecam na tentativa de estabelecer uma linha de entrega contínua a seus clientes, onde os motivos vão desde erros operacionais básicos das equipes até mesmo o despreparo por parte do cliente em relação ao modelo de entrega proposto.

Para evitar os pecados mencionados anteriormente, procure criar uma cultura de entrega continua. Faça com que a entrega de versões ou a simples entrega de uma nova funcionalidade faça parte do planejamento de cada equipe e não apenas após finalizado a codificação da mesma. Discuta estratégia de entregas. Discuta, reforce, defina o conceito de “PRONTO” com o seu time e lembre-se, tarefa pronta significa valor entregue ao cliente em produção.

Automação

Novamente parafraseando @jezhumble “… automação é tudo” ou talvez seria para tudo? O fato é que automação é um ponto chave para quem busca realizar entregas consistentes independentemente do tamanho do ciclo de desenvolvimento trabalhado.

Garanta através de “mecanismos de segurança” constantes validações sob a versão ainda em desenvolvimento, gerando feedback constante e garantindo que a linha de produção não pare, ou se caso venha parar que volte a produzir o quanto antes possível. Entre estes mecanismos estão a automação de testes validando a versão a cada commit realizado. Integrar continuamente a versão corrente evitado surpresas ao fechar versões para produção ou então rodar noturnamenta suites de regressões antecipando não conformidades geralmente identificadas apenas na validação de versões pré-produção.

Eliminar processos complexos e consequentemente dificeis de serem executados é um fator muito importante na automação de tarefas. Se uma tarefa é complexa para ser executada, talvez necessite ser executada com mais frequência buscando assim alternativas e soluções mais simples de serem executadas.

Não elimine a intervenção das pessoas no processo de entrega, pessoas são ótimas em heuristica.

“… se é demorado é porque é dificil, se é dificil é porque é manual, se é manual precisa ser automatizado”

 Continuous Deployment e Continuous Delivery

Os termos Continuous Deployment e Continuous Delivery podem nos gerar confusão. Pois bem vamos exemplificar o conceito de cadas um deles abaixo:

  • Continuous Deployment: É caracterizado pelo fechamento de builds de software funcionais.

Ex.: Realizar o fechamento de versão e realizar o deploy no ambiente de homologação a cada nova funcionalidade uma vez validada pelos testes. Note não estamos entregando software em produção. 

  • Continuous Delivery: Pode ser considerado o passo de simplesmente agregar valor ao negócio propriamente dito. Conforme o ambiente, baterias de validações podem fazer parte deste processo intermediado diretamente pelo pessoal de negócio, ou simplesmente em ambientes automatizados este mesmo time decide qual o melhor entregável deve ser promovido para produção clicando no botão “release”. http://goo.gl/QkaO 

Cultura DevOps 

Leve para dentro de seu time a cultura DevOps, fazendo o time de desenvolvimento sentir as dores atuais para realizar a liberação de uma nova versão. Fazer do time de operações uma extensão do time de desenvolvimento ou vice-versa.

Esta maior integração propicia ao desenvolvedor uma maior responsabilidade dentro do processo de liberação de novas versões. A prática de code refactoring não pode ser vista como ato de heroísmo e sim de responsabilidade e respeito para com o time. Um desenvolvedor deve garantir que após realizar uma refatoração em uma parte do sistema, tudo deve continuar funcionando conforme anteriormente.

Realize eventos para apresentar grandes mudanças no software, evitando assim também grandes surpresas e processos de rollbacks/fallbacks traumáticos. Mas esteja sempre preparado para executá-los da melhor forma possível.

Estude melhores práticas e formas de modo a facilitar o bom andamento do ciclo de desenvolvimento de seu time tais como:

  • Feature Toogles;
  • Feature Branching; 
  • Blue-Green Deployment;
  • Virtualização etc …

Pratique Chaos Monkey! Aprenda com suas falhas e a melhor forma de fazer isso é falhar frequentemete. Certifique-se de que sua infraestrutura pode ser recriada através do seu controle de versão, incluindo scripts de toda e qualquer espécie.