Conforme vimos no artigo anterior, utilizar infraestrutura como código é fundamental, principalmente quando estamos trabalho com provedores de nuvem. O terraform veio pra ajudar em vários desafios como vimos anteriormente e sua uilização tem trazido mais beneficios do que ferramentas nativas dos cloud providers.
Aqui continuaremos falando sobre o funcionamento e as vantagens do uso do terraform e também do terragrunt.
TERRAFORM
CONTROLE DE ESTADOS
Antes a gente usava as GMUD’s para controlar o estado do nosso ambiente e realizar as atualizações, agora com o terraform conseguimos controlar os estados da infraestrutura garantindo o estado atual a cada iteração. Esses estados são basicamente a nossa gerência de configuração.
Desta maneira eu posso entender qual é o estado do ambiente naquele momento e posteriormente até exportá-lo.
PLANEJAMENTO
No terraform, antes de realizar qualquer alteração, a gente pode ter uma noção de tudo que será criado em nosso ambiente. Podemos simular como aquele ambiente ficará após a execução, ver tudo que será criado, o que será alterado e removido antes de subir. E dessa maneira temos todo o controle de modificações antes de escolher se vamos ou não aplicar esses updates.
ABSTRAÇÃO
Com o uso do terraform a gente consegue ter uma abstração em alto nível. Ao invés de ter um código com valores estático, posso ter variaveis para alterar aquele valor de acordo com a minha necessidade e sem precisar de me preocupar em fazer essa modificação em vários lugares.
Por exemplo, a gerencia de vários ECS na AWS e neste cenário vamos supor que precisamos trocar o valor da memória de duas tasks definitions. Aqui poderíamos ter uma variável chamada taskdef_memoria para a quantidade de memória das minhas tasks definitions e sempre que eu quero mudar esse valor, eu preciso alterar somente nessa variável e não nos vários lugares em que esse recurso poderia estar. Assim o controle fica mais fácil
MODULARIZAÇÃO
Um dos maiores benefícios do é a modularização. A modularização é muito importante pra evitar que a gente tenha uma repetição de código muito grande. Ou seja, eu posso criar um módulo generico para um recurso e utilizar esse módulo para criar esse recurso para diferentes ocasiões. Por exemplo, pegando o caso da criação de um EC2, eu posso usar esse módulo padrão para subir vários EC2 diferentes, em contas diferentes, mudando somente as variáveis que vão personalizar essa instância. Vale lembrar que o terraform faz a organização de módulo a nível de diretório
E a ideia de modularizar, além de evitar a repetição de código, é desacoplar os recursos e trabalhar com eles separadamente. Voltando ali no caso do EC2, para que esse serviço funcione na AWS ele precisa também de outros recurso como rede e segurança e para criar a parte de rede eu posso ter um módulo de VPC (serviço de rede da AWS) em um local diferente de onde está meu módulo de EC2.
Dessa forma tudo fica mais simples e ajuda a não ter interferências quando precisamos ter atualizações paralelas, porque se alguém está modificando o módulo de VPC o de EC2 não será afetado e isso garante também a confiabilidade.
CRIAÇÃO DE NOVOS MÓDULOS E PROVEDORES
Por ser open source, dá super para fazer gerenciamento por API o que faz com que tenhamos a oportunidade de criar um provedor novo ou um módulo novo. Os providers grandes de nuvem investem muito nisso e a gente consegue ver pessoas dessas nuvens trabalhando fortemente nesse desenvolvimento. Em 2021 mesmo, lá no re:Invent a AWS anunciou um novo módulo do terraform, o AFT que permite provisionar e personalizar contas AWS por meio do Terraform usando um pipeline de implantação.
ORGANIZAÇÃO
Quando usamos o terraform, podemos organizar nossos arquivos e códigos em duas maneiras. A primeira é tudo junto em um diretório só e a segunda é em pastas separadas.
Na primeira abordagem podemos criar umarquivo para cada recurso dentro uma pasta e nessa organização a declaração das variáveis é feita em um lugar só, deixando a compreensão mais fácil e a repitação de código menor, mas por outro lado quando quando precisarmos fazer uma atualização, toda a infraestrutura será validada novamente. Ele vai checar se tem alguma atualização em todos os recursos dentro dessa pasta e se estiver alguma coisa não terminada pode quebrar o ambiente, assim como a aplicação da sua atualização pode ser muito demorada por precisar conferir recurso por recurso.
A recomendação para uso desse tipo de organização é quando a equipe é pequena, os recursos a serem criados não são muitos ou você ainda não tem a real noção da infra solicitada.
Na segunda abordagem, a organização acontece a nível de diretório e dessa forma conseguimos criar módulos e definir qual será a ordem de execução a partir de um depends_on. Aqui fica mais fácil de trabalhar e não tem o problema citado anteriormente da atualização de todos os recursos, nos diferentes arquivos, de uma só vez.
Nesse tipo de organização é onde acontece a modularização, por mais que eu tenha que declarar variaveis em todos os modulos, o que pode causar um pouco de duplicidade caso existam variaveis dependentes, o reuso de código é bem possível. Eu posso chamar esse modulo em um lugar e alterar somente o valor das varíaveis de acordo com a minha configuração.
TERRAFORM WORKSPACES
Agora que entendemos como funciona o terraform, precisamos pensar também em uma forma de trabalhar com nossos módulos, arquivos em vários ambientes, como desenvolvimento(DEV), homologação(HML) e produção(PRD).
Quando temos vários ambientes para trabalhar e precisamos usar o mesmo código, o terraform oferece um recurso chamado workspaces que basicamente cria ambientes separados, mas identicos e separa os states de cada um deles.
O uso do workspaces começa a ficar complicado quando temos um ambiente significativamente diferente dos demais, então por exemplo, se meu ambiente de HML é bem diferente de PRD e o pior, estão em contas diferentes, isso começa a dar mais trabalho e precisaríamos começar a fazer algumas gambiarras para tentar contornar o problema, como criar vários arquivos de configuração backend dentro de um código e ter que inicializar o terraform de acordo com o arquivo backend do ambiente a cada update.
Além desse problema, caso tenha algum recurso compartilhado a complexidade de gerencia aumenta, pois os estados também vão ter que ser compartilhados entre as workspaces.
E para mim, o maior problema do workspace é que não tem nada que avise em qual workspace você está e se por algum acaso você esquecer de trocar na hora na execução, você vai subir o ambiente errado sem perceber.
Desses problemas nasceu o terragrunt.
TERRAGRUNT
O terragrunt é uma ferramenta usada para orquestrar a execução do terraform. Ele trabalha a nível de diretório também, então você pode ter uma pasta para seu ambiente de DEV, um para HML e ou para PRD o que deixa mais facil a visualização e a evitar erros de aplicação por ambientes errados, como pode acontecer no workspaces.
O legal do terragrunt é a organização da execução de acordo com as dependencias que temos, então assim, se a gente tem inúmeros recursos que dependem um do outro, como um EC2 que depende de uma VPC, o terragrunt nos ajuda a gerenciar as dependencias pra fazer com que a VPC seja criada antes do EC2.
Com o terragrunt é possível fazer a comunicação de vários provedores de uma só vez. Então se eu tenho uma aplicação que usa containers e um banco de dados, onde os serviços de containers estão na AWS e o banco de dados estão na GCP, eu não preciso me preocupar em fazer a segregação por providers, posso manter tudo no mesmo repositorio pois ele consegue comunicar com os dois ao mesmo tempo mantendo a hierarquia de pastas.
Um outro ponto é que ele pode trabalhar com diferentes versões dos nossos modulos terraform. Se criar uma versão nova tagueando-a, é só informar na url de chamada do modulo essa versão e o terragunt vai trabalhar em cima dela.
CONCLUSÃO
Então o que usar e quando usar? Pra responder essa pergunta você precisa analisar o seu cenário. O uso do terraform é importante para ajudar no controle e gerenciamento da sua infraestrutura, assim como para ajudá-lo a subir todo seu ambiente de forma rápida cada aconteça algum incidente.
Se sua equipe for grande, com um projeto robusto o terraform com terragrunt é uma boa opção. Caso seja somente para subir poucos recursos que não tenham criticidade alta, o terraform dá conta do recado. E se a sua ideia for validar um ambiente antes de subir, criando uma copia testando e depois destruindo, o workspaces pode te ajudar.
REFERENCIAS
Esse blogpost foi inspirado em uma talk da Camilla Gomes no DevOpsDays VIX 2022.