Testando sua infraestrutura de forma rápida e fácil

Escrito por Diogo Silva, Rafael Lima e Leonardo Marquezini

Introdução

É muito comum termos aplicações inteiras sendo executadas a partir da nuvem, onde serviços e recursos estão sempre disponíveis. Esse cenário é extremamente interessante para redução de custos e para prover às organizações agilidade frente às mudanças. Entretanto, é também comum a necessidade de diferentes atributos e configurações em ambientes com essas características. Por exemplo, podemos ter os mais diversos sistemas operacionais e bibliotecas instalados nesses recursos, obrigando a equipe de desenvolvimento a utilizar uma abordagem eficaz para verificar rapidamente tais configurações.

Existem muitas técnicas para garantir o funcionamento e a saúde de uma infraestrutura. Isso se torna ainda mais fácil e rápido se a infraestrutura for criada utilizando código. Ferramentas como Vagrant, Docker e Chefpermitem esse tipo de abordagem programática. Sendo assim, é que claro que boas práticas de desenvolvimento de software podem ser utilizadas na criação de uma infraestrutura. Testar essa infraestrutura é uma dessas práticas.

Iremos nos concentrar em dois tipos de verificações: verificações a nível de código e verificações a nível de integração. As verificações a nível de código são verificações onde o código que descreve a infraestrutura é inspecionado a procura de problemas relacionados com a descrição do ambiente. Isso acontece de forma simulada, não havendo a criação de nenhuma máquina ou ambiente real. Um exemplo de ferramenta que realiza esse tipo de análise é o ChefSpec. Já as verificações a nível de integração são realizadas em instâncias reais, permitindo que verificações em uma infraestrutura já previamente criada sejam realizadas. A importância desse tipo de verificação é garantir que servidores e recursos estejam funcionando exatamente como o esperado. Um exemplo de ferramenta que realiza esse tipo de análise é o ServerSpec.

Um possível problema

Imagine o seguinte cenário: uma grande empresa do ramo de software gostaria de prover aos seus times uma stack de desenvolvimento na nuvem. Essa stack consiste em ferramentas para análise e desenvolvimento de software, como aplicações de gerenciamento de projetos, controle de versão e a execução de builds automáticas. Nesse contexto, cada time necessita de uma stack própria. Por exemplo, digamos que o time BRAVO possui uma stack própria com três ferramentas: uma ferramenta para integração contínua, uma ferramenta de controle de versão e uma ferramenta para gerenciamento do projeto. Já o time ALPHA possui uma stack própria com duas ferramentas: uma ferramenta para integração contínua e uma ferramenta de controle de versão. Cada ferramenta citada anteriormente é executada em uma instância remota.

Como garantir que essas instâncias estão funcionando corretamente? Como ter certeza que essas máquinas e ferramentas estão trabalhando em conjunto sem erros? Quais serviços estão sendo executados em cada stack? Esses serviços estão rodando na porta correta? Temos alguma porta incorretamente configurada, abrindo assim uma brecha de segurança?

Uma possível solução

O ServerSpec pode nos ajudar nesse contexto. O ServerSpec é uma DSLbaseada em Ruby e RSpec. A flexibilidade do Ruby e a clareza do RSpec fazem com que o ServerSpec seja considerada uma ferramenta poderosa na hora de verificar um comportamento em uma infraestrutura.

Por exemplo, o ServerSpec pode facilmente verificar se uma máquina remota possui uma determinada configuração, executando comandos diretamente na máquina para determinar o estado da instância em questão.

O ServerSpec trabalha com o conceito de especificações. Cada especificação contém um conjunto de cenários que explicitam um comportamento esperado. Por exemplo, imagine que um serviço de monitoramento é executado em uma porta específica de uma máquina remota. Utilizando a DSL do ServerSpec é fácil descrever esse cenário, acessar a máquina e verificar se o serviço em questão está sendo executado corretamente.

Vagrant? Docker? O ServerSpec provê suporte para essas tecnologias. Por exemplo, arquivos de configuração de ferramentas como o Docker podem ser escritos utilizando TDD e ServerSpec. Além disso, é sempre interessante lembrar que essas especificações podem servir posteriormente para documentar todo o comportamento de uma infraestrutura, gerando uma documentação viva.

Instalação e Configuração

Para instalar o ServerSpec, é necessário primeiramente um ambiente de desenvolvimento Ruby. Se o bundler estiver sendo utilizado no ambiente, a simples adição da biblioteca ao Gemfile do projeto e a execução do comando bundle irá permitir o uso ferramenta.

Para começar a explorar o ServerSpec, o comando serverspec-init pode ser utilizado. Esse comando irá criar automaticamente arquivos com exemplos de uso da ferramenta. Além disso, as especificações criadas anteriormente poderão ser executadas utilizando uma tarefa do Rake.

Utilização da ferramenta

No que diz respeito a funcionalidades, considerando que o ServerSpec trabalha com o conceito de cenários, é muito fácil especificar um determinado comportamento da infraestrutura. É possível ainda detalhar se uma verificação deve ser executada somente se um cenário for verdadeiro.

Por exemplo, voltando ao cenário inicial da empresa que precisa prover aos seus times uma stack de desenvolvimento. Digamos que precisamos verificar se a ferramenta de integração contínua está sendo executada e rodando na porta 80. Entretanto, essa verificação só fará sentido se o sistema operacional for Ubuntu. Utilizando o ServerSpec isso é uma tarefa simples de realizar:

Nesse exemplo, verificamos se o serviço do Jenkins está habilitado e rodando. Além disso, como mencionado anteriormente, essa verificação só será realizada se o sistema operacional da máquina remota for Ubuntu. Por último, verificamos se a porta 80 está aberta. Caso a ideia seja testar se um determinado pacote esteja instalado na máquina remota, o ServerSpec já provê uma funcionalidade para verificação da presença de pacotes:

Agora, imagine que temos que garantir a existência de um arquivo na instância que executa a ferramenta de gerenciamento de projetos. Considerando que o ServerSpec suporta esse tipo de verificação, é muito simples proceder com essa validação:

Caso precisássemos verificar a existência de uma determinada string no arquivo, o código seria:

Além disso, o que aconteceria se precisássemos verificar que a instância de integração contínua é capaz de se comunicar com a instância de controle de versão? Basicamente, precisamos ter certeza que um determinado host está acessível em uma instância. Para isso, o seguinte código seria necessário:

Conclusões

Apesar de ser uma poderosa DSL, o ServerSpec não é uma solução perfeita. Não existem soluções perfeitas, certo? O ServerSpec é uma ferramenta que provê flexibilidade na hora de testar sua infraestrutura. Além disso, como todas as verificações são executadas em instâncias reais, os testes escritos com o ServerSpec podem demorar para serem executados, especialmente se compararmos com outros tipos de testes. Pensando em uma pipeline, essas verificações dependem que a infraestrutura seja criada primeiro para depois serem executadas, e criar uma instância para depois configurá-la pode levar tempo. Variáveis como largura de banda e tempo de resposta em uma rede são pontos que devem ser levados em consideração.

É muito importante entender quando utilizar uma ferramenta como essa. Uma análise criteriosa na aplicação e na infraestrutura deve ser o aspecto mais importante antes da utilização de qualquer ferramenta. Por exemplo: Como minha infraestrutura é criada? Existe algum tipo de automação que realiza essa tarefa? Quantas instâncias são necessárias? Como essas instâncias se comunicam? De quanto em quanto tempo essa infraestrutura deve ser atualizada? Essas são perguntas que podem ajudar na hora de escolher uma ferramenta e na hora de definir uma estratégia de testes. A pirâmide de testes também pode nos ajudar na tarefa de determinar uma estratégia de testes para uma infraestrutura. Entretanto, mesmo que a proporção da pirâmide de testes seja respeitada, é sempre aconselhável garantir que validações com instâncias reais aconteçam, exercitando assim os cenários mais importantes.

Além disso, é interessante refletir sobre a granularidade dos cenários que gostaríamos de cobrir com o ServerSpec. Ou melhor, qual tipo de verificação é mais recomendada quando utilizamos o ServerSpec? Pequenas alterações em arquivos devem ser validadas com uma ferramenta como essa? De acordo com a nossa experiência, acreditamos que o ServerSpec deve ser utilizado para verificar o funcionamento e comunicação de integrações. A comunicação entre um host e outro está ocorrendo de forma adequada? Um pacote que está instalado em uma máquina remota está sendo executando de acordo? O foco deve ser a saúde geral da infraestrutura e não validações menores e mais específicas.

Por fim, recomendamos que diferentes tipos de ferramenta sejam utilizados para diferentes níveis de teste. Por exemplo, ferramentas que validam o código da infraestrutura, como o ChefSpec, podem ser utilizadas em conjunto com o ServerSpec. Considerando que a execução de scripts utilizando ChefSpec é mais rápida, o ChefSpec pode vir a ser o primeiro passo de verificações em uma suíte de testes, fornecendo assim um feedback simples e direto. Além disso, é uma ferramenta para auxiliar no TDD. Posteriormente, validações com ferramentas de integração, como o ServerSpec, podem ser realizadas.

Muito obrigado a Juraci Vieira e Rafael Gomes pela leitura e sugestões durante a escrita do texto.

Leituras recomendadas

Texto publicado originalmente em ThoughtWorks Medium (Brasil)

--

--

Thoughtworks Brasil
Desenvolvimento ágil | Thoughtworks

Nossas ideias e opiniões sobre tecnologia, inovação, justiça social e muito mais! Conheça mais sobre a Thoughtworks Brasil: https://www.thoughtworks.com/pt-br