Iniciando com Atlantis
Tags: terraform, atlantis, devops, ptbr
Published: 2021-06-15 20:48:38

Esse é o primeiro post de uma série sobre o [Atlantis](https://www.runatlantis.io/), onde o intuito é dar um mega salto no fluxo de trabalho de quem já utiliza Terraform no dia dia. Se você já:

* Utiliza Terraform para criar infraestrutura
* Ainda usa o Terraform local
* E sente falta de um ambiente mais colaborativo para desenvolver sua infraestrutura.

Essa série é para você! 

Vamos passar por alguns pontos básicos de como a ferramenta funciona e até explorar alguns modos de deployment. Tudo isso com um [repo](https://github.com/brunopadz/atlantis-101) no Github para te ajudar com configuração e exemplos.

Caso você não tenha experiência prévia com Terraform, super recomendo o conteúdo do [Igor Souza](https://www.youtube.com/channel/UC3yoPZJdjwOjrHWy_iEP08A/videos) no Youtube. :)

---

## O que é o Atlantis

O Atlantis é uma aplicação que automatiza através de Pull Requests a forma como rodamos o Terraform. 

> Gosto muito da definição do [Matheus Fidelis](https://twitter.com/fidelissauro), que o Atlantis permite fazer GitOps para Terraform. 

Ele funciona ouvindo Webhooks de plataformas de Git como: Github, Gitlab ou do Bitbucket e retorna o output dos comandos `terraform plan` e `terraform apply` através de comentários. Ou seja, todo fluxo de trabalho que antes era feito via CLI, terminal, pipeline do Jenkins, agora é feito nos comentários de uma Pull Request.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2afb9dxqo9xynyqypx6g.png">
  <figcaption>Exemplo de fluxo no trabalho. 🙂</figcaption>
</figure>

De uma forma mais simples, o Atlantis atua como uma "ponte" entre o Terraform e a plataforma de Git tornando os plans e applies muito mais colaborativos. Mas por quê? Oras, infraestrutura como código é uma abordagem de automação de infraestrutura baseada em princípios de desenvolvimento de software, com reviews, testes, CI/CD e etc...

---

## Antes de iniciar

Como mencionei acima, o Atlantis é uma espécie de wrapper do Terraform, por isso, a partir do momento que o Atlantis é adotado, é ele quem define qual versão do Terraform está rodando e é ele quem conhece as secrets e keys dos provedores de cloud, serviços e etc...

Por isso, a primeira dica é ficar de olho nas [releases](https://github.com/runatlantis/atlantis/releases) do projeto para saber se a última versão do Terraform já é suportada pelo Atlantis. E não necessariamente utilizar a última versão do Atlantis requer que você atualize seus projetos, por exemplo, é possível utilizar a última versão do Atlantis e para cada repo/projeto utilizar uma versão diferente do Terraform. Veremos sobre isso mais pra frente.

### Um pouco de mundo real...

Para os projetos do time de e-commerce da Leroy Merlin, nós rodamos o Atlantis como container no Kubernetes, utilizamos Terraform Cloud como backend e uma abordagem com monorepo e multirepo. Alguns projetos como IAM, configuração do Vault e coisas relacionadas a sec, ficam fora do monorepo por uma questão de segurança.

Nos outros repositórios todo o time de engenharia possui acesso e cada módulo e projeto, possui documentação para auxiliar a criar novos recursos.

Dependendo do repositório e do projeto é necessário que haja no mínimo "x" aprovações para rodar um `atlantis apply`, em outros é necessário aprovação de `CODEOWNERS`. O ponto é que não importa sua estrutura atual ou o que você está planejando, o Atlantis vai suportar.

De uma forma gráfica, o Atlantis funciona assim no nosso time:

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51fsr5zrsc97d0m04ttj.png">
  <figcaption>Fluxo do Atlantis no time de e-commerce da Leroy Merlin.</figcaption>
</figure>

---

## Indo mais a fundo

Nessa série de posts, utilizarei Github, Kubernetes e AWS. E durante ela, você irá encontrar nesse [repo](https://github.com/brunopadz/atlantis-101) mais informações e formas de deploy.

### Requerimentos

**Git** 

O Atlantis suporta as principais plataformas de Git como:

* Github
* Gitlab
* Bitbucket
* Azure DevOps

**Backend**

O Atlantis suporta todos os tipos de backend, menos o local, já que o Atlantis não tem um banco de dados e não commita o state no git (o que é um mega anti-pattern).

**Estrutura de diretório e repositórios**

Qualquer seja a estrutura utilizada, o Atlantis vai rodar sem problemas. É possível utilizar:

* Monorepo com vários projetos
* Único repo com um único projeto
* Monorepo com vários projetos e + módulos
* Multirepo (basta ter um webhook para cada um deles)

É possível também utilizar [Workspaces](https://www.terraform.io/docs/language/state/workspaces.html).

### Arquitetura

O Atlantis é uma aplicação desenvolvida em Go. Com um binário por volta de 40MB e com uma imagem docker por volta de 250MB é super simples de subi-lo no Kubernetes, ECS / Fargate ou instalá-lo em uma instância.

A comunicação entre o Atlantis e o plataforma de Git é intrínseca. Por exemplo, o Atlantis precisa receber os Webhooks e fazer chamadas para as APIs da plataforma de Git utilizada. Em caso de serviços externos, o Atlantis precisa responder por uma URL válida, já em casos de serviços internos como Github Enterprise, Gitlab Enterprise e Bitbucket Server, isso já não é necessário.

> **Importante**
> O Atlantis não possui um banco de dados, todos os arquivos de `plan`, binários dos providers e etc são salvos em disco.

### Configuração

Existem alguns métodos de configurar o Atlantis:

* Utilizando flags no comando `atlantis server`, onde também é possível utilizar arquivo de configuração e ENV VARs. Por exemplo: 
```sh
# Flags
atlantis server --gh-token="token/123456/ABCDE"

# ENV VAR
ATLANTIS_GH_TOKEN='token/123456/ABCDE' atlantis server
```

* Arquivo de configuração para cada repo. Onde o arquivo de configuração `repos.yml` fica junto do server.
* Arquivo de configuração em cada repositório. Onde cada repo possui o seu `atlantis.yml`.

### Utilização

Como deu pra notar, a principal diferença é que a partir de agora, o comando para rodar o Terraform mudou. O comando a ser chamado agora é o `atlantis`. Existem três principais subcomandos:

* `atlantis plan` que roda o `terraform plan` na branch de uma determinada Pull Request. É possível configurar para rodar de forma automática a cada novo commit, evitando intervenções manuais.
* `atlantis apply` que roda o `terraform apply` no plan executado anteriormente. 
* `atlantis help` que mostra a ajuda do Atlantis.

E claro, existem algumas flags em comum no `plan` e no `apply`, que no caso são as:

* `-w` que roda o plan ou apply contra um determinado workspace.
* `-d` que roda o plan ou apply de um projeto dentro de um diretório. Ele é importante quando a uma criação, alteração ou deleção de vários recursos em vários projetos em um único Pull Request. Se não especificado, roda em todos diretórios novos.

```sh
# Roda um plan para no diretório app1
atlantis plan -d app1

# Roda um plan no diretório aws/iam
atlantis plan -d aws/iam
```

* E existe o `-p` que roda plan e apply para um projeto.

É possível também utilizar flags do Terraform, como `-target`, `-var` e `-var-file`.

### Gerência do state

Assim como o Terraform, o Atlantis trabalha com state locking. Esse processo ocorre toda vez que um `atlantis plan` é executado e o state só será liberado quando a Pull Request for mergeada, fechada ou o plan é deletado de forma manual.

Vale a pena reforçar que esse state locking é do Atlantis e não do Terraform, onde o state do Atlantis é feito para prevenir várias Pull Requests trabalhando no mesmo projeto e o state do Terraform é feito para prevenir mudanças durante um `terraform apply`. Mais infos [aqui](https://www.terraform.io/docs/language/state/locking.html).

---

## Concluindo

Nessa primeira parte, abordamos o básico do Atlantis, como ele funciona, qual problema ele resolve e os motivos de utilizá-lo.

Nos próximos posts iremos nos aprofundar nos passos de instalação, configuração e como trabalhar de uma forma inteligente com Terraform.

Até mais!