segunda-feira, 17 de fevereiro de 2014

Infrastructure As Code (IAC)

Continuando nossa série de artigos sobre Entrega Contínua (Continuous Delivery) e DevOps, vamos falar sobre uma técnica muito importante e necessária para atingir esses dois objetivos: Infrastructure As Code, uma abordagem diferente de encarar a infraestrutura de TI, que é a base para outras técnicas, como: PaaS e SaaS.




Isso tudo é coisa do passado

No final dos anos 2000, a instalação de um software em ambiente de "produção" exigia a aquisição de equipamento. Cada novo aplicativo ou website, era instalado em seu próprio servidor, assim como suas cópias (balanceamento de carga), Servidor de banco de dados e Servidor de aplicação. Eu mesmo, cansei de supervisionar instalação de novos servidores e sites, passando noites dentro de salas-cofre, geladas, tentando instalar tudo e testar antes do raiar do dia.

Era uma atividade de altíssimo risco, pois a intervenção humana era absolutamente indispensável, desde a montagem do hardware, instalação do sistema operacional e drivers, até a instalação e configuração do sistema aplicativo. Quase sempre, alguém esquecia de configurar alguma coisa, e isto gerava vários atrasos.

Além do mais, o teste da nova instalação era todo manual, e feito por pessoas cansadas e sonadas, lá pelas 3 horas da manhã.

Com o passar do tempo, as Caixas individuais foram sendo substituídas por Sistemas modulares, que vinham com vários computadores "embutidos", e que podiam crescer de maneira bem descomplicada. Eu me lembro de ficar "babando" diante de uma Sun Enterprise F 15.000, com vários servidores UltraSparc alinhados em um armário gigantesco. Com estas máquinas, era possível dividir o sistema em vários "domínios" virtuais, criando clusters de servidores.

Mas, apesar do avanço, a configuração desses "clusters" de máquinas ainda dependia de muita intervenção manual, e a documentação de configuração de infraestrutura, nunca foi muito boa.

A virtualização mudou tudo

Há muito tempo, eu tive a oportunidade de trabalhar com uma solução baseada no sistema VirtuOS, criado no Brasil pela empresa Microbase, que era capaz de emular várias máquinas X86, tornando o MS-DOS multiusuário e multitarefa. Eu fiquei muito impressionado com aquilo e tive a sensação de que o futuro estava reservado à virtualização.

Depois, tive a oportunidade de trabalhar com outros softwares, como o QEMU, o VMWare, o Virtual PC, e o VirtualBox. Em meu ambiente de desenvolvimento, tenho várias VMs (Máquinas Virtuais), rodando serviços diversos, atitude que virou "mania" entre os desenvolvedores de aplicações corporativas, afinal, não podemos investir em comprar várias máquinas físicas só para emular Servidores.

Uma VM é um software de emulação de hardware que seja capaz de executar um sistema operacional, e seus drivers, além de executar servidores e aplicações como se fosse uma máquina real. No início dos anos 2000, não conseguíamos executar mais do que uma VM em um computador, porém, com a evolução do hardware (64 Bits, aumento de memória e aumento de núcleos de CPU), é possível executar várias VMs com desempenho satisfatório em apenas um único computador físico.


Podemos criar VMs e replicá-las entre vários servidores físicos, desacoplando, desta forma, o hardware da plataforma de execução. As VMs podem ser criadas, mantidas em "estoque", distribuídas, replicadas e até trocadas de máquina, sem prejuízo de sua funcionalidade. Assim, se der "xabú" em um Servidor, podemos simplesmente pegar o arquivo original da VM e subir outra cópia, com tudo o que precisamos pré-instalado.

O processo de criar uma VM ainda era "doloroso" e manual, portanto sujeito a erros. Era necessário baixar a imagem ISO do sistema operacional, ou ter o CD de instalação em mãos, e depois criar a VM, configurando drivers etc. Tudo começou a mudar quando algumas pessoas começaram a disponibilizar VMs na Internet, já pré-configuradas com tudo o que precisamos.

Criação e provisionamento de VMs

Com o passar do tempo, surgiram várias ferramentas capazes de interagir com os Provedores de VMs, como o VMWare ou o VirtualBox, e comandar a criação de VMs dinamicamente, baixando as imagens prontas da Internet ou de um local na Rede privada. Da mesma forma, surgiram ferramentas de Provisionamento (Provisioning) de VMs, que consiste em instalar tudo o que é necessário para subir uma VM, sem intervenção manual.

Ferramentas de criação e gestão como o Vagrant, se tornaram populares, substituindo o tedioso processo manual de criação e configuração de VMs.

Gestão e configuração de VM

Ferramentas de gestão e configuração permitem gerenciar diversas VMs, espalhadas em um ambiente físico, ou mesmo em nuvem. Estas ferramentas criam e configuram VMs com base em imagens prontas, obtidas da Internet ou de uma rede própria, configurando tudo o que é necessário para que funcionem adequadamente. O Vagrant é uma das mais conhecidas e populares ferramentas de criação e gestão de VMs.

Provisionamento de VM

As ferramentas de provisionamento são especializadas em instalação e preparação de servidores, podendo validar e instalar tudo o que é necessário, sem intervenção manual. As mais modernas, utilizam um processador de linguagem específica de domínio (DSL), que oferece uma interface de programação de alto nível para configuração das máquinas. Existem ferramentas "stand alone", e existem ferramentas Cliente-Servidor, que facilitam a atualização das VMs. Entre as ferramentas mais populares de provisionamento estão: Puppet e Chef.

Por que precisamos de dois tipos de ferramentas? Algumas, como o Vagrant, possuem capacidade limitada de provisionamento, atendendo a necessidades pontuais e até permitindo a criação de infraestruturas distribuídas, porém, quando começamos a pensar em oferecer serviços de IaaS e PaaS, temos que ter maior flexibilidade, logo, pode ser interessante separar as duas necessidates (Gestão e Provisionamento). O próprio Vagrant é capaz de se integrar com o Puppet ou com o Chef para provisionamento.


Se adicionarmos um sistema de controle de versões (VCS) e um ambiente de Integração Contínua (IC), podemos criar e oferecer IaaS - Infrastructure As A Service, formando um verdadeiro ambiente de "Cloud Computing" (nuvem) para uso interno ou externo.

Usando ferramentas de Gestão e Provisionamento de VMs, passamos a ter toda a nossa infraestrutura codificada em arquivos de texto, que é exatamente o conceito de "Infrastructure As Code", que estamos apresentando aqui. Desta forma, se alterarmos algum parâmetro no código fonte da nossa Infra, o sistema de Integração Contínua pode detetar a mudança e acionar o servidor de Provisionamento, que pode atualizar "on the fly" as máquinas existentes.

E para nuvem, falta o quê? 

O objetivo deste artigo não é apresentar tecnologias de "Cloud computing", porém, quando falamos em IaC (Infrastructure as Code), é quase impossível deixar de falar em nuvens. É claro que é possível criar um serviço de oferta "on demand" de VMs, pré-configuradas exatamente como o Cliente deseja, e gerenciar as várias instâncias virtuais somente com ferramentas de Gestão e Provisionamento. Porém, existem softwares especializados em gestão de nuvens, como o OpenStack que, em seu módulo "Compute" é especializado e fornecer recursos de TI sob demanda, incluindo a gestão e provisionamento. Eu pretendo falar um pouco mais dele e mostrar exemplos com o DevStack, a versão para desenvolvedores, que vão fazer você ficar completamente atordoado. Mas, isso já é outro assunto...

Nada como um pequeno exemplo

Sei que foi muito blá-blá-blá até agora, então, vamos mostrar um pequeno caso para que você entenda o poder do IaC e como pode usá-lo para ganhar tempo e oferecer maior segurança aos seus Clientes. Imagine que você tenha um Website, desenvolvido em Java, e use o Tomcat7 para executá-lo. Vamos criar um código que represente essa infraestrutura e permita a você criar, provisionar e gerenciar quantos servidores desejar, formando sua própria nuvem pessoal. Para isso, vou usar o Vagrant, que é Open Source, e muito utilizado para gestão de VMs. Para começar:

  1. Baixe o Vagrant para sua plataforma (Windows, Mac OSX, Debian, Ubuntu, Red Hat, Fedora e CentOS);
  2. Baixe o VirtualBox;
  3. Se estiver utilizando Microsoft Windows, baixe o PuTTY;
Após instalar tudo, crie uma pasta e copie o seguinte arquivo para ela, chamando-o de "Vagrantfile" (assim mesmo, com o "V" maiúsculo e sem extensão: 

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precision32"
  config.vm.box_url = "http://files.vagrantup.com/precise32.box"
  config.vm.provision :shell, :inline => "sudo apt-get -y update"
  config.vm.provision :shell, :inline => "sudo apt-get -y install openjdk-7-jdk"
  config.vm.provision :shell, :inline => "sudo apt-get -y install tomcat7"
end

Este script informa ao Vagrant que queremos criar uma VM usando a imagem Ubuntu "precise32", que está armazenada no próprio site do Vagrant. Existem várias imagens, e você pode criar a sua própria, usando o VeeWee. Se quiser, pode ir ao site VagrantBoxes e baixar vários tipos de boxes pré-configuradas.

Depois de criar a máquina virtual com a imagem baixada, o Vagrant vai provisioná-la com alguns comandos Bash. Podem ser arquivos ".sh" externos, ou mesmo scripts Puppet ou Chef. Neste caso, estamos atualizando a lista de pacotes do Ubuntu e mandando instalar o OpenJDK 7 e o Apache Tomcat 7.

Bem, na pasta onde você criou o arquivo "Vagrantfile", digite o comando:

vagrant up

E aguarde. Vai demorar um pouco... Em um ambiente de produção, é melhor baixar a box e instalar na sua própria rede. Depois de baixar, o Vagrant vai provisionar e iniciar a VM.

Para saber se a VM está rodando, digite:

vagrant status

Para derrubar a VM, digite:

vagrant halt

Para destruir a VM, digite:

vagrant destroy

Sempre que você digitar "vagrant up", o Vagrant vai procurar pelo "Vagrantfile" e, caso a VM não exista, ele vai criar e provisionar.

Como saber se a VM está rodando? Como saber se funcionou? 

É claro que podemos configurar "port forward" e outros recursos, mas o objetivo desse artigo não é ensinar a usar Vagrant. Se você usa Linux ou Mac OS X, é só usar o comando:

vagrant ssh

Agora, se você está usando Microsoft Windows, abra uma sessão do PuTTY e conecte-se com:

Host: 127.0.0.1
Porta: 2222

E digite o usuário "vagrant", senha "vagrant".

Seja no PuTTY ou no Cliente SSH, para testar se o provisionamento funcionou, acesse a página do Tomcat:

wget 127.0.0.1:8080

E abra o arquivo "index.html" que ele baixou:

more index.html