↓ Ir para o conteúdo principal

Projeto 02: site estático na AWS com Terraform e GitLab CI

3 minutos

Problema
#

Publicar um site estático na AWS sem guardar chaves de acesso no pipeline e sem abrir SSH para os runners do GitLab. A aplicação é o site do curso de HTML e CSS do Gustavo Guanabara; o foco do projeto é a infraestrutura e o pipeline, não o site.

Ver repositório no GitLab

Arquitetura do projeto
#

Arquitetura do projetoDesenvolvedorGitLab CIIAM · role via OIDCAWS · us-east-1ECRecr-site-dandroidS3state do TerraformSSM Run Commanddeploy sem SSHEC2 t3.microAmazon Linux 2023container nginx · 8080 → 80Navegadortúnel SSH (porta 22)
Diagrama conceitual baseado na implementação documentada no repositório GitLab.
  • O Terraform cria uma EC2 t3.micro numa subnet nova, dentro de uma VPC que já existe. O security group libera só SSH, para um IP.
  • O ECR guarda a imagem ecr-site-dandroid, construída a partir de um Dockerfile com nginx:alpine.
  • O state do Terraform fica num bucket S3, com lock nativo.

Decisões técnicas e o motivo
#

  • Deploy por SSM em vez de SSH no pipeline: os runners compartilhados do GitLab têm IPs variáveis. Liberar a porta 22 para eles exigiria abri-la para a internet. Com SSM, o deploy usa a API da AWS e nenhuma porta de entrada é necessária.
  • OIDC em vez de chave de acesso: o GitLab assume uma role por OIDC e recebe credenciais temporárias. Não há chave de longa duração guardada.
  • Acesso só por túnel SSH: a porta 8080 da EC2 não é publicada na internet. Para ver o site, abre-se um túnel SSH. Domínio e HTTPS não estão configurados.
  • Tag da imagem pelo SHA do commit: o ECR tem tags mutáveis. Usar latest faria cada build sobrescrever o anterior.
  • Plano salvo e aplicado: o job plan gera um tfplan, e o apply aplica esse mesmo arquivo. O que foi revisado é o que entra.
  • Apply manual, numa branch só: o apply é manual e está configurado para a branch mes-11-projects.

Desafios reais
#

  • Dependência na primeira execução: o job build envia a imagem para um ECR que só existe depois do apply. Na primeira rodada, o build falha. O README orienta marcar o job com allow_failure nessa rodada e remover depois.

O que eu faria diferente
#

  • HTTPS com domínio: hoje o site só é acessível por túnel SSH. Com domínio e certificado, no host ou num ALB com ACM, ele poderia ficar público.
  • Docker no user_data: o deploy instala o Docker a cada execução. Instalar no user_data deixaria a instância pronta ao nascer.
  • Role e bucket em variáveis: o nome da role e do bucket do state estão fixos no código, o que dificulta reproduzir o projeto em outra conta.
  • Mínimo privilégio na role: a política de criação da role usa Resource: "*". Eu restringiria por ARN e por tag.
  • Apply na main: hoje o apply roda só na branch de trabalho. Em um fluxo real, ele rodaria na main, depois de revisão.

Tecnologias
#

Terraform, AWS (EC2, ECR, S3, IAM, SSM, VPC), Docker, nginx, GitLab CI, OIDC.