Caixa de Ferramentas DevOps Um Guia Para Construção, Administração e Arquitetura de Sistemas...

175

description

Caixa de Ferramentas DevOps Um Guia Para Construção, Administração e Arquitetura de Sistemas Modernos - Casa Do Codigo

Transcript of Caixa de Ferramentas DevOps Um Guia Para Construção, Administração e Arquitetura de Sistemas...

SOBRE O AUTORPassei minha infncia e adolescncia mexendo em eletrnica,guitarra e computadores 8 bits. Hoje sou formado em Cincia daComputao e ps-graduado em Sistemas de Informao.Gosto muito do que fao: construo e conserto sistemasdistribudos e de larga escala h 20 anos. Alm de programar emPython, Erlang e Go, fao caf, e-mail, cloud, big data e automaode infra.H algum tempo comecei a trabalhar gerenciando pessoas e meapaixonei pela possibilidade de criar equipes e conquistar grandesprojetos. Quando descobri minha carreira gerencial tive certeza deque deveria me esforar mais para continuar relevante tecnicamentee falar a lngua das pessoas que trabalham comigo. Tive a sorte departicipar de empresas e equipes que desenvolvem e operam algunsdos maiores sistemas da internet do Brasil.Escrevi um livro em 2005 chamado Programao Avanada emLinux, o primeiro livro brasileiro a falar sobre kernel, mdulos,drivers, dispositivos eletrnicos e temas avanados do sistemaoperacional.J palestrei em vrias edies da RubyConf, QCon e OSCon, noBrasil e nos Estados Unidos. Tenho um repositrio de cdigo(https://github.com/gleicon) e publico o que acho interessante noTwitter (https://twitter.com/gleicon).Meu perfil profissional no Linkedin fica emhttps://linkedin.com/in/gleicon. Tenho um site com links paraprojetos em http://7co.cc/. O material das palestras que j dei podeser encontrado em http://www.slideshare.net/gleicon e tambm emhttps://speakerdeck.com/gleicon/.Participe do nosso grupo de discusso do livro, emhttps://groups.google.com/forum/#!forum/caixa-de-ferramentas-devops.INTRODUOEste livro uma introduo com opinies sobre ferramentas paradesenvolvimento e administrao de sistemas. As ferramentasdemonstradas so flexveis e extensveis, o que permite que a mesmatarefa seja executada de formas distintas.Meu objetivo mostrar uma maneira de utiliz-las para ganharprodutividade rapidamente. Ao longo do texto, coloquei refernciaspara que o leitor possa se aprofundar ou buscar um conceito tericoque est fora do escopo proposto. No vou me deter em discussesholsticas de implantao de conceitos geis ou DevOps.Originalmente, este livro era um conjunto de notas que fuicolecionando durante o dia a dia e conversas com colegas.Revisando estas notas quando precisei comear um novo projeto medei conta de que elas contavam uma histria interessante para quemteve pouco ou nenhum contato com ferramentas de automao evirtualizao. Mais ainda, elas me ajudaram a treinar outras pessoascom pouco tempo e com objetivos maiores do que se especializaremem Ansible, Vagrant ou Virtualbox.As ideias descritas podem ser implementadas e utilizadas comqualquer substituto destas ferramentas provavelmente voc temum deploy.sh em algum diretrio ou repositrio que faz mais queelas em conjunto. Isso bom, pois mostra que a necessidade existe eque j foi investido um tempo em atend-la. Minha proposta nestecaso explorar a combinao das ferramentas apresentadas paraentender a maneira modular como o mesmo problema resolvidopor elas.Automatizao um amplificador da energia que voc investeem suas tarefas. O mesmo argumento que era utilizado paracontrole de verso pode ser utilizado para automao: voccompromete um tempo aprendendo, investe um pouco mais nosprimeiros passos e depois ganha em escala e qualidade de trabalho.Uma das ideias que vou explorar no texto de que todorepositrio de cdigo tenha uma estrutura mnima que consiga criarum ambiente para desenvolvimento ou teste localmente. Ao montaruma estrutura de automao para sua aplicao que funcionalocalmente, voc ganha a mesma estrutura para seu ambiente deproduo.Desenvolver localmente com a habilidade de criar ambientescom arquitetura semelhantes s encontradas em ambiente deproduo um principio poderoso. Ele habilita o desenvolvimentoincremental e testes funcionais, alm da familiaridade com aarquitetura do sistema.A velocidade de desenvolvimento e avaliao de bibliotecas eprojetos de cdigo aberto tambm aumenta com a habilidade decriar um ambiente isolado com todas as dependncias e descart-loaps o uso. Finalmente, um treinamento para o processo dedeploy.Se encararmos o fato de que sistemas e suas arquiteturas no soestticos, importante desenvolver um conjunto de prticas paraacompanhar o desenvolvimento e mudana desta arquitetura.Temos que ter respostas para recriar o ambiente em caso dedesastres, fazer crescer seus componentes quando confrontadoscom uma carga inesperada e desenvolver em uma rplica em escalado ambiente final.Ferramentas como Ansible e Vagrant so associadas aomovimento DevOps, que explora mudanas culturais eorganizacionais, alm de novas abordagens para problemasconhecidos como gerenciamento de configurao, monitoramento ecoletas de mtricas, aplicao de tcnicas de engenharia de softwarena criao de infraestrutura e a interao rpida entre equipes.Acompanhe podcasts (por exemplo o FoodFight, listas comoDevOps Weekly, Reddits como reddit.com/r/devops ereddit.com/r/sysadmin e conferencias como a Velocity para novasideias e projetos.Com as ferramentas que vamos ver, fcil testar de formacontrolada novas ideias apresentadas nestes canais. No mandatrio adotar ou se associar a qualquer grupo ou metodologiapara ter benefcios. So boas prticas colhidas e compartilhadas porpessoas com experincia de sistemas em produo. O custo baixo eo maior investimento o tempo para consumir o materialdisponvel.Vou assumir que seu sistema operacional baseado em Linuxou MacOS X. Usurios de Windows podem seguir as mesmasinstrues, mas provavelmente tero que trocar a direo da barra (de / para \ ), encontrar um editor de textos legal e pensar um poucoonde declarar variveis de ambientes e bibliotecas de Python. Ocdigo demonstrado neste livro estar disponvel em um repositrioem minha conta no GitHub (https://github.com/gleicon/caixa-de-ferramentas-devops). Este cdigo livre exceto aonde a licena dasbibliotecas utilizadas informem.Para as maquinas virtuais e receitas de Ansible, vou utilizar altima verso LTS de Ubuntu Server. Vou marcar os pontosespecficos e explicar um pouco de como fazer o mesmo paradistribuies baseadas em RPM realmente fcil e mostra comovale a pena investir tempo em um framework de automao como oAnsible. Tambm vou assumir que voc consegue usar o terminal(Terminal, iTerm, RXVT, XTerm etc.) disponvel. Novamente, paraWindows vou ficar devendo algo alm do command prompt e da versodo PuTTY que funciona localmente. Se souberem de umaalternativa legal que no seja instalar cygwin + XWindow mecontem.Por ltimo, tentei cobrir exemplos de aplicaes simples erepeti-los sob condies diferentes para criar uma histria deevoluo do uso das ferramentas.Vamos instalar um Wordpress em vrias configuraes eprovedores de servio e posteriormente um Banco de dados NoSQLchamado Cassandra. So aplicaes que cobrem alguns padres deuso e configurao que se repetem. Com isso, quero estimular adiscusso e a reflexo da arquitetura de suas aplicaes. Pense emcomo elas so compostas e qual a melhor maneira de organiz-las.Enjoy!147141516172027292931343638Sumrio1 Linux, SSH e Git1.1 Linux1.2 SSH1.3 Git1.4 Concluso2 Vagrant2.1 Introduo2.2 Caixa de Ferramentas Vagrant e VirtualBox2.3 Instalao do VirtualBox2.4 Instalao do Vagrant2.5 Concluso3 Ansible3.1 Instalao3.2 A configurao do Ansible e o formato YAML3.3 Ansible e Vagrant3.4 Refatorao3.5 Concluso4 Instalando WordPress em uma mquina4.1 Expandindo nosso playbook Um blog com WordPressSumrio Casa do Cdigo5257606870737783878994981001021031051121181201221251345 Proxy Reverso e WordPress em duas mquinas5.1 nginx e proxy reverso5.2 WordPress em duas mquinas5.3 Instalando seu WordPress em mquinas virtuais.5.4 DigitalOcean API v25.5 Concluso6 Cassandra e EC26.1 Vagrant e Cassandra6.2 Provisionamento na AWS6.3 Cassandra e AWS6.4 Concluso7 Mtricas e monitorao7.1 Monitorao7.2 CollectD e Logstash7.3 Profiling7.4 Concluso8 Anlise de performance em cloud com New Relic8.1 WordPress na AWS8.2 Instalando o New Relic8.3 Gerando carga profiling da aplicao8.4 Simulando limitaes de rede8.5 Concluso9 Docker9.1 Virtualizao9.2 Containers e CGroups9.3 Docker9.4 Boot2DockerCasa do Cdigo Sumrio1351411511531541581591649.5 Criando nosso container de PHP e NGINX e usando o DockerHub9.6 Docker Compose9.7 Concluso10 Em produo10.1 Deploy10.2 Building Blocks e Lock-In10.3 Blue/Green Deploy e pacotes10.4 Testes10.5 ConclusoSumrio Casa do CdigoCAPTULO 1Neste captulo vamos ver um resumo de trs assuntos quepermeiam o livro: Git, SSH e Linux. Se voc fluente nestastecnologias pode pular esta introduo tranquilamente.Estes assuntos em si criaram livros bem completos einteressantes. Vou demonstrar e explicar o necessrio parasobreviver aos prximos captulos. Voc deve procurar outros livrose material na internet para se aprofundar caso tenha interesse.O sistema operacional utilizado em todos os exemplos destelivro o GNU/Linux, distribuio Ubuntu na sua verso 14.04 LTSde 64 bits. Com poucas adaptaes, outras distribuies podem serutilizadas. Escolhi reduzir as opes para nos concentrarmos noobjeto do livro, principalmente quando falarmos sobre Ansible.Assumi tambm que sua mquina tem alguma variante de Linuxou Mac OS X. Falei um pouco sobre isso na introduo. No vamosutilizar comandos complexos, mas vou utilizar o Terminal sempreque possvel. No Mac OS X eu uso o ITerm 2 mas nada impede deutilizar o Terminal.app. No Linux fique vontade para usar oterminal com o que est acostumado.O interpretador de shell que uso o bash que estiver instalado, eo editor de textos o Vim, tambm na verso que estiver disponvel.LINUX, SSH E GIT1.1 LINUXLINUX, SSH E GIT 1Onde for preciso, fornecerei listagens de cdigos para seremdigitadas e cpias em um repositrio do GitHub.Esta verso de Linux encontrada nos provedores de servioque vamos utilizar, o que facilita a transposio dos exemplos parafora da mquina local. Explore as diferenas entre um Linuxexecutando localmente e remotamente. Crie mquinas e observe ocomandotopnelas.Aconselho que digite os exemplos no ambiente Linux para sefamiliarizar com as ferramentas e comandos. Nos prximoscaptulos vou sugerir que o que fizermos localmente seja feito emuma mquina em um provedor de cloud externo. A progresso doscaptulos nos levar a criar as mquinas automaticamente, masenquanto no chegamos l, voc precisar de mquinas criadas comautenticao por chave de SSH.Adiante, veremos como criar mquinas na AWS(http://aws.amazon.com) e na DigitalOcean(http://digitalocean.com). Escolhi estes dois provedores pois elestm cupons e opes de criar e utilizar mquinas sem custo por umperodo limitado, o que ideal para o aprendizado.Qualquer produto usado em provedores de cloud tem um custo.Load balancer so cobrados por trfego, e volumes de storage socobrados por trfego e armazenamento. Mquinas virtuaisgeralmente so cobradas enquanto esto ligadas ou enquantoexistirem. Leia bem a documentao oferecida e as regras decobrana.Na DigitalOcean, o processo simples: procure no Twitter deles(@DigitalOcean) um cdigo ou link e crie uma conta. s vezes, naprimeira vez que voc cria uma conta j ganha um crdito de 5dolares, o suficiente para um ms contnuo da menor mquinavirtual que eles oferecem. Se utilizarmos mais mquinas por um2 1.1 LINUXperiodo menor de tempo, criando e destruindo as instncias (outronome para mquina virtual) este valor d e sobra.Figura 1.1: Painel de criao de mquinas da DigitalOceanNa AWS, se voc j no tem uma conta, precisa criar, configurarum VPC (Virtual Private Cluster), um security group e subnet. Vocconsegue executar uma mquina sem isso apenas entrando noconsole, selecionando a opoEC2e no painel que aparecer clicarno boto a seguir:Figura 1.2: Boto de criao de mquinas na AWSO processo de criao e utilizao da AWS complexo poisoferece toda a infraestrutura de um datacenter de forma virtual eutilizvel programaticamente via API. Leia a documentao em(https://aws.amazon.com) para entender melhor e use o free tierpara seguir os exemplos oferecidos.1.1 LINUX 3Nas opes de criao de instncias sero feitas vrias perguntas. seguro inicialmente usar as opes padro. Lembre-se sempre dedesligar as mquinas no console para evitar cobrana extra.O SSH o protocolo utilizado para se conectar de forma seguraem servidores. Por meio de criptografia, ele cria um canal seguroentre duas mquinas. O SSH pode ser utilizado tambm paraexecutar comandos remotamente sem entar no shell da mquina.A configurao do SSH rica, mas para os propsitos deste livro importante aprender uma tcnica de autenticao apenas.Normalmente, quando nos conectamos a uma mquina aparece umpedido de senha.Para automatizar o gerenciamento de configurao precisamosconectar aos servidores sem este pedido de senha de forma segura.Provedores de cloud como a Amazon oferecem esta opo como aprincipal e recomendada para o acesso a servidores. Outros sistemasde gerenciamento de configurao preveem a instalao de umagente nas mquinas. O Ansible s precisa deste acesso por SSH.Na maioria dos provedores, voc encontrar uma opo paraadicionar uma chave de SSH pblica (Public SSH Key). Na AWS, ocaminho das chaves fica dentro do itemEC2no subitemKey Pairs .Voc pode criar suas chaves no console e um arquivo com aextenso.pemser salvo em seu computador. Na DigitalOcean,voc deve adicionar uma chave existente e o gerenciamento diferente da AWS mas o resultado o mesmo: as mquinas criadastero esta chave configurada automaticamente.O painel de gerenciamento e criao de chaves da AWS:1.2 SSH4 1.2 SSHFigura 1.3: Gerenciamento de chaves na AWSO painel de gerenciamento de chaves da DigitalOcean:Figura 1.4: Gerenciamento de chaves na DigitalOceanVamos gerar um par de chaves localmente. No terminal digite:$ ssh-keygen -t rsaNo momento em que o comando perguntar sobre umapassphrase, digite[ENTER]duas vezes sem entrar o passphrase. Oresultado esperado o da prxima figura:1.2 SSH 5Figura 1.5: ssh-keygenNossa chave foi criada com o nomeid_rsa_devopse doisarquivos foram criados dentro do diretriosshno home do seuusurio:id_rsa_devopseid_rsa_devops.pub .Com o par de chaves pblica e privada podemos configurar oacesso remoto a outras mquinas. O arquivo com extenso.pub onico que dever ser copiado para outras mquinas e para painisde configurao. Para configurar a chave na DigitalOcean, siga estetutorial (https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets) a partir do trs. umasequncia de telas indicando onde voc coloca a chave pblicacriada dentro do painel de controle.O teste deste tutorial criar uma mquina e executar ocomando:$ ssh root@ip-da-maquinaA chave ser colocada no usurioroot . Se voc j tem umamquina criada ou gostaria de fazer login com outro usurio queno seja oroot , faa uma copia da sua chave ublica, entre na6 1.2 SSHmquina pelo mtodo normal de conexo com senha e crie umaentrada no arquivoauthorized_keysque fica dentro do diretrio .ssh/com o contedo do arquivo que tem sua chave pblica nonosso caso,id_rsa_devops.pub .O Git um sistema de controle de verso gratuita. Seu site ficaem (http://git-scm.com/). Em termos prticos, sua funo controlar mudanas em repositrios de dados. Eu digo dadosporque ele pode ser usado para outros tipos de dados alm decodigo-fonte de programas.Este livro, por exemplo, foi escrito utilizando um sistemabaseado no (https://www.gitbook.com), que utiliza o Git paracontrolar verses e o progresso do cdigo-fonte de um livro. uma ferramenta simples mas bem pensada, portanto algunsconceitos e ideias podem demorar para fazer sentido para quem nousou um sistema de controle de verso. Mas o tipo de ferramentaque voc aprende muito rpido quando a inclui em seu dia a dia.Uma das formas de utilizar o Git em seus projetos com oGitHub em (https://github.com). Vamos instalar o Git em seusistema operacional. No site do Git e do GitHub voc encontrarinstrues mais detalhadas. Minha recomendao utilizar ogerenciador de pacotes do seu sistema operacional:# Para linux baseado em debian:$ sudo apt-get install git-core# Para linux CentOS/RH$ sudo yum install git# Para MacOS X com homebrew$ brew install git1.3 GIT1.3 GIT 7Para Windows, procure uma verso compatvel no site(http://git-scm.com/downloads). Existem interfaces grficas parautilizar o Git mas vou me manter no terminal. Voc pode utiliz-lasse est acostumado.Aps instalar o Git, execute os comandos a seguir:git config --global user.name "Seu nome"git config --global user.email "[email protected]"O Github um site que fornece repositrios remotos de Git emsua conta sem custo, caso o projeto seja aberto, e com custo casovoc queira repositrios privados. A diferena que repositriosprivados s sero vistos por pessoas que voc autorizar. Para utiliz-lo, v at o site e crie uma conta. O processo simples e voc serredirecionado ao seu painel de controle, que, se no mudou at apublicao deste livro, assim:Figura 1.6: Painel do GithubNeste ponto, precisamos de um par de chaves para o SSH. OGitHub tem uma boa explicao para este procedimento em8 1.3 GIT(https://help.github.com/articles/generating-ssh-keys/) sob aperspectiva de sua configurao. Com o que vimos anteriormenteno deve ser um problema. Voc pode copiar a chave criada( ~/.ssh/id_rsa.pub ) diretamente no passo 4 se j tem sua chavecriada. Se no criou anteriormente, siga este tutorial.Com a chave configurada, vamos criar um novo repositrio.Note um boto chamado+ New Repositorydo lado direito, ao ladodo texto Your repositories. Clique nele.Figura 1.7: Criao de repositrioEu preenchi a caixa embaixo do texto Repository Name com onomeprojeto-simples . Deixei o resto das opes como estavam ecliquei emCreate Repository .1.3 GIT 9Figura 1.8: Repositrio criadoNa barra de endereos do seu browser est o endereo pblicodo seu repositrio. No lugar do usurio gleicon aparecer seuusurio. Como nenhum cdigo foi enviado ainda, a tela que aparece uma ajuda para a configurao de um novo repositrio ou para aativao de um novo remote em um repositrio existente.Remote, na terminologia do Git, um repositrio remoto.Vamos criar um repositrio local que conhece este repositrioremoto e mediante comandos sincroniza ou envia as mudanas paral.Esta troca de dados bilateral. Podemos recuperar mudanasem um repositrio remoto para o repositrio local, por exemploquando um colega tem autorizao ao repositrio e modifica ocdigo. O Git chama estas transferncias de deltas.Abra o terminal do seu sistema operacional e crie um diretriochamadoprojeto-simples :10 1.3 GIT$ mkdir projeto-simplesEntre neste diretrio comcd projeto-simplese use seu editorde textos para criar um arquivo chamadoREADME.md . Neste arquivodigite o texto a seguir:# README do meu projeto-simplesEste projeto apenas um shell script que conta itens unicos nodiretrio /etcCrie um arquivo chamadoitens_unicos.sh :#!/bin/shecho "Itens unicos"ls /etc | cut -d' ' -f 1 | sort | uniq | wc -lVamos seguir as instrues do GitHub, com uma pequenamudana emgit add :git initgit add .git commit -m "first commit"git remote add origin [email protected]:gleicon/projeto-simples.gitgit push -u origin masterNo browser, faa reload da pgina do seu repositrio. Ela deve separecer com a prxima imagem:1.3 GIT 11Este comando mostra o estado atual do repositrio e dasmudanas. A sada deste comando tem uma sesso chamadaUntracked files e o arquivoportas.shestar l com uma indicaodo comandogit add para adicion-lo.$ git add portas.shAgora o git status vai mostrar uma sesso chamada Changes tobe committed com o arquivoportas.she uma indicao de uso dogit reset para reverter a ltima mudana em relao ao estado dorepositrio. Vamos em frente com o comandogit commit .$ git commit -m "novo arquivo"O parmetro-mdo comandogit commit apenas umamensagem que indica o motivo da mudana. Aps o commit, gitstatus mostra uma mensagem indicando que seu branch local estum commit frente do repositrioorigin/mastere sugere o uso do git push .$ git push origin masterAps ogit push , a mensagem do git status Your branch is up-to-date with 'origin/master'. nothing to commit, working directory isclean. Volte pagina do seu repositrio no GitHub e confira amudana.Com este conhecimento, voc j est apto a usar o Git para seusprojetos e a criar mquinas que podem ser acessadas sem senha,com o uso de chave pblica de SSH. Se voc j executa estas tarefasde outra maneira, no tem problema, os captulos a seguir foramescritos de forma a funcionar com uma variao grande dosprocessos descritos.1.4 CONCLUSO14 1.4 CONCLUSOCAPTULO 2O primeiro passo para criar um ambiente de produo oudesenvolvimento ter uma mquina dedicada ou um espao emuma mquina. Com a popularizao de tcnicas de virtualizao, halgum tempo voc pode ter mquinas virtuais executadas em suamquina local.Uma mquina fsica consegue executar mais de uma mquinavirtual em paralelo. Aplicativos como VirtualBox, Parallels eVMWare so utilizados para gerenciar e execut-las.Uma mquina virtual parada nada mais que uma imagem deum disco e metadados que descrevem sua configurao:processador, memria, discos e conexes externas. A mesmamquina em execuo um processo que depende de um scheduler(agendador de tarefas e processos) para coordenar o uso dosrecursos locais.Voc pode gerenciar suas mquinas virtuais diretamente dasinterfaces das aplicaes citadas anteriormente ou pode utilizarbibliotecas e sistemas que abstraem as diferenas entre essasplataformas, com interface consistente para criar, executar, parar emodificar uma mquina virtual. importante na escolha deste sistema levar em conta queexistem diferentes formatos de mquinas virtuais e diferentesVAGRANT2.1 INTRODUOVAGRANT 15sistemas operacionais, portanto, um formato de template e algunsconceitos adicionais que auxiliem na criao destas mquinas sodesejveis.Precisamos tambm de fontes de mquinas virtuais,inicialmente com o sistema operacional original, mas tambm coma possibilidade de ter mquinas customizadas. Aps a criao damquina, queremos executar um passo posterior, que chamaremosde provisionamento, para modificar o sistema operacionalentregue, instalando pacotes e configuraes, alm de instalar suaaplicao e possivelmente salvar aquela verso da mquina virtualpara uso posterior.Para criar e gerenciar os ambientes de mquinas virtuais locais,escolhi o Vagrant (https //www vagrantup com/)Para executar asmquinas virtuais, escolhi o VirtualBox(https://www.virtualbox.org/).O Vagrant gerencia e abstrai provedores de mquinas virtuaislocais e pblicos (VMWare, VirtualBox, Amazon AWS,DigitalOcean, entre outros). Ele tem uma linguagem especfica(DSL) que descreve o ambiente e suas mquinas. Alm disso, elefornece interface para os sistemas de gerenciamento deconfigurao mais comuns como Chef, Puppet, CFEngine e Ansible.Com o VirtualBox, temos uma alternativa de cdigo aberto egrtis para executar as mquinas virtuais localmente. Ele bemintegrado com o Vagrant e tem todas as opes de outrasplataformas. Por um preo mdico voc pode trocar por outroprovedor e ainda assim utilizar a mesma linguagem e interface paragerenciar suas mquinas e ambientes da mesma forma.2.2 CAIXA DE FERRAMENTAS VAGRANT EVIRTUALBOX16 2.2 CAIXA DE FERRAMENTAS VAGRANT E VIRTUALBOXV at o site do VirtualBox em (https://www.virtualbox.org),faa o download da ltima verso estvel para seu sistemaoperacional. Ele deve pedir para instalar algumas extenses quepermitem a execuo de mquinas virtuais e packs de expanso paraoutros dispositivos como USB e volumes de disco. Voc ver quequando executa o VirtualBox ele mostra um menu que permite criarmquinas a partir de imagens ISO ou importar mquinas existentes.Se ocorrer algum problema nesta fase, verifique se o seu sistemaoperacional est atualizado, se a verso do VirtualBox a correta, setem espao em disco e se j no tem uma verso instalada que possaestar em conflito. Leia a documentao de troubleshooting antes depostar um bug e, se encontrar algo novo, avise os desenvolvedores.Neste ponto, voc pode fazer o download de uma ISO deUbuntu neste endereo (http://www.ubuntu.com/download/server)e testar a criao de uma mquina virtual.Execute o VirtualBox e clique emNewno canto superioresquerdo. Um dilogo que pede o nome e o tipo de sistemaoperacional aparecer. Preencha com o nome da sua mquinavirtual, sistema operacional e verso do sistema.2.3 INSTALAO DO VIRTUALBOX2.3 INSTALAO DO VIRTUALBOX 17Figura 2.1: VirtualBox - criao da mquina virtualOs prximos dilogos sero sobre tamanho da memria,tamanho e tipo de disco. Selecione a quantidade de memria de1GB, indique que o disco ser novo, d um nome a ele, diga qual oespao alocado e se cresce dinamicamente. Mantenha as opesdefault em caso de dvida.Sua mquina foi criada mas ainda est vazia. De um duploclique em cima dela e execute (ou Run se estiver em ingls).18 2.3 INSTALAO DO VIRTUALBOXFigura 2.2: VirtualBox - primeira execuo da mquina virtualO dilogo a seguir aparecer, com a tela preta de fundo. Nesteponto, selecione a imagem ISO de que fez download anteriormentee aguarde a instalao do sistema operacional. Finalize a instalaodo Ubuntu (se tiver dvidas, leia a documentao). Marque o tempofinal e quantos minutos levou para instalar esta mquina. Estainformao ser importante para a prxima sesso.2.3 INSTALAO DO VIRTUALBOX 19Figura 2.3: VirtualBox - instalao do sistema operacionalA instalao de mquinas virtuais em provedores deinfraestrutura no diferente desta sequncia. Em alguns casos,algumas opes so predefinidas para poupar o usurio, porexemplo, imagens disponveis.Selecione e faa o download da verso de Vagrant para seusistema operacional em https://vagrantup.com. Leia adocumentao pois h informaes interessantes e sempreatualizadas das plataformas suportadas. Um instalador fornecido evoc tem tudo de que precisa em poucos cliques.Abra seu terminal e digitevagrant help .2.4 INSTALAO DO VAGRANT20 2.4 INSTALAO DO VAGRANTAs opes apresentadas podem variar de acordo com a versoatual do Vagrant. Vamos comear com algumas opes comunspara gerenciar o ciclo de vida da mquina virtual.Criaremos uma mquina usando o Vagrant. No terminal, crieum diretrio chamadotestevm . Entre nele e com seu editor detextos predileto (por exemplo, o Vim) digite o seguinte cdigo emum arquivo chamadoVagrantfile(o cdigo est disponvel em umrepositrio mas eu sugiro que inicialmente voc digite para terfamiliaridade com o que estamos fazendo):# -*- mode: ruby -*-# vi: set ft=ruby :VAGRANTFILE_API_VERSION = "2"Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|config.vm.define "testvm" do |testvm|testvm.vm.box = "ubuntu/trusty64"testvm.vm.network :private_network, ip: "192.168.33.2 "endconfig.vm.provider "virtualbox" do |v|v.customize ["modifyvm", :id, "--memory", "1024"]endendSalve e sada do seu editor predileto ( ESC :wqno Vim) e digitevagrant up no terminal. Aguarde alguns segundos ou minutos deacordo com a configurao de sua mquina. Verifique quantotempo levou para executar estes passos. Para testar, digite ocomandovagrant ssh .Utilize sua mquina normalmente (executartoppara ver osprocessos, examinar o diretrio/etc , instalar algum pacotemanualmente).Dentro da mquina, digitecd /vagrante veja que o seu2.4 INSTALAO DO VAGRANT 21diretrio local foi mapeado como um mount point dentro damquina virtual. Voc pode criar este ponto com outro nome oudeixar de cri-lo de acordo com a configurao doVagrantfile .Digitevagrant destroyno terminal eyquando perguntado sepode realmente destruir esta mquina virtual.Sem considerar a capacidade de sua mquina fsica e suaproficincia digitando cdigo, vimos pelas imagens do passo a passodo VirtualBox que o nmero de passos para criar uma mquinavirtual grande. Some ao tempo do VirtualBox o tempo dedownload da imagem ISO de Ubuntu e o fato de que para apagar amquina virtual ter que se passar por todos os passos novamente etemos um procedimento longo a ser replicado.Aps criar esteVagrantfile , voc pode subir (up) a mesmamquina vrias vezes, em ocasies distintas sem utilizar a interfacedo VirtualBox. possvel versionar este arquivo que descreve suamquina virtual junto com seu cdigo e quando mudar aconfigurao de memria, por exemplo, esta mudana estar nohistrico junto s mudanas de cdigo.Mea quanto tempo leva para subir uma nova mquina virtualde Ubuntu utilizando o Vagrant, agora que a imagem est gravadaem sua mquina. Este cache de imagens importante quando vocest em um estgio em que precisa criar e destruir mquinasrapidamente.At agora, aprendemos a criar um diretrio com um arquivoque descreve uma mquina virtual, a subir, conectar e destru-la( vagrant up ,sshedestroy ). Agora vou explicar o que estearquivo significa.O Vagrant e a sua configurao utilizam Ruby. Existem versesdistintas de APIs e vamos utilizar a verso 2. Dentro de uma22 2.4 INSTALAO DO VAGRANTinstncia da configurao definimos mquinas e suas caractersticas,em um bloco de cdigo Ruby. Veja o mesmo cdigo comentado:Vagrantfile# -*- mode: ruby -*- # vi: set ft=ruby : # as linhas acima indicam a linguagem para o editor de textoVAGRANTFILE_API_VERSION = "2" # verso da API do Vagrant# Este bloco de ruby contm todas as atividades que o Vagrant # deve executar representadas pelo objeto que chamei de configVagrant.configure(VAGRANTFILE_API_VERSION) do |config|# config.vm cria um objeto que descreve uma mquina virtual. # Chamei esta vm de "testevm" e quero utilizar o Ubuntu Trusty# Indiquei que quero um IP privado para esta mquina config.vm.define "testvm" do |testvm|testvm.vm.box = "ubuntu/trusty64"testvm.vm.network :private_network, ip: "192.168.33.2 "end# Este bloco me d acesso ao provedor da mquina virtual # (VirtualBox)# Configurei esta mquina com 1GB de memriaconfig.vm.provider "virtualbox" do |v|v.customize ["modifyvm", :id, "--memory", "1024"]endendNeste arquivo, descrevi minha mquina virtual e disse quegostaria de usar o Ubuntu Trusty (14.04) de 64 bits. O Vagrantfornece algumas imagens e tem uma comunidade que permite aosseus usurios compartilharem imagens customizadas. interessantenotar que ele cria uma biblioteca local com as imagens que vocutiliza, portanto, o custo de fazer download da imagem amortizado entre as vezes em que voc sobe e destri suas mquinasvirtuais.O nome das imagens no ecossistema do Vagrant box ou boxesno plural. O box que utilizei chamado de base box, por ser uma2.4 INSTALAO DO VAGRANT 23das imagens que eles mantm s com o sistema operacional.Alm de subir e destruir sua mquina virtual, voc podedesativ-la usando o comandovagrant halt . Leia a documentaodo Vagrant sobre criar suas prprias mquinas. Neste ponto, seuexerccio explorar a mquina que criamos e customiz-la deacordo com seu gosto.Comvagrant up , suba a mquina e conecte comvagrant ssh .Com cuidado para ter certeza de que est conectado e que no vaiexecutar um comando em sua mquina fsica local, execute asequncia de comandos:$ sudo apt-get update$ sudo apt-get install nginxAbra seu browser local e aponte para o endereohttp://192.168.33.2. Voc deve ver a mensagem de boas-vindas donginx. Volte ao terminal e digite:$ sudo -s$ echo "boa cabelo" > /usr/share/nginx/html/index.htmlVolte ao seu browser e d reload na pagina, deve aparecer otexto "boa cabelo". Imagine outras configuraes que gostaria defazer nesta mquina alm de colocar um web server com um ndiceservindo a frase "boa cabelo". Execute e crie uma mquinapersonalizada para isso.Seu prximo passo modificar oVagrantfilepara utilizar estamquina. Se errar em alguma configurao, lembre-se que possveldestruir a mquina e recri-la do zero. Teste outros sistemasoperacionais e imagens criadas para fins distintos em(https://atlas.hashicorp.com/boxes/search).Criar a mquina rpido e ter que instalar o nginx manualmente melhor do que criar usando o mtodo manual na interface do24 2.4 INSTALAO DO VAGRANTVirtualBox, mas ainda pode melhorar.O Vagrant implementa o conceito de provisionador com driverspara quase todos os sistemas de gerenciamento de configuraoexistentes. Estes sistemas vo de receitas simples para instalarpacotes at agentes que verificam a integridade de arquivos deconfigurao e variveis do sistema.Vamos utilizar um driver de provisionamento do Vagrant quepermite que um arquivo com comandos do shell seja executado logoaps a criao da mquina virtual. Crie o arquivowebserver.shnomesmo diretrio e digite os seguintes comandos:#!/bin/bashecho "Atualizando repositrios"sudo apt-get updateecho "Instalando o nginx"sudo apt-get -y install nginxSalve o arquivo e edite o arquivoVagrantfilepara ativar oprovisionador. Ele deve ficar como a listagem a seguir:# -*- mode: ruby -*-# vi: set ft=ruby :VAGRANTFILE_API_VERSION = "2"Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|config.vm.define "testvm" do |testvm|testvm.vm.box = "ubuntu/trusty64"testvm.vm.network :private_network, ip: "192.168.33.2 "testvm.vm.provision "shell", path: "webserver.sh" endconfig.vm.provider "virtualbox" do |v|v.customize ["modifyvm", :id, "--memory", "1024"]endendA linhatestvm.vm.provision "shell", path: webserver.shdiz2.4 INSTALAO DO VAGRANT 25para o Vagrant que para aquela mquina virtual deve ser usado odriver de provisionamento de shell script e passa como parmetro oarquivo com comandos que criamos.Destrua e crie a mquina virtual novamente comvagrantdestroye crie comvagrant up . Observe a sada no terminal e faa omesmo teste no browser, sem a necessidade de se conectar porssh para executar o comando que instala o nginx.Vamos instalar o PHP5 na mquina. Modifique o arquivo webserver.shde acordo com a listagem a seguir:#!/bin/bashecho "Atualizando repositrios"sudo apt-get updateecho "Instalando o nginx"sudo apt-get -y install nginxecho "Instalando o PHP"sudo apt-get install -y php5-fpmNeste ponto, no precisamos destruir e recriar a mquina paraexecutar novamente o provisionamento. Contamos com o fato deque o gerenciador de pacotes no instalar um pacote duas vezes.Poderamos executar o mesmo script, que s o PHP seria instalado.O Vagrant oferece um comando que ativa somente a fase doprovisionamento vagrant provision. Executevagrant provisionemseu terminal e observe a execuo do script.At este ponto vimos como criar uma descrio de mquinavirtual com o Vagrant e os seguintes comandos:$ vagrant up$ vagrant ssh$ vagrant destroy$ vagrant halt$ vagrant provisionCom estes comandos, conseguimos gerenciar de forma rpida elimpa as mquinas virtuais criadas de acordo com oVagrantfile .26 2.4 INSTALAO DO VAGRANTNote que eles s funcionaro dentro do diretrio em que o Vagrantfileest. Execute o comandols -larthe veja que foicriado um diretrio chamado.vagrantque contm todos os dadosdo ciclo de vida e provisionamento da mquina virtual.Voc j conhece as ferramentas de gerenciamento de mquinasvirtuais instaladas em sua mquina e j consegue us-las para tarefasbsicas. Explore a documentao para entender como elas podemfacilitar seu trabalho at com provedores reais de IaaS. Participe daslistas de discusses e procure Vagrantfiles no GitHub(https://github.com) para ter novas ideias de como utiliz-lo.Explore novas imagens de sistemas operacionais.O Vagrant abstrai muitas tarefas de gerenciamento de mquinascomo automao da troca de chaves de SSH, criao de usurios emontagem de diretrios. Ele permite provisionadores plugveis e acomposio simplificada de clusters com mquinas de configuraesdistintas. O que vimos at agora do Vagrant suficiente paracontinuarmos com o Ansible no prximo captulo.2.5 CONCLUSO2.5 CONCLUSO 27CAPTULO 3Neste captulo, vamos retomar o exemplo do captulo anteriorusando Ansible. O Ansible um sistema de automao deconfigurao feito em Python, que permite descreverprocedimentos em arquivos no formatoYAMLque so reproduzidosutilizando SSH em mquinas remotas.Existem outras ferramentas desta categoria que executamlocalmente e que fornecem servidores para o gerenciamento dedados remotamente, como CHEF, Puppet e CFEngine.Vamos utilizar o Ansible localmente sem seu servidor de dados,o Ansible Tower. O Ansible vem com bibliotecas completas paraquase todas as tarefas alm de uma linguagem de template. Almdas tarefas dentro de um servidor, o Ansible fornece mdulos paraprovisionamento de mquinas e aplicaes remotas. Provisionar ojargo para instalar e configurar itens de infraestrutura e plataformacomo mquinas, bancos de dados e balanceadores de carga.No captulo anterior, terminamos com umVagrantfilee um shell scriptpara instalar nginx e PHP. Vamos traduzirliteralmente para o Ansible e progressivamente vamos utilizar seusmdulos para fazer do jeito certo (tm). Posteriormente utilizaremoso Ansible para criar mquinas virtuais em provedores e gerenciar ociclo de vida delas.Poderamos ter continuado a usarshell scriptpara configurarANSIBLE28 ANSIBLEnossas mquinas, mas sistemas como o Ansible implementamtarefas com uma caracterstica importante: idempotncia. Aidempotncia uma propriedade que, aplicada ao gerenciamento deconfigurao, garante que as operaes tero o mesmo resultadoindependentemente do momento em que sero aplicadas. A criaode sua mquina utilizando este conjunto de configuraes sempreter o resultado previsvel.Temos que instalar o Ansible em nossa mquina local. Ele notem nenhum agente ou biblioteca que deva ser instalado namquina virtual. O Ansible feito em Python e funciona em muitasplataformas. A maneira como se comunica com as mquinasvirtuais ou fsicas configurada por intermdio de SSH.Se o seu sistema operacional for MacOS X, use o homebrew.Abra o terminal e digitebrew install ansible . No usa homebrew?Use:$ sudo easy_install pip$ sudo pip install ansiblePara Linux, siga a documentao em(http://docs.ansible.com/intro_installation.html#latest-releases-via-apt-ubuntu). Vou reproduzir o procedimento para Ubuntu:$ sudo apt-get install software-properties-common$ sudo apt-add-repository ppa:ansible/ansible$ sudo apt-get update$ sudo apt-get install ansiblePara testar se foi instalado, digite no terminalansible-playbook-h . Deve aparecer a ajuda do Ansible.3.1 INSTALAO3.2 A CONFIGURAO DO ANSIBLE E O3.1 INSTALAO 29Entre no diretriotestvme digite o arquivo a seguir com onome dewebserver.yml :- hosts: allsudo: Trueuser: vagranttasks:- name: "Atualiza pacotes"shell: sudo apt-get update- name: "Instala o nginx"shell: sudo apt-get -y install nginxEste um arquivo no formatoyaml . Use dois espaos como tab( set ts=2no Vim). Preste ateno no sinal de:(dois pontos)aps os atributos. O Ansible vai reclamar se no entender o arquivoe voc poder consert-lo.Sempre confira a indentao e os dois pontos aps os atributos.Confira tambm o hfen antes dos atributos quando necessrio. Aformatao simples mas importante. YAML um formato que serve para serializao e transmisso dedados. Ele composto de palavras-chaves separadas de um valorpor:(dois pontos). Seus dados podem ser chaves e valores, listasde chaves e valores e dicionrios. Por exemplo:Uma lista:- gato- cachorro- limoDicionrio:nome: gleiconsobrenome: moraeslinux: sim por favorOs valores podem ser alfanumricos. A combinao segue oFORMATO YAML30 3.2 A CONFIGURAO DO ANSIBLE E O FORMATO YAMLpadro detabspace=2(cada nvel separado por 2 espaos). umformato simples e o Ansible utiliza um subset de tudo que ele poderepresentar. Voc pode usar o YAML Lint em(http://www.yamllint.com/) para verificar seu playbook sem ter queexecut-lo.Vamos ver mais sobre o arquivo de configurao neste e nosprximos captulos. O nome correto deste arquivo playbook , poiso Ansible tem um arquivo de configurao de suas propriedadesque no dependem de um host especfico.Abra o arquivoVagrantfilee modifique-o para que fique deacordo com a listagem a seguir:# -*- mode: ruby -*-# vi: set ft=ruby :VAGRANTFILE_API_VERSION = "2"Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|config.vm.define "testvm" do |testvm|testvm.vm.box = "ubuntu/trusty64"testvm.vm.network :private_network, ip: "192.168.33.2 "testvm.vm.provision "ansible" do |ansible|ansible.playbook = "webserver.yml"ansible.verbose = "vvv"endendconfig.vm.provider "virtualbox" do |v|v.customize ["modifyvm", :id, "--memory", "1024"]endendA diferena entre os dois arquivos o bloco a seguir:3.3 ANSIBLE E VAGRANT3.3 ANSIBLE E VAGRANT 31testvm.vm.provision "ansible" do |ansible|ansible.playbook = "webserver.yml"ansible.verbose = "vvv"endA definio de mquina virtual detestvmtem um atributo quedefine um provisionador. No captulo anterior, usei umshellscriptpara instalar o nginx. Com esta mudana, o Vagrant utilizaro Ansible como provisionador com o playbookwebserver.yml .Deixei o atributoverbosedo Ansible com o valorvvvpara indicarque quero todas as mensagens enviadas para o console.Vamos examinar o arquivowebserver.ymllinha a linha eadicionar a instalao do PHP. A primeira linha que contm oatributohosts o nvel mais alto do playbook. Ela define em qualmaquina ou grupo de mquinas a descrio ser aplicada. O valor allindica que pode ser aplicado a qualquer uma definida noarquivo que contm os endereos das mquinas. Como o Vagrantexecuta o Ansible indiretamente, ele fornece este arquivo.Se executarmos o playbook diretamente no terminal sem oVagrant, teramos que passar um arquivo de inventrio (em ingls, inventory fileouhosts.ini ). O formato deste arquivo simples:[grupo1]10.0.0.110.0.0.210.0.0.3[grupo2]10.0.0.410.0.0.5Se o valor do atributohostsfossegrupo1e estivssemosexecutando o Ansible manualmente:$ ansible-playbook -i hosts_file webserver.ymlO playbook seria aplicado apenas nas mquinas com IPs10.0.0.1, 10.0.0.2, 10.0.0.3. Se o valor fosseall , ele seria aplicado32 3.3 ANSIBLE E VAGRANTem todas as mquinas. Este o caso utilizado caso voc tenha umamquina virtual em algum provedor e queira executar o playbook.Basta se certificar de que seu usurio tem autenticao por chavede SSH ( ssh usuario@maquinadeve logar sem pedir senha). Ajuste onome do usurio no arquivo do Ansible e execute o playbook comoindicado anteriormente.Voc no precisar se preocupar com este arquivo agora, masposteriormente vamos utilizar o mesmo playbook paradesenvolvimento local e deploy em uma VPS e este arquivo ser util.sudo: Trueuser: vagrantEstes atributos indicam que o Ansible pode usar sudo e ousurio de conexo na mquina o usuriovagrant . Esteparmetro tambm ser modificado para instalao em uma VPSpara seu usurio ou o usurio default da distribuio.tasks:- name: "Atualiza pacotes"shell: sudo apt-get update- name: "Instala o nginx"shell: sudo apt-get -y install nginxO atributotasks uma lista de tarefas que o Ansible vaiexecutar. Ela composta por nome/ao. Neste arquivo, utilizamosuma task chamadashellque executa o comando em seguidadiretamente no terminal da mquina.Agora, executevagrant upe observe a instalao do Ansible atreceber um status final semelhante a este:PLAY RECAP ******************************************************testvm : ok=3changed=2unreachable=0failed=0 PLAY RECAP o resumo da aplicao do playbook. Para o host testvmduas tasks ( ok=3 ) foram executadas. Uma delas causou3.3 ANSIBLE E VAGRANT 33uma mudana no host ( changed=2 ). Durante a execuo doprovisionamento cada uma das tasks foi executada e indicada peloAnsible, alm do passo chamado GATHERING FACTS.Como nossoVagrantfiletem um indicador de nvel deverbosidade do Ansible configurado, voc viu bem mais do que isso.Voc pode remover esta opo quando terminar um playbook poisela s til para debug durante desenvolvimento.Se executarmos o provisionamento novamente na mesmamquina comvagrant provision , teremos a mesma sada:PLAY RECAP ******************************************************testvm : ok=3changed=2unreachable=0failed=0O Ansible executou a mesma sequncia de comandos nas duasvezes. A taskshell uma das mais simples do Ansible e tem poucocontrole de estado, o que no contribui com a idempotncia entre asrodadas do provisionamento. Nesta configurao, o controle executar as duas tasks com sucesso sem guardar um estado atual oulev-lo em conta. Vamos melhorar isso e aprender como utilizarmelhor os mdulos que o Ansible oferece.Toda task uma funo de um mdulo do Ansible. Os mdulosque vm na instalao padro ele so chamados de Core Modules.Voc pode construir seus mdulos utilizando a linguagem Python eestender o Ansible.Vamos refatorar nosso playbook para utilizar um mdulo corechamadoapt_module(http://docs.ansible.com/apt_module.html)em vez do mduloshell . O mduloshell til para automatizarmuitas tarefas, mas voc vai encontrar mdulos especializados doAnsible que cuidam da consistncia da tarefa e criam estados paramanter a idempotncia. Atualize o arquivowebserver.ymlde3.4 REFATORAO34 3.4 REFATORAOacordo com a listagem a seguir.- hosts: allsudo: Trueuser: vagranttasks:- name: "Atualiza pacotes e instala nginx"apt: name=nginx state=latest update_cache=yes install_recommends=yesReduzimos as duas tasks para uma que utiliza o mduloaptediz para o Ansible instalar o nginx no ltimo release presente norepositrio. Um dos atributos desta task indicar que um update nocache do gerenciador de pacotes deve executado.Outro atributo que utilizaremos a indicao de que asdependncias recomendadas devem ser instaladasautomaticamente. Note que, utilizando o mduloshell , eu preciseipedir explicitamente pela atualizao do repositrio e tambmadicionar o parmetro-yao comandoapt-get installpara evitarque a task ficasse esperando uma entrada do usurio.O Ansible tambm fornece um mdulo para o gerenciador depacotes yum (http://docs.ansible.com/yum_module.html) ediretivas condicionais que podem ser usadas para detectar o sistemaoperacional e distribuies de Linux. Veja como declarar a mesmatask para instalar nginx para duas famlias de distribuies de Linuxutilizando o condicionalwhene variveis internas do Ansible:- name: Install the nginx packagesyum: name={{ item }} state=presentwith_items: redhat_pkgwhen: ansible_os_family == "RedHat"- name: Install the nginx packagesapt: name={{ item }} state=present update_cache=yeswith_items: ubuntu_pkgenvironment: envwhen: ansible_os_family == "Debian"Podemos testar o novowebserver.ymlcomvagrant upou3.4 REFATORAO 35apenasvagrant provisioncaso sua mquina virtual ainda estejasendo executada. Aps a primeira execuo dovagrant upou vagrant provision , executevagrant provisionnovamente e analisea sada no console. O PLAY RECAP deve ser diferente.Execute o provisionamento em seguida para notar a diferenaentre a primeira e a segunda execuo. Esta uma maneira simplesde verificar a idempotncia do playbook: na segunda rodada, oatributochangeddeve ser 0.Apsvagrant up :PLAY RECAP ******************************************************testvm : ok=2changed=1unreachable=0failed=0Apsvagrant provision :PLAY RECAP ******************************************************testvm : ok=2changed=0unreachable=0failed=0Este mdulo nos deu mais controle e um estado: a interpretaodo gerenciador de pacotes. Existem mdulos para RPM e outrasdistribuies de Linux alm da possibilidade de automatizar ainstalao ou gerao de um pacote a partir de um repositrio decdigo.O parmetrostateconfigurado paralatestdescreve doisestados: o pacote deve estar instalado e deve ser a ltima versodisponvel. Se no momento da execuo estas condies foremverdadeiras, nenhuma ao ser tomada. Se alguma delas for falsa, aao correta ser executada utilizando o gerenciador de pacotes apt .Neste captulo, vimos como o Ansible funciona e como sair deum provisionamento baseado emshell scriptpara o3.5 CONCLUSO36 3.5 CONCLUSOprovisionamento baseado no Ansible.Explore a documentao e mdulos do Ansible para entendercomo a biblioteca que vem com ele aborda tarefas de administraode sistemas como instalao de pacotes, arquivos de configurao ediferentes distribuies de sistemas operacionais.Procure mais informaes sobre outros sistemas degerenciamento de configurao j citados: CFEngine(http://cfengine.com/), Puppet (https://puppetlabs.com/) e CHEF(https://www.chef.io/chef/). Entenda como a arquitetura delesinterfere na sua arquitetura de sistemas atual e qual ocomprometimento de tempo e estrutura est envolvido na adoode um sistema mais completo e complexo.3.5 CONCLUSO 37tasks:- name: "Atualiza pacotes e instala nginx"apt: name=nginx state=latest update_cache=yes install_recommends=yesEstes arquivos so as verses finais do captulo anterior.Seguindo a nossa lista, coloquei a instalao de PHP-FPM e MySQL.Uma das maneiras de utilizar o PHP com nginx utilizar a versoFPM do PHP. uma implementao alternativa do protocoloFastCGI que j tem um gerenciador de processos. A interface entreo servidor HTTP e o interpretador ser feita por um Unix DomainSocket que o PHP-FPM disponibiliza.Nossa prxima tarefa criar um arquivo de configurao nonginx para um site que saiba intepretar arquivos com extenso PHP.Vou explicar como isso fica no nginx e posteriormente comofaremos o Ansible montar o arquivo de configurao correto. Parafacilitar, vou criar odocument rootno lugar onde o WordPressficar instalado,/opt/wordpress .server {listen 80;server_nameblog localhost;access_log/var/log/nginx/blog.access.log;root /opt/wordpress;indexindex.html index.htm index.php;location / {try_files $uri $uri/ /index.html;}location ~ \.php$ {try_files $uri =404;fastcgi_pass unix:/var/run/php5-fpm.sock;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;}}40 4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESSO nginx pode servir vrios sites. A definio de cada um delefica em uma diretiva chamada server. No Ubuntu, a estrutura deconfigurao fica em/etc/nginxe os sites dentro de /etc/nginx/sites-availablecom um link dentro de /etc/nginx/sites-enabledquando ativo.A prxima tarefa transportar a configurao do nosso site donginx para esta estrutura. Vamos criar trs tasks: criar o */opt/wordpress , copiar a configurao e ativar o novo site. Parafacilitar, vamos remover o site default e reiniciar o nginx.Para testar estes passos, vamos colocar uma task que vai criarum arquivo simples chamadotest.phpcom o comando php_info() . Nosso teste abrir o IP 192.168.33.2 owser e vera tela de informaes sobre o PHP impressa.

- hosts: allsudo: Trueuser: vagranttasks:- name: "Atualiza pacotes e instala nginx"apt: name=nginx state=latest update_cache=yes install_recommends=yes- name: "Instala PHP-FPM"apt: name=php5-fpm state=latest install_recommends=yes- name: "Instala MySQL"apt: name=mysql-server state=latest install_recommends=yes- name: "Cria diretrio /opt/wordpress"shell: mkdir -p /opt/wordpress- name: "Copia configurao de blog.nginx para /etc/nginx/sites-available/blog"copy: src=blog.nginx dest=/etc/nginx/sites-available/blog - name: "Ativa o site"shell: ln -fs /etc/nginx/sites-available/blog /etc/nginx/sites-enabled/blog4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS 41- name: "Apaga o site default"shell: rm -f /etc/nginx/sites-enabled/default- name: "Reinicia o NGINX"shell: service nginx restart- name: "Cria uma pagina de teste do PHP"copy: src=test.php dest=/opt/wordpressNeste playbook, introduzi uma nova task, chamadacopyquecopia arquivos locais para o host. Tambm voltei a utilizar a task shellcomo o modo mais simples de executar uma tarefa.Vamos executar o fluxo completo. Se sua mquina virtual estcriada, usevagrant destroypara apag-la evagrant upparaexecutar nossa instalao. Abra seu browser e aponte parahttp://192.168.33.2/test.php.42 4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESSFigura 4.1: test.phpPLAY RECAPPLAY RECAP ******************************************************blogvm : ok=10 changed=9unreachable=0failed=0Se o teste falhar ou o seu PLAY RECAP estiver diferente, observea sada do provisionamento por erros. A sada dotest.phppode serum pouco diferente dependendo de atualizaes de bibliotecas oucomponentes do sistema operacional.Vamos colocar o WordPress neste playbook e configur-lo como MySQL como banco de dados. As distribuies de Linux vm com4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS 43pacotes do WordPress, mas vamos baixar a verso latest do site parailustrar como instalar um software diretamente do cdigo-fonte. Sevoc navegar at (https://wordpress.org) na sesso de downloadsver que o ltimo release sempre tem o nome de latest.A URL https://wordpress.org/latest.tar.gz a que utilizaremospara fazer o download do WordPress. Tambm vamos utilizarmdulos do Ansible em substituio s tarefas de criar um linksimblico e apagar um diretrio.Introduzi novas diretivas, comounarchive ,url_get , mdulosdo MySQL e novos usos do mdulofile . Temos o conceito devariveisvarse de templates.Vamos experimentar o playbook antes da explicao completa.Se voc estiver executando diretamente do repositrio, pode pularpara depois da listagem, pois vamos ver algumas tasks especiais ediscutir como refatorar este playbook.A listagem a seguir instala o Wordpress completo em umamquina virtual:- hosts: allsudo: Trueuser: vagrantvars:mysql_root_password: rootmysql_wp_user: wordpressmysql_wp_password: wordpresswordpress_db_name: wordpresstasks:- name: "Atualiza pacotes e instala nginx"apt: name=nginx state=latest update_cache=yes install_recommends=yes- name: "Instala PHP-FPM"apt: name=php5-fpm state=latest install_recommends=yes- name: "Instala MySQL"apt: name=mysql-server state=latest install_recommends=yes44 4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS- name: "Instala Extenses de MySQL para PHP"apt: name=php5-mysql state=latest install_recommends=yes- name: "Instala biblioteca python-mysqldb"apt: name=python-mysqldb state=latest install_recommends=yes- name: "Copia configurao de blog.nginx para /etc/nginx/sites-available/blog"copy: src=blog.nginx dest=/etc/nginx/sites-available/blog - name: "Apaga o site default"file: path=/etc/nginx/sites-enabled/default state=absent- name: "Ativa o site"file: src=/etc/nginx/sites-available/blog dest=/etc/nginx/sites-enabled/blog state=link- name: "Reinicia NGINX"service: name=nginx state=restarted- name: "Cria /opt/wordpress"file: dest=/opt/wordpress mode=755 state=directory owner=www-data- name: "Download do Wordpress"get_url: url=https://wordpress.org/latest.tar.gz dest=/tmp/latest.tar.gz- name: "Abre wordpress em /opt/wordpress"unarchive: src=/tmp/latest.tar.gz dest=/opt copy=no - name: "Corrige permisses"file: path=/opt/wordpress recurse=yes owner=www-data group=www-data- name: "Inicia MySQL"service: name=mysql state=started enabled=true- name: "Cria .my.cnf"template: src=my.cnf.j2 dest=~/.my.cnf mode=0600- name: "Cria senha de root para root@mysql"mysql_user: name=rootpassword="{{ mysql_root_password }}"check_implicit_admin=yespriv="*.*:ALL,GRANT"state=present4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS 45host="{{ item }}"with_items:- "{{ ansible_hostname }}"- 127.0.0.1- *1- localhost- name: "Cria wordpress database"mysql_db: name=wordpress login_user=rootlogin_password="{{ mysql_root_password }}"state=present- name: "Cria usurio wordpress"mysql_user: name="{{ mysql_wp_user }}"password="{{ mysql_wp_password}}"priv="{{ wordpress_db_name }}".*:ALLcheck_implicit_admin=yeslogin_user=rootlogin_password="{{ mysql_root_password }}"host="{{ item }}"state=presentwith_items:- "{{ ansible_hostname }}"- 127.0.0.1- *1- localhostAponte seu browser para http://192.168.33.2 e configure oWordPress. Estes passos tambm podem ser automatizados mas ficacomo exerccio.Este playbook contm uma sesso nova chamadavars. Estasvariveis podem ser usadas no prprio playbook, como nas tasks deMySQL ou em arquivos externos chamados templates. A sintaxe simples baseada no engine de templates Jinja2.De todos os recursos do Jinja2 s utilizaremos a substituio devariveis entre chaves duplas, mas a linguagem possui desvioscondicionais, loops e muitos recursos para criar templatesinteligentes. Eu recomendo ler a documentao, mas tambmmanter os templates simples: template module(http://docs.ansible.com/template_module.html).46 4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESSAlgumas tasks tm uma construo semelhante ao exemplo aseguir:- name: "Cria usurio wordpress"mysql_user: name="{{ mysql_wp_user }}"password="{{ mysql_wp_password}}"priv="{{ wordpress_db_name }}".*:ALLcheck_implicit_admin=yeslogin_user=rootlogin_password="{{ mysql_root_password }}"state=presenthost="{{ item }}"with_items:- "{{ ansible_hostname }}"- 127.0.0.1- *1- localhostEsta estrutura permite que passemos uma lista de itens qual atask ser aplicada. Estes itens podem ser locais comwith_itemsouprovenientes de um template ou varivel. So teis para manter ocdigo modular sem repeties desnecessrias. Vale a regra demanter o playbook simples sem utilizar estruturas complexas para oloop das tasks. Neste caso, os itens na sesso with_items so hostsutilizados para a criao do usurio. Os direitos (GRANTS) dosusurios do MySQL so especficos para cada host ou IP de origemda conexo (o mesmo usurio pode ter permisso de criar tabelas apartir do localhost, mas s ler, se vindo de outro host).As tasks de MySQL deste playbook foram estruturadasassumindo que a instalao do pacote domysql_servercria umusurio root sem senha.Para que o template tenha comportamento idempotente emtodas as execues, seguimos a recomendao da documentao doAnsible: instalamos um mdulo de Python para MySQL, criamosuma senha para o usurio root e um arquivo chamado.my.cnfquemora no diretrio/root . Existem outras maneiras de trabalharcom autenticao e tokens que so mais seguras, que voc pode4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS 47pesquisar na documentao do Ansible.O playbook funciona e poderamos parar a para instalar umblog. Tudo est na mesma mquina, voc pode subir e descerquantas vezes quiser, modificar parmetros at ficar a contento eposteriormente fazer o deploy em uma mquina de produo.Vamos refatorar este playbook para introduzir a ideia de roles.Um playbook tem roles (papis em portugus) que agem sobrepartes especficas do sistema operacional. Esta mudana contribuipara a modularidade e reaproveitamento de cdigo: um role podeser utilizado em vrios playbooks. A refatorao contribui tambmpara a legibilidade do playbook.Vamos separar nosso playbook em 5 roles:common(sistemaoperacional e tarefas genricas),nginx ,php ,mysqlewordpress .Vamos separar tambm as variveis e criar um modelo de variveispara evitar que coloquemos senhas e tokens de acesso por enganoem um repositrio de cdigo. A mudana no introduz tarefasdiferentes, apenas muda a organizao dos arquivos. A rvore dediretrios ficar assim: |-- .gitignore |-- blog.yml |-- roles | |-- common | | |-- tasks | | | |-- main.yml | | |-- templates | |-- mysql | | |-- tasks | | | |-- main.yml | | |-- templates | | | |-- my.cnf.j2 | |-- nginx | | |-- tasks | | | |-- main.ymlREFATORAO48 4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS | | |-- templates | | | |-- blog.nginx | |-- php | | |-- tasks | | | |-- main.yml | | |-- templates | |-- wordpress | | |-- tasks | | | |-- main.yml | | |-- templates |-- Vagrantfile |-- vars | |-- mysql.yml | |-- mysql.yml.distAgora temos um diretrio chamadorolescom cincosubdiretrios, cada um representando um elemento quedescrevemos anteriormente. Dentro de cada diretrio de role temosos subdiretriostasketemplates . As tasks moram dentro doarquivomain.yml .Voc pode dividir em quantos arquivos quiser para organizar,mas neste modelo usaremos apenas omain.yml . Dentro dosubdiretriotemplatesficam os arquivos.j2ou arquivos quevamos copiar para o servidor.O diretriovarsna raiz do projeto tem arquivos com variveisque sero utilizadas pelos roles. Eu criei omysql.yml.distque omodelo do arquivo. No.gitignorecoloquei propositalmente ocaminhovars/mysql.ymlpara evitar que minhas credenciais sejamversionadas. Voc vai copiar omysql.yml.distparamysql.yml dentro do mesmo diretrio e complet-lo com suas credenciais esenhas.O arquivoblog.ymlficou bem simples e agora utiliza a diretiva roles :- hosts: allsudo: Trueuser: vagrantvars_files:4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS 49- vars/mysql.ymlroles:- common- mysql- php- nginx- wordpressO exerccio deste captulo mais uma refatorao. Existe umacondio que faz com que o rolewordpressdependa do role common : a criao do diretrio/opt/wordpress .Voc poderia utilizar o rolewordpressem outro playbook masprecisaria criar este diretrio.A melhor forma de remover esta dependncia criar umavarivel para o diretrio destino, substituir todas as ocorrncias de"/opt/wordpress" por ela e em cada role criar o diretrio caso ele noexista.Neste captulo, vimos novas tasks do Ansible e um exemplocompleto de como fazer o deploy de uma aplicao em umamquina virtual. Se voc imaginar que no lugar do WordPress vocacessou o repositrio do seu cdigo, pode ver que no difcil criarum ambiente portvel para desenvolvimento e a estrutura paradeploy com o que vimos at aqui. interessante notar que a progresso do desenvolvimento doplaybook semelhante ao processo que usamos para programar.At refatorao fizemos e, como os arquivos esto estruturados,poderamos ter versionado com Git ou outro controle de verso.Voc poderia ter verses de software ou mquinas sendo executadaspara testes de regresso ou performance rapidamente.CONCLUSO50 4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESSA ltima refatorao que fizemos organizou o playbook em rolesque podem ser reaproveitados em outros playbooks, assim como oscomponentes que o Ansible prov como mdulos e playbooks doAnsible Galaxy (http://galaxy.ansible.com).4.1 EXPANDINDO NOSSO PLAYBOOK UM BLOG COM WORDPRESS 51CAPTULO 5Este captulo ousado mas simples: vamos aproveitar o que vimosanteriormente para melhorar nosso playbook e usar o Vagrant paracriar uma estrutura que tem mais de uma mquina. Antes vamosentender um pouco mais a tcnica de proxy reverso com o nginx ecomo este padro de arquitetura pode ser usado para diferentesinterpretadores e linguagens.O exemplo deste captulo e do anterior servem para outrasaplicaes que utilizam PHP e MySQL. O que precisaria sermodificado para instalar um CMS (Content Management System)como o Joomla (http://www.joomla.org/)? E para outras linguagense plataformas ?Nestes casos, devemos voltar a ateno ao passo deconfigurao: se depende de um arquivo com os dados dasmquinas instaladas, se precisa de passos completados pelo browserou se podemos fornecer um arquivo com as configuraes corretas,sem interveno manual.A maneira como configuramos o nginx chamada de proxyPROXY REVERSO EWORDPRESS EM DUASMQUINAS5.1 NGINX E PROXY REVERSO52 PROXY REVERSO E WORDPRESS EM DUAS MQUINASreverso. Se em vez de executar o PHP-FPM uma aplicao emPython estivesse ouvindo em uma porta local, no mudaria muito oplaybook.Vamos construir uma aplicao simples que ouve na porta10000 e responde uma API de echo: ela recebe umPOSTcom oparmetromsge imprime o valor de volta. Se o mtodo chamadoforGET , um formulrio com uma caixa de texto aparecer. um exemplo simples mas demonstra o conceito de proxyreverso e de outro interpretador. Este exemplo est no diretrio python-nginxdo repositrio com o nome dehttp_server.py :#!/usr/bin/pythonimport SimpleHTTPServerimport SocketServerimport cgiimport socketPORT=10000class ReuseAddrTCPServer(SocketServer.TCPServer):def server_bind(self):self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.socket.bind(self.server_address)class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):def do_GET(self):self.wfile.write("")self.wfile.write("")self.wfile.write("
")self.wfile.write("")returndef do_POST(self):self.send_response(200)self.end_headers()form = cgi.FieldStorage(5.1 NGINX E PROXY REVERSO 53fp=self.rfile,headers=self.headers,environ={'REQUEST_METHOD':'POST', 'CONTENT_TYPE':self.headers['Content-Type'], })for field in form.keys():self.wfile.write('\t%s=%s\n' % (field, form[field].value))returnReuseAddrTCPServer(("", PORT), ServerHandler).serve_forever()Este cdigo cria um servidor HTTP com as bibliotecas padrodo Python, ouve na porta 10000 e s responde a requests HTTP dotipoGETePOST . Para test-lo, abra dois terminais; em um delesexecute o comando:$ python http_server.pyNo outro, o comandocurlpara mandar um requestPOSTparanosso servidor:$ curl -X POST -d "msg=aaaa&oi=123" http://localhost:10000No terminal em que o servidor est sendo executado, a sadadeve ser parecida com:$ curl -X POST -d "msg=aaaa&oi=123" http://localhost:10000msg=aaaaoi=123$O servidor no tem o mnimo necessrio para uma boaaplicao web como logs, monitorao, arquivo de configuraopara dados como a porta e o endereo, mas servir para o propsitode demonstrar a mudana em nosso playbook para utilizar umaaplicao Python e o nginx como proxy reverso.OVagrantfiledeste exemplo parecido com o do captuloanterior: apenas uma mquina virtual ser criada e o arquivo54 5.1 NGINX E PROXY REVERSO web.ymlser executado. Dentro desta mquina, teremos o nginx,Python e nosso programa. Ele ser executado dentro de umprograma chamado supervisord.O supervisord um programa que cuida da execuo de outrosprogramas: redireciona a sada padro para um arquivo de log emonitora sua execuo para reiniciar caso o script pare deresponder.Dentro desta mquina, nossohttp_server.pyser executado evai ouvir na porta 10000 delocalhost .O nginx ter um site que vai ouvir no IP 192.168.33.10 e quefar o request para este servio de backend. Ele vai gerenciar asconexes vindas de usurios e as respostas vindas do backend.Este oweb.yml :- hosts: allsudo: Trueuser: vagrantvars_files:- vars/mysql.ymlroles:- common- nginx- appPara organizar o deploy da aplicao, criei um role chamado app . Este role cria um diretrio/opt/app , copia ohttp_server.py para l, configura osupervisorde inicia a aplicao. Este oarquivotasks/main.ymldo role app- name: "Cria o diretrio /opt/app se ele no existe"file: dest=/opt/app mode=755 state=directory owner=www-data- name: "Copia o arquivo http_server.py para /opt/app"copy: src=http_server.py dest=/opt/app/- name: "Cria a entrada app para o supervisord"template: src=app.conf dest=/etc/supervisor/conf.d/5.1 NGINX E PROXY REVERSO 55- name: "Reinicia supervisord"service: name=supervisor state=restarted- name: "Inicia a aplicao"supervisorctl: name=app state=startedNo rolecommon , instalamos o pacotesupervisordpara suportara tasksupervisorctle o controle da aplicao. Nos passosanteriores implementamos o que j discutimos.A configurao do nginx mudou um pouco:server {listen 80;server_nameapp localhost;access_log/var/log/nginx/app.access.log;root /opt/app;indexindex.html index.htm index.php;location / {proxy_passhttp://127.0.0.1:10000/;proxy_redirectoff;proxy_set_headerHost$host;proxy_set_headerX-Real-IP $remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;client_max_body_size5M;client_body_buffer_size 5M;proxy_connect_timeout 30;proxy_send_timeout30;proxy_read_timeout30;proxy_buffer_size 16k;proxy_buffers 16 128k;proxy_busy_buffers_size 512k;proxy_temp_file_write_size512k;}}Suba a mquina comvagrant upe acesse http://192/168.33.10em seu browser. Digite algo e clique emsubmit . Repita os testescom ocurlno terminal:$ curl -vvv -X POST -d "msg=oie" http://192.168.33.10 /56 5.1 NGINX E PROXY REVERSOEntre na mquina virtual comvagrant sshe teste o serviolocalmente:$ curl -vvv -X POST -d "msg=oie" http://localhost:10000/O resultado deve ser semelhante, mas com os headers dabiblioteca SimpleHTTPServer do Python. Neste teste, voc acessou obackend diretamente, antes do nginx. Analise os logs em /var/log/nginx/e o log da aplicao em/var/log/app.log ,redirecionado pelo supervisord.No o objetivo fazer uma anlise das opes de configuraodo nginx, basta dizer que a diretivaproxy_passredireciona o trafegoque chega na URI/para o backend.As opes em seguida so relacionadas a HTTP HEADERS quedevem ser repassados para a aplicao de backend e o tamanho dosbuffers disponveis. Com o nginx possvel fazer proxy, loadbalancing e cache alm de servir pginas HTTP. Procure maisinformaes em (http://nginx.org/en/docs/).O motivo deste desvio foi tcnica que utilizamos para fastcgi eHTTP em aplicaes de backend.O objetivo agora simples: quero que meu banco de dados fiqueem uma mquina e o WordPress em outra. Quero rodar esteambiente localmente com o Vagrant, mas quero que o playbookesteja pronto para provisionar em duas mquinas externas.Vamos usar oVagrantfilepara criar as mquinas e aplicar oprovisionamento correto em cada uma. Dividiremos nossos rolespara indicar o que pertence ao banco de dados e o que pertence aowebserver com WordPress. A documentao do Vagrant em(http://docs.vagrantup.com/v2/multi-machine/) sobre isso bem5.2 WORDPRESS EM DUAS MQUINAS5.2 WORDPRESS EM DUAS MQUINAS 57clara. Adaptando ao nossoVagrantfile , fica assim:# -*- mode: ruby -*-# vi: set ft=ruby :VAGRANTFILE_API_VERSION = "2"Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|config.vm.define "web" do |webvm|webvm.vm.box = "ubuntu/trusty64"webvm.vm.network :private_network, ip: "192.168.33.2 "webvm.vm.provision "ansible" do |ansible|ansible.playbook = "blog.yml"ansible.verbose = "vvv"ansible.groups = {"web" => ["192.168.33.2 "],"db" =>["192.168.33.2 "],}ansible.limit = "web"endendconfig.vm.define "db" do |dbvm|dbvm.vm.box = "ubuntu/trusty64"dbvm.vm.network :private_network, ip: "192.168.33.2 "dbvm.vm.provision "ansible" do |ansible|ansible.playbook = "blog.yml"ansible.verbose = "vvv"ansible.groups = {"web" => ["192.168.33.2 "],"db" =>["192.168.33.2 "], }ansible.limit = "db"endendconfig.vm.provider "virtualbox" do |v|v.customize ["modifyvm", :id, "--memory", "1024"]endendAs mudanas noVagrantfileforam simples: duas sesses para58 5.2 WORDPRESS EM DUAS MQUINAScriar mquinas virtuais distintas. Como os componentes destaarquitetura so independentes, uma mquina web e uma de bancode dados, criei dois grupos e programaticamente usei o Vagrantpara indicar ao Ansible o que cada uma representa. No momento deconfigurar o WordPress pela interface web, coloque o IP192.168.33.2 no campo hostname. a nica mudana em relaoao setup anterior.Aps a configurao e o primeiro post no WordPress, use vagrant ssh dbevagrant ssh webpara inspecionar as duasmquinas. Em um setup com mais de uma mquina o, Vagrant usao nome que demos paraconfig.definecomo identificador paraseus comandos. Para provisionar novamente s a mquina debanco,vagrant provision db ; para se conectar mquina defrontendvagrant ssh web ; o mesmo paradestroy ,halteup .Poderamos automatizar totalmente a configurao doWordPress sem utilizar a interface web, com templates de arquivosno formato correto com as variveis. uma tarefa relativamentesimples, s precisa de um pouco de engenharia reversa: entre namaquina de frontend e transforme owp-config.phpem umtemplate. Para emular o final da configurao, voc deve olhar nobanco de dados criado pelo WordPress e preencher seu banco dedados de acordo. Existem playbooks para WordPress bemcompletos que oferecem esta opo.Precisei modificar um pouco o rolemysqlpara que ele trocasseo arquivo de configurao do MySQL por um que oua em todas asinterfaces de rede da mquina (originalmente, o MySQL s ouve nainterface 127.0.0.1) e tambm uma correo para que o usurioWordPress tenha permisso para conectar de outras mquinas.Poderamos ter usado o Ansible para corrigir apenas esta linhano arquivo original mas minha recomendao versionar seusarquivos de configurao da maneira que precisam ser no final e5.2 WORDPRESS EM DUAS MQUINAS 59variar parmetros utilizando templates. Desta forma, dados comoIPs, senhas, tokens e at contedo de banco de dados so facilmenteidentificados caso outra pessoa precise utilizar seu playbook.Ao executarvagrant up , os dois blocos de cdigo soexecutados em srie com os respectivos provisionadores. Oplaybook mudou tambm: tem duas sesses marcadas pelo atributo host . Se fssemos instalar em duas mquinas virtuais emprovedores externos, teramos que preencher um arquivo hosts.inicom dois grupos como no exemplo a seguir:[web]IP da VPS1[db]IP da VPS2Executaramos, portanto:$ ansible-playbook -i hosts.ini blog.ymlSe a mquina estiver configurada corretamente para aceitarconexo utilizando chave SSH sem senha, o Ansible conectar emcada uma das mquinas e executar os playbooks.O exerccio que proponho antes de prosseguir escolher umprovedor de infraestrutura e instalar este playbook em duasmquinas virtuais fora da sua mquina local. As informaes ataqui so suficientes, voc deve criar as duas mquinas manualmentee criar umhosts.inicom os endereos IPs corretos.Para fazer isso na DigitalOcean, siga os passos do primeirocaptulo para criar uma conta, v ao painel e crie uma chave SSH. ADigitalOcean tem um bom preo entre provedores de mquinasvirtuais e no difcil conseguir um cupom de descontos. Procure o5.3 INSTALANDO SEU WORDPRESS EMMQUINAS VIRTUAIS.60 5.3 INSTALANDO SEU WORDPRESS EM MQUINAS VIRTUAIS.item your settings no seu profile e escolha o tab security(https://cloud.digitalocean.com/settings/security). Neste itemprocure SSH Keys e crie uma nova chave. Caso tenha dvidas paracriar uma chave SSH, consulte o mesmo captulo.Figura 5.1: Painel de controle da DigitalOceanCom a chave criada, vamos um fazer um playbook que cria duasmquinas com Ubuntu 14.04 e instalawebedbem cada uma delasusando o Ansible. O Ansible tem mdulos que interagem comprovedores de servio usando suas APIs.A DigitalOcean lanou uma nova API em abril de 2015,portanto seu mdulo ainda no havia sido atualizado no Ansible ata data de edio deste livro. Vou indicar as duas maneiras de acess-la, mas o exemplo utilizar a V1 (verso 1) da API.No painel da DigitalOcean v at o item API:5.3 INSTALANDO SEU WORDPRESS EM MQUINAS VIRTUAIS. 61Figura 5.2: API da DigitalOceanPara a verso 1.0 da API, clique no link View API v1. Apareceruma tela para a criao de um par de Client ID e Apy Key. Clique em Generate New Keye copie os valores apresentados:Figura 5.3: API verso 1 da DigitalOceanEstes dois valores sero importantes para o provisionamento.Exporte os dois em variveis de ambiente:$ export DO_CLIENT_ID=$ export DO_API_KEY= node,'seeds' => nodes.join(","),'cluster_name' => cluster_name,}end# Para cada item da lista de servidores (servers) uma vmVagrant.configure(VAGRANTFILE_API_VERSION) do |config|servers.each do |server|config.vm.define server['hostname'] do |cfg|cfg.vm.box = "ubuntu/trusty64"cfg.vm.host_name = server['name']cfg.vm.network :private_network, ip: server['ip']cfg.vm.provision "ansible" do |ansible|ansible.extra_vars = {74 6.1 VAGRANT E CASSANDRAcluster_name: server["cluster_name"],seeds: server["seeds"],listen_address: server['ip'],rpc_address: server['ip']}ansible.verbose = 'vvvv'ansible.playbook = "cassandra.yml"endcfg.vm.provider "virtualbox" do |v|v.customize ["modifyvm", :id, "--memory", "2048"]endendendendA listanodescontm 3 endereos IP, com base nos quais vamosinstruir o Vagrant a criar e provisionar estes ns. Para cadamquina, vamos passar as variveis que o role de instalao doCassandra vai utilizar para configurar cada n.O atributoextra_varsdo Ansible aceita um dicionrio (Hashem Ruby) com valores que sero repassados como variveis doAnsible. O bloco dentro deservers.eachrepete o processo decriao e provisionamento de mquinas virtuais para cada item de servers .A preparao inicial da listaserversusa nodes para criarnomes para cada um dos elementos do cluster (node0, node1 enode2), d um endereo IP para cada n e cria o parmetroseeds com todos os IPs, alm do nome do cluster.Esta a configurao mnima para o Cassandra, entre ascentenas de itens que podem ser modificados. Com isso, criamosum cluster de 3 mquinas. No instalei o opscenter nem outrasferramentas necessrias para executar o Cassandra em ambiente deproduo, apenas o banco de dados.Esta configurao fica pesada em um computador normal, poisas mquinas precisam de pelo menos 2GB de memria para evitar6.1 VAGRANT E CASSANDRA 75que o kernel do Linux rode o OOM Killer (out of memory killer).Poderamos habilitar o swap mas sairia do escopo doprovisionamento. um exerccio que eu sugiro: melhorar aconfigurao destas mquinas virtuais e criar as tasks no playbook.O teste para cada n simples:vagrant ssh node[0..2]eexecute o comandonodetool statuspara ver o estado do n. Esteplaybook completo pode ser encontrado no repositrio do livro.Para instalar este cluster fora do Vagrant vamos precisar dasvariveis para cada n. Veja como fica o inventriohosts.iniparaeste caso, assumindo que cada um dos IPs uma maquina pronta ecom o SSH configurado para autenticar sem senha por chavepblica:[cassandra]192.168.33.100 cluster_name="Super Cluster" seeds="192.168.33.100,192.168.33.101,192.168.33.102" listen_address="192.168.33.100" rpc_address="192.168.33.100" 192.168.33.101 cluster_name="Super Cluster" seeds="192.168.33.100,192.168.33.101,192.168.33.102" listen_address="192.168.33.101" rpc_address="192.168.33.101"192.168.33.102 cluster_name="Super Cluster" seeds="192.168.33.100,192.168.33.101,192.168.33.102" listen_address="192.168.33.102" rpc_address="192.168.33.102"Para executar o Ansible nas trs mquinas:ansible-playbook -i hosts.ini cassandra.ymlVoc poderia gerar dinamicamente este arquivo vindo de umsistema de gerenciamento de mquinas ou de configurao. OAnsible chama isso de dynamic inventory e um dos principaisrecursos do Ansible Tower, a soluo centralizada de gerenciamentoque o Ansible oferece.Existem plugins para gerenciar o inventrio dinmico sem usarAnsible Tower. Escolhi a AWS para testar este playbook. Vamosinstalar 3 mquinas para o Cassandra, mas antes vamos examinar76 6.1 VAGRANT E CASSANDRAsomente o provisionamento.O Ansible tem o cdigo e mdulos necessrios para utilizar aAPI da AWS. Mas como provisionador ele deve manter umconjunto de informaes sobre o inventrio de mquinas queestamos utilizando. A AWS faz isso do lado da API e precisamos demeios de recuperar esta informao em um formato que o Ansiblecompreenda.Precisamos do plugin de inventrio dinmico para EC2instalado. Este plugin nada mais que um programa que facilita acomunicao com a API do EC2 e substitui ohosts.ini . Para queele funcione, voc vai precisar de uma conta na AWS, credenciais( AWS_ACCESS_KEY_IDeAWS_SECRET_ACCESS_KEY ) e a chavepblica/privada de SSH configurada. As credenciais so encontradasno menu IAM do painel da AWS. Vamos seguir as instrues doAnsible:$ sudo pip install boto # or use your favorite package manager$ curl https://raw.githubusercontent.com/ansible/ansible/devel/plugins/inventory/ec2.py > ec2.py$ chmod +x ec2.py$ curl https://raw.githubusercontent.com/ansible/ansible/devel/plugins/inventory/ec2.ini > ec2.ini$ export AWS_ACCESS_KEY_ID=seu access key id$ export AWS_SECRET_ACCESS_KEY=seu secret access key$ ./ec2.py --helpAnote o nome da sua chave na AWS. Se no tiver chave, noconsole, menu EC2, v ao item Key Pairs e crie uma. Um arquivocom extenso.pemser salvo em sua mquina. A minha tem onome deaws_devel , portanto o arquivo se chamaaws_devel.pem .Para usar esta chave com o SSH, copie para seu diretrio ~/.ssh/e mude as permisses para 0600 comchmod 06006.2 PROVISIONAMENTO NA AWS6.2 PROVISIONAMENTO NA AWS 77~/.ssh/aws_devel.pem . Quando a mquina estiver instalada, testecomssh -i ~/,ssh/aws_devel.pem ubuntu@ip_publico , trocando aws_devel.pempelo nome do arquivo com a sua chave.Dentro do diretriogroup_varscriamos um arquivo chamado allcom os dados de chave SSH, regio, nome da imagem, VPC(Virtual Private Cluster), subnet e tipo de instncia. O diretrio group_varscontm arquivos com o nome dos grupos eallparavariveis que se aplicam para todos os grupos.key_name: aws_develaws_region: us-east-1ami_id: ami-9instance_type: t2.microvpc_id: vpc-XXXXXXXXsubnet_id: subnet-XXXXXXXEsta a descrio para mquinas do EC2 na regio us-east-1,sistema operacional Ubuntu 14.04 t2.micro (a t1.micro apenas PVe a imagem que queremos usar HVM. So tipos de virtualizaoque impactam na performance e tamanho da mquina). Vamosprecisar de uma VPC criada e uma subnet atrelada a esta VPC.Existe um wizard para isso e provavelmente voc j est usandoVPC e subnets.Para se familiarizar com o Ansible como provisionador, crieidois playbooks que executam a tarefa que j fizemos anteriormente:instalar uma mquina com nginx. Vamos fazer um desvio aqui paraexecutar este playbook e conferir se tudo est configuradocorretamente. Execute o comando:$ ansible-playbook -vvvv -i aws_hosts.ini cria_maquina.yml --private-key ~/.ssh/aws_devel.pemO parmetro--private-keydeve apontar para seu arquivo coma chave pblica, o parmetro-vvvvserve para nos mostrar todos ospassos que esto sendo executados. O arquivoaws_hosts.ini aponta para localhost, pois a maioria das tarefas sero executadas a78 6.2 PROVISIONAMENTO NA AWSpartir da mquina local.A construo deste playbook interessante pois tem duassesses: o provisionamento da mquina na AWS e oprovisionamento na mquina j criada. Introduzimos tambm ataskwait_forpara esperar a criao da mquina virtual.Como a criao de mquinas virtuais remota, o tempo podevariar mais do que a criao local com o Vagrant. Esta primeirasesso substitui algumas tarefas do Vagrant ao coletar dados damquina criada e repassar para a segunda sesso, que contm a taskque instala o nginx.Vamos examinar cada task do provisionamento:# Cria uma mquina- hosts: localhostconnection: localgather_facts: Falsetasks:- name: "Cria security group"ec2_group:name: cassandra_groupdescription: "Cassandra Security group"vpc_id: "{{vpc_id}}"region: "{{aws_region}}"rules:- proto: tcptype: sshfrom_port: 22to_port: 22cidr_ip: 0.0.0.0/0- proto: tcptype: httpfrom_port: 80to_port: 80cidr_ip: 0.0.0.0/0rules_egress:- proto: alltype: allcidr_ip: 0.0.0.0/0register: ec2_firewallO incio deste playbook indica que estas tarefas sero executadas6.2 PROVISIONAMENTO NA AWS 79localmente. Com a ajuda da biblioteca boto em Python, o Ansiblepode usar a API da AWS para criar mquinas e outros servios. Opassogather_facts: Falseinstrui o Ansible a no coletarinformaes do ambiente local.A primeira task cria um Security Group chamado cassandra_groupno VPC e regio indicadas.Para este grupo so criadas algumas regras de firewall paraliberar o acesso a SSH e HTTP. Egress e Ingress so palavrasindicadas para descrever o sentido dos pacotes de redes. Egresssignifica pacotes de rede que saem da mquina. Por ltimo, adiretivaregistercoloca o resultado desta tarefa em uma varivelglobal do playbook que pode ser acessada por outras tasks.- name: "Cria uma instancia no EC2"local_action: ec2 key_name="{{key_name}}"vpc_subnet_id="{{subnet_id}}"region="{{aws_region}}"group_id="{{ec2_firewall.group_id}}"instance_type="{{instance_type}}"image="{{ami_id}}"wait=yesassign_public_ip=yesregister: ec2Nesta tarefa, criamos a mquina virtual. Criei uma mquina ealm dos dados de chave SSH ( key_name ),subnet_id , regio daAWS ( region ), imagem e tipo de instncia, passei ogroup_idquefoi gravado dentro da varivelec2_firewallvinda da tarefaanterior. Esta instncia ter um IP vlido ( assign_public_ip=yes ).A task est configurada para esperar a concluso da chamada daAPI comwait=yes . Se estivssemos em um VPC que usa umamquina de gateway, poderamos criar as mquinas sem IP vlido eutilizar apenas a rede interna do VPC. Registramos o resultado datask na varivelec2 .- name: "Adiciona host ao grupo instancias"80 6.2 PROVISIONAMENTO NA AWSadd_host: hostname={{ item.public_ip }} groupname=instanciaswith_items: ec2.instances- name: "Espera confirmao antes de seguir, verificando a porta 22"wait_for: port=22 host="{{ item.public_ip }}" search_regex=OpenSSH delay=10with_items: ec2.instancesA varivel ec2 serve para a prxima taskAdiciona host ao grupoinstanciascriar uma lista de mquinas que posteriormenteusaremos como hosts para a segunda parte do playbook. importante entender que este inventrio no existe em umarquivo pois ainda estamos criando as mquinas. O artifcio paratanto usar um auxiliar externo, como oec2.pye tambm utilizaros dados que so retornados ao final de cada task.A ltima task da primeira parte uma precauo para esperar acriao e boot da mquina virtual. Ela apenas espera que a porta 22(SSH) esteja aberta e que devolva uma string com "OpenSSH" apster uma conexo. Pode testar diretamente do seu console com um telnet ip_da_maquina 22e voc ver que antes do trfegocriptografado o servidor SSH manda um breve cabealho com estastring.# Usando a mquina que criamos, vamos instalar o NGINX.- hosts: instanciassudo: Trueuser: ubuntugather_facts: Truetasks:- name: "Atualiza pacotes e instala nginx"apt: name=nginx state=latest update_cache=yes install_recommends=yesNa segunda parte tudo ficou simples: usamos a varivel instanciasque criamos a partir do IP pblico vindo do resultadoda execuo da taskCria uma instancia no EC2e utilizamos comoum playbook normal. Este o inventrio dinmico dentro da6.2 PROVISIONAMENTO NA AWS 81mesma rodada do playbook.Se voc executar o playbook novamente, ele no agir sobreinstncias criadas em outras execues. O papel doec2.pyficarmais claro ao analisarmos o playbook de remoo de mquina.Antes de execut-lo, faa:$ ./ec2.py --listO retorno do comando ser umJSONcom todas as mquinascriadas e seus status. Explore as outras opes deste comandotrocando--listpor--help . A maneira de fazer um playbook"lembrar" do estado de execues anteriores para a AWS usar o ec2.pycomo seuhosts.ini(inventory file). Vamos utiliz-lo pararemover a mquina que criamos. Antes de apag-la, teste o SSH e owebserver. Para se conectar mquina use:$ ssh -i ~/.ssh/aws_devel.pem ubuntu@ip_publico_da_sua_mquinaExecute novamente o programaec2.py( ./ec2.py ) e examinesua saida. O nome de grupo que colocamos anteriormente aparececom o prefixosecurity_group . Esta sesso interpretada como umasesso de inventrio esttico. Portanto, conseguimos executar tasksnas mquinas que esto neste grupo. o que a primeira parte doplaybook faz. Vamos remover a mquina antes e posteriormenteexaminar o playbook.$ ansible-playbook -i ./ec2.py remove_maquina.yml- hosts: security_group_cassandra_groupconnection: localgather_facts: Falsetasks:- name: Remove a instncialocal_action:module: ec2state: 'absent'region: '{{aws_region}}'instance_ids: '{{ec2_id}}'- hosts: localhost82 6.2 PROVISIONAMENTO NA AWSconnection: localgather_facts: Falsetasks:- name: Remove o security group cassandra_grouplocal_action:description: "Cassandra group"module: ec2_groupname: security_group_cassandra_groupregion: "{{aws_region}}"state: 'absent'Neste playbook, inicialmente removemos a mquina eposteriormente osecurity group . Poderamos no t-lo removidomas optei por deixar este ciclo completo. Note que as variveis queesto no arquivogroups_var/allso aplicadas s tarefas tambm,pois pertencem a todos os grupos e todos playbooks deste diretrio.Em ambas as tarefas usamos o estado (state)absentparaindicar que aquela descrio indica um item que deve estar ausente(removido) ao final da tarefa. Esta semntica se repete para todas astarefas do Ansible: instalao de pacote, movimentao de arquivos,templates e provisionamento.Agora estamos prontos para retomar o provisionamento doCassandra. Examine o playbook para ver como integrei o quetnhamos para uso com o Vagrant com o que aprendemos sobreEC2. Criei um playbook separado para facilitar a comparao. Esteplaybook vai parecer grande pois ter as funes deprovisionamento e configurao de ambiente, mas com o que vimosno parecer complexo.A descrio de nossa tarefa combinar os playbooks anteriores,criar uma configurao de firewall que permita que os ns deCassandra se comuniquem, criar mquinas um pouco maiores paraque o sistema consiga ser executado e fazer com que as mquinas se6.3 CASSANDRA E AWS6.3 CASSANDRA E AWS 83comuniquem pela rede interna. Temos que extrair e organizar asinformaes das instncias criadas para satisfazer os requerimentosdas variveis dos roles que vamos usar.Este playbook est no mesmo repositrio com o nome de cassandra_aws.yml . No esquea de desligar suas mquinas quandoterminar de us-las pois o custo pode ser alto.Usei instncias menores do que as recomendadas para aoperao segura de um cluster Cassandra pois meu objetivo mostrar o provisionamento. Vamos examinar ohosts.inidoprovisionamento local:[cassandra]192.168.33.100 cluster_name="Super Cluster" seeds="192.168.33.100,192.168.33.101,192.168.33.102" listen_address="192.168.33.100" rpc_address="192.168.33.100" 192.168.33.101 cluster_name="Super Cluster"seeds="192.168.33.100,192.168.33.101,192.168.33.102" listen_address="192.168.33.101" rpc_address="192.168.33.101" 192.168.33.102 cluster_name="Super Cluster" seeds="192.168.33.100,192.168.33.101,192.168.33.102" listen_address="192.168.33.102" rpc_address="192.168.33.102"Temos que criar as variveiscluster_name ,seeds , listen_addresserpc_address , cada mquina virtual utilizando osdados de criao de cada instncia. Criamos uma task paraacumular seeds e modifiquei o cdigo do rolecassandra , notemplatecassandra.yaml.j2usei uma diretiva do Jinja2 para criarum valor default baseado em uma varivel do inventrio do Ansible.Comparando antes e depois:Antes: listen_address: {{ listen_address }}Depois: listen_address: {{ listen_address | default(ansible_default_ipv4.address) }}Para instncias com IP interno, como a AWS em um VPC namesma regio, esta configurao junto com o EC2Snitch so ascorretas. Pode ser diferente em outros provedores que forneamapenas uma interface com IP vlido ou entre regies da AWS com o84 6.3 CASSANDRA E AWSEC2MultiRegionSnitch que demanda mudanas de regras na firewalle no VPC. Aproveitei a mesma tcnica para a definio de Snitch,com um valor default para oSimpleSnitch .endpoint_snitch: {{ snitch | default(SimpleSnitch) }}Para este cluster vamos criar trs instncias, portanto criei a taskde criao com o parmetro extra*count=3* . O Ansible consegueprovisionar as mquinas virtuais em paralelo. Vamos mudar oparmetrosnitchparaEC2Snitch . Snitch no Cassandra ocomponente que ajuda a gerenciar a infraestrutura. Nosso playbooktem uma jogada ninja para montar o seeds: criamos um grupo dehosts com os IPs privados e posteriormente o utilizamos para criar oparmetro seeds.- name: "Cria instancias no EC2 para o cluster"local_action: ec2 key_name="{{key_name}}"count="{{ vm_count }}"vpc_subnet_id="{{subnet_id}}"region="{{aws_region}}"group_id="{{ec2_firewall.group_id}}"instance_type="{{instance_type}}"image="{{ami_id}}"wait=yesassign_public_ip=yesregister: ec2- name: "Adiciona host ao grupo instancias"add_host: hostname={{ item.public_ip }} groupname=instanciaswith_items: ec2.instances- name: "Cria a varivel seeds com os IPs privados das instncias"add_host: hostname={{ item.private_ip}} groupname=private_ipswith_items: ec2.instancesvars:- java_versions: oracle-java7-installer- cluster_name: "Cassandra Cluster AWS"- snitch: EC2Snitch- seeds: "{{ groups['private_ips'] | join(',') }}"Utilizamos o template engine Jinja2 embutido no Ansible para6.3 CASSANDRA E AWS 85acessar o grupo chamadoprivate_ipspreenchido na taskCria avarivel seeds com os IPs privados das instncias . Estes I