Terraform, mesmo código, ambientes diferentes, com Jenkins e AWS Fargate
Tags: terraform, fargate, jenkins
Published: 2021-03-24 22:21:03

Desde que comecei a usar o Terraform para montar minha infra estrutura via código na AWS ( Azure já estou de olho em você… ), me deparei com um problema de de replicação de código que me incomodava muito.
Várias documentações e exemplos de projetos que vi, os mesmos arquivos eram publicados em pastas diferentes, por exemplo, dev, homo e prod era algo do tipo:

![1_k7ClvbMgKbwQ7dmzfnqrUg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vynxmscj49xc9i5no9m3.png)
 

Ou algo muito próximo disso, ou em módulos (tá eu sei que são patterns), que replicavam os arquivos de variáveis, ou versionando em branches diferentes no repositório, enfim… testei quase todas estas opções (menos versionamento em branch, não faz o mínimo sentido, projetos diferentes tem tempo de vidas diferentes), mas, conforme o código evoluía, eu sempre tinha que replicar muitos arquivos, seja para passar parâmetros, para colocar em ambientes diferentes, enfim.
Considerando que, no caso, quando falamos três ambiente (dev, homo e prod), estamos falando de três contas distintas da AWS, o problema era muito maior de manter coeso os ambientes nas três contas.
Como eu sempre usava o Jenkins para implantar da infra estrutura via Terraform, fui apanhando, apanhando… até que achei uma forma, que para mim, foi a ideal.
Criei a estrutura de pastas em um repositório, com somente uma branch, a master, aqui vale a lei do Highlander, só pode haver um código para qualquer ambiente, independente do tempo de evolução do projetos contidos nele.

Vamos a ele …

Uma pasta ambientes, onde temos as configurações e variáveis comuns a todos os projetos, notem que o arquivo profile.tf se repete nas pastas, mas cada um com sua configuração.

![ambientes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mi6nvz3rpyb4b9b5d1mp.png)


Uma pasta projetos, onde dentro de cada um, há três pastas: dev, homo e prod, com as variáveis específicas de cada ambiente para cada projeto.

![projetos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bw4kmk42mbep63lekvmc.png)
 
Uma pasta recursos, onde tem as estruturas dos recursos que serão criados para cada projeto.

![recursos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqk0nyzpp5hl44si8p44.png)


Como podemos ver até aqui, temos dois projetos que podem ser implantados, um chamado “apihelloworld” e outro “apphelloworld”, o primeiro será via fargate e o segundo via S3. De que forma ?

Simples… passamos o trabalho para o Jenkins resolver:

Criando um pipeline, com 5 parâmetros:

TFRepository — caminho para o fonte do repositório acima.
TFEnvironment — ambiente que será executado.
TFProject — nome (e pasta) do projeto que será executado.
TFResource — tipo de recurso utilizado.
TFAction — ação do terraform, info ou apply.

A execução é explicada no código do pipeline:

{% gist https://gist.github.com/HSGiacomini/ec1b70cb87d7b44968d36bb2be6c4783 %}

De acordo com o código, estamos criando uma Task, onde os containers tem tamanhos diferentes dependendo do ambiente. (Futuramente estarei publicando o uso do AWS Fargate)

![env_var](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cu6s5aiq0oot2wvlo1ee.png)

Desta forma, quando vamos criar um projeto novo, seja uma API, uma aplicação, EC2, etc.. basta replicar alguma das pastas em projetos alterar (inserir ou excluir), as variáveis pertinentes ao projeto, e se for o caso, o mesmo pertinente ao ambiente (por exemplo, não vamos usar um bucketname para uma API e nem uma taskname para um S3…).

Vai replicar uma API, simples… seria algo do tipo: copiar a pasta apihelloworld para uma chamada apishowthecode e alterar os nomes de variáveis, depois, executar o job do Jenkins com o TFProject = apishowthecode

Depois, basta publicar o fonte no repositório e deixar o Jenkins fazer o resto, só informando, basicamente o ambiente, projeto e recurso.

Lembrando que os respectivos plugins, como Terraform, GIT, etc. devem ser instalados no Jenkins.

Outro ponto importante, aqui é só um exemplo, todos os parâmetros dos arquivos de recursos podem ter seus dados em variáveis, sejam na pasta projetos ou subdivididos nas pastas dos ambientes.

Bom galera, minha intenção aqui não é mostrar um jeito certo de fazer, o Terraform permite trabalhar de muitas formas, cada uma de acordo com o sua necessidade; a intenção foi mostrar mais uma forma de se fazer, e espero ajudá-los com um pontapé inicial para estruturação do seu ambiente, ou ao menos uma nova visão sobre as possibilidades que o Terraform nos oferece.

Aqui o link para fonte deste artigo.

Infra as code é igual bluetooth, bacon e café…. é vida !!!!

Abs a todos,