From ae4327324185b0cdd86bc9a1bcd9df9c32fd8920 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Thu, 17 Sep 2026 20:11:11 -0300 Subject: [PATCH 1/2] docs(aula-06): entrega trabalho-em-aula - GABRIEL REIS CUNHA (RA: 6325149) Code review do main.tf duplicado (dev/staging): 7 pares de recursos identicos, so mudando CIDR/tags; proposta de 4 modulos (vpc, security- group generico, ec2, rds) com inputs/outputs; diagrama de dependencias VPC -> SG -> EC2/RDS e analise de impacto de destruir a VPC. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01MXPSPGpiYJfKLiBzUL22VY --- entregas/aula-06/6325149/trabalho-em-aula.md | 116 +++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 entregas/aula-06/6325149/trabalho-em-aula.md diff --git a/entregas/aula-06/6325149/trabalho-em-aula.md b/entregas/aula-06/6325149/trabalho-em-aula.md new file mode 100644 index 00000000..2252cb8b --- /dev/null +++ b/entregas/aula-06/6325149/trabalho-em-aula.md @@ -0,0 +1,116 @@ +# Trabalho em Aula — Aula 06: Módulos Terraform + +**Aluno:** Gabriel Reis Cunha +**RA:** 6325149 +**Data:** 17/09/2026 + +## Parte 1 — Identificação de Duplicação + +1. **Blocos de recursos duplicados entre dev e staging (7 pares, 14 recursos):** + - `aws_vpc` (`dev` / `staging`) + - `aws_subnet` público 1 (`dev_public_1` / `staging_public_1`) + - `aws_subnet` público 2 (`dev_public_2` / `staging_public_2`) + - `aws_internet_gateway` (`dev` / `staging`) + - `aws_security_group` da API (`dev_api` / `staging_api`) + - `aws_security_group` do RDS (`dev_rds` / `staging_rds`) + - `aws_instance` da API (`dev_api` / `staging_api`) + +2. **O que muda entre dev e staging:** só um punhado de valores — + o CIDR da VPC (`10.0.0.0/16` → `10.1.0.0/16`), os CIDRs das duas subnets + (`10.0.1.0/24`/`10.0.2.0/24` → `10.1.1.0/24`/`10.1.2.0/24`), a tag + `Environment` (`dev` → `staging`) e o prefixo usado em todos os nomes/tags + (`technova-dev-*` → `technova-staging-*`). Toda a **estrutura** — quantidade + de subnets, regras de ingress/egress dos Security Groups, AMI, tipo de + instância, referência ao key pair — é idêntica byte a byte. + +3. **Módulos que eu criaria (mínimo 3, uso 4):** + - `modules/vpc` — VPC + subnets + Internet Gateway + route table + - `modules/security-group` — SG genérico, reutilizável tanto para a API + quanto para o RDS (e qualquer SG futuro) + - `modules/ec2` — instância EC2 parametrizável + - `modules/rds` — RDS PostgreSQL parametrizável (não aparece no trecho + de código analisado, mas é parte natural da arquitetura da TechNova das + aulas anteriores e está no diagrama de referência do exercício) + +4. **Variáveis (inputs) de cada módulo:** + - **vpc:** `vpc_cidr`, `project_name`, `environment`, `subnets` + (`map(object)` com `cidr`, `az`, `type`) + - **security-group:** `name`, `vpc_id`, `ingress_rules` (`list(object)`), + `environment`, `project_name` + - **ec2:** `instance_name`, `instance_type`, `ami_id`, `subnet_id`, + `security_group_ids`, `key_name` + - **rds:** `db_name`, `db_username`, `db_password` (sensitive), + `subnet_ids`, `security_group_ids`, `instance_class`, `environment`, + `project_name` + +5. **Outputs de cada módulo:** + - **vpc:** `vpc_id`, `public_subnet_ids`, `private_subnet_ids` + - **security-group:** `sg_id` + - **ec2:** `instance_id`, `public_ip`, `private_ip` + - **rds:** `db_endpoint`, `db_name`, `db_port` + +6. **Linhas para um ambiente de produção — código atual vs. módulos:** + O `main.tf` atual tem ~180 linhas para 2 ambientes (~90 linhas por + ambiente). Sem módulos, produção seria **mais uma cópia inteira**: +90 + linhas, chegando a ~270 linhas totais, todas quase idênticas e todas + precisando ser mantidas em sincronia manualmente. Com módulos, os 4 + módulos são escritos **uma única vez** (a lógica fica concentrada neles); + um ambiente novo é só um bloco de chamadas `module { ... }` com valores + diferentes — algo como **20-30 linhas**, não 90. Produção deixa de ser + "copiar e adaptar 90 linhas" e vira "adicionar um bloco pequeno". + +## Parte 2 — Design de Módulos (Diagrama de Dependências) + +``` + ┌──────────────────┐ + │ modules/vpc │ + │ │ + │ out: vpc_id │ + │ out: public_ids[] │ + │ out: private_ids[] │ + └─────────┬──────────┘ + │ vpc_id + ┌───────────────┼───────────────┐ + ▼ ▼ + ┌────────────────────┐ ┌────────────────────┐ + │ modules/security- │ │ modules/security- │ + │ group (api) │ │ group (rds) │ + │ out: sg_id │ │ out: sg_id │ + └──────────┬───────────┘ └──────────┬───────────┘ + │ sg_id │ sg_id + public_subnet_ids private_subnet_ids + │ │ + ▼ ▼ + ┌────────────────────┐ ┌────────────────────┐ + │ modules/ec2 │ │ modules/rds │ + │ (subnet_id + │ │ (subnet_ids + │ + │ security_group_ids) │ │ security_group_ids) │ + └────────────────────┘ └────────────────────┘ +``` + +- **Qual módulo deve ser criado primeiro, e por quê:** o `vpc`. Todos os + outros módulos precisam de `vpc_id` (Security Groups) ou dos IDs das + subnets (EC2 e RDS) que só existem depois da VPC ser criada — é a base de + toda a dependência. +- **Os módulos de Security Group dependem de qual output da VPC:** + `vpc_id` — é o único dado que o `aws_security_group` precisa da VPC para + saber onde aplicar as regras. +- **De quantos outros módulos o módulo EC2 depende:** 2 — do `vpc` (para o + `subnet_id` da subnet pública) e do `security-group` (para + `security_group_ids`). +- **O que acontece com os outros módulos se a VPC for destruída:** o + Terraform enxerga a dependência implícita via referência aos outputs + (`module.vpc.vpc_id`, `module.vpc.public_subnet_ids`), então ele tentaria + destruir primeiro tudo que depende da VPC (SGs, EC2, RDS) antes de poder + destruir a própria VPC. Se alguém tentasse remover só a VPC do state fora + de ordem, os outros módulos ficariam órfãos — outputs como `vpc_id` + deixariam de existir e o próximo `plan` mostraria erro ou tentativa de + recriação em cascata. +- **Vantagem de um módulo genérico de Security Group em vez de "api-sg" e + "rds-sg" separados:** com um único módulo parametrizado por + `ingress_rules` (lista de objetos), a mesma lógica de `aws_security_group` + é escrita uma vez e reutilizada para qualquer finalidade — API, RDS, e + amanhã um bastion host ou um load balancer, bastando passar regras + diferentes. Dois módulos hardcoded (`api-sg`, `rds-sg`) duplicariam a + mesma estrutura de recurso só mudando as regras, reproduzindo exatamente o + problema de duplicação que o exercício pede para eliminar. From 99ce36185bf68fb905ecb4e38dad4a1de98046cc Mon Sep 17 00:00:00 2001 From: Gabriel Date: Thu, 17 Sep 2026 21:08:09 -0300 Subject: [PATCH 2/2] docs(aula-06): entrega TF - GABRIEL REIS CUNHA (RA: 6325149) Biblioteca de modulos Terraform (vpc, security-group, ec2, rds) + dois ambientes (dev/staging) no unifaat-devops-portfolio. Evidencias de terraform plan nos dois ambientes, comportamento seletivo do for_each, e apply real (smoke test) do ambiente dev - 19 recursos criados, validados e destruidos na mesma sessao. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01MXPSPGpiYJfKLiBzUL22VY --- entregas/aula-06/6325149/entrega.md | 125 ++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 entregas/aula-06/6325149/entrega.md diff --git a/entregas/aula-06/6325149/entrega.md b/entregas/aula-06/6325149/entrega.md new file mode 100644 index 00000000..b612b92c --- /dev/null +++ b/entregas/aula-06/6325149/entrega.md @@ -0,0 +1,125 @@ +# Entrega — Aula 06: Terraform Modules + +**Aluno:** Gabriel Reis Cunha +**RA:** 6325149 +**Data:** 17/09/2026 + +## Repositório + +- URL: https://github.com/gabrielreis354/unifaat-devops-portfolio +- Pasta do projeto: [`aula-06/`](https://github.com/gabrielreis354/unifaat-devops-portfolio/tree/main/aula-06) +- Spec (SDD): [`specs/002-aula06-terraform-modules/`](https://github.com/gabrielreis354/unifaat-devops-portfolio/tree/main/specs/002-aula06-terraform-modules) + +## Evidências + +- [x] Módulo VPC com `for_each` para subnets dinâmicas +- [x] Módulo Security Group genérico (regras como lista de objetos) +- [x] Módulo EC2 reutilizável +- [x] Módulo RDS reutilizável +- [x] Composição entre módulos (output de um alimenta input de outro) +- [x] Dois ambientes (dev + staging) usando os mesmos módulos +- [x] `terraform validate` e `terraform plan` sem erros nos dois ambientes +- [x] README documentando cada módulo (inputs, outputs, exemplo) + +## Evidência do `terraform plan` (ambiente dev) + +``` +$ terraform plan + + # module.api_server.aws_instance.this will be created + # module.api_sg.aws_security_group.this will be created + # module.api_sg.aws_security_group_rule.egress[0] will be created + # module.api_sg.aws_security_group_rule.ingress[0] will be created + # module.api_sg.aws_security_group_rule.ingress[1] will be created + # module.database.aws_db_instance.main will be created + # module.database.aws_db_subnet_group.main will be created + # module.rds_sg.aws_security_group.this will be created + # module.rds_sg.aws_security_group_rule.egress[0] will be created + # module.rds_sg.aws_security_group_rule.ingress[0] will be created + # module.vpc.aws_internet_gateway.main will be created + # module.vpc.aws_route_table.public will be created + # module.vpc.aws_route_table_association.public["public-1"] will be created + # module.vpc.aws_route_table_association.public["public-2"] will be created + # module.vpc.aws_subnet.this["private-1"] will be created + # module.vpc.aws_subnet.this["private-2"] will be created + # module.vpc.aws_subnet.this["public-1"] will be created + # module.vpc.aws_subnet.this["public-2"] will be created + # module.vpc.aws_vpc.main will be created + +Plan: 19 to add, 0 to change, 0 to destroy. +``` + +O ambiente `staging` produz o mesmo conjunto de 19 recursos, com CIDRs e +nomes próprios (`10.1.0.0/16`, `technova-staging-*`), sem colisão com `dev`. + +## Evidência do comportamento seletivo do `for_each` + +Removendo `"private-2"` do mapa `subnets` (ambiente dev) e rodando `plan` +novamente, **apenas aquela subnet** deixa de aparecer no plano — as demais +(`public-1`, `public-2`, `private-1`) mantêm as mesmas chaves nomeadas, sem +qualquer reindexação: + +``` +$ terraform plan # com "private-2" removida +Plan: 18 to add, 0 to change, 0 to destroy. +``` + +(mudança revertida antes do commit final — as 4 subnets voltaram ao mapa.) + +## Evidência de `apply` real (smoke test do ambiente dev) + +Apesar de não ser exigido pelo TF.md, rodei `terraform apply` real no +ambiente `dev` para confirmar que os módulos funcionam de ponta a ponta, com +`destroy` imediato após a evidência: + +``` +$ terraform apply +... +Apply complete! Resources: 19 added, 0 changed, 0 destroyed. + +Outputs: +api_sg_id = "sg-0d496fab03c893eb7" +db_endpoint = "technova-dev-db.ch0dmfn54vrt.us-east-1.rds.amazonaws.com:5432" +ec2_public_ip = "52.90.99.133" +rds_sg_id = "sg-05fb0c5a18823aea3" +vpc_id = "vpc-000ba4578e0f3b85e" + +$ terraform plan +No changes. Your infrastructure matches the configuration. + +$ aws rds describe-db-instances --db-instance-identifier technova-dev-db \ + --query "DBInstances[0].{PubliclyAccessible:PubliclyAccessible,MultiAZ:MultiAZ,Encrypted:StorageEncrypted}" +Encrypted=true MultiAZ=false PubliclyAccessible=false + +$ terraform destroy +Destroy complete! Resources: 19 destroyed. +``` + +**Achado real:** a conta do AWS Academy Learner Lab rotacionou entre a +aula-05 e hoje — a key pair `technova-key` não existia na conta nova +(`InvalidKeyPair.NotFound` na criação do EC2). Resolvido com `aws ec2 +import-key-pair` reaproveitando a chave pública já gerada. Confirma que o +módulo `ec2` trata a key pair como pré-requisito externo (não a cria), como +documentado no `README.md` — e vira nota prática: **se a conta do lab +rotacionar, reimportar a chave antes do apply.** + +`environments/staging` permanece validado só por `terraform validate` + +`plan` (mesmos módulos que `dev`; o TF.md desaconselha aplicar os dois +ambientes ao mesmo tempo, para não dobrar o consumo do Learner Lab). + +## Nota sobre o módulo RDS + +Nenhum dos dois laboratórios desta aula cobre um módulo RDS. Ele foi +desenhado a partir do `aula-05-rds/rds.tf`, já validado com `terraform +apply` real na aula-05 (RDS PostgreSQL criado, testado via `psql` e +destruído). Detalhes da decisão em +[`specs/002-aula06-terraform-modules/plan.md`](https://github.com/gabrielreis354/unifaat-devops-portfolio/blob/main/specs/002-aula06-terraform-modules/plan.md). + +## Sobre `terraform apply` + +Conforme o `TF.md` desta aula, `terraform apply` **não é obrigatório** — a +avaliação usa `terraform validate` e `terraform plan` limpos nos dois +ambientes (o que `staging` cumpre). Ainda assim, apliquei de verdade o +ambiente `dev` como smoke test (seção acima) para confirmar que os módulos +funcionam de ponta a ponta, e destruí tudo imediatamente após capturar a +evidência — nenhum recurso ficou ativo na AWS.