beatrizgdc/Terraform-AWS-EC2-RemoteSt
GitHub: beatrizgdc/Terraform-AWS-EC2-RemoteSt
一个以教学为目的的 Terraform 项目,演示如何在 AWS 上通过远程状态与状态锁定安全地部署 EC2 与 Nginx。
Stars: 0 | Forks: 0
# Projeto Terraform AWS + EC2 - Remote State
## 📋 Índice
- [Visão Geral](#visão-geral)
- [Pré-requisitos](#pré-requisitos)
- [Estrutura de Arquivos](#estrutura-de-arquivos)
- [O que este projeto cria](#o-que-este-projeto-cria)
- [Como executar](#como-executar)
- [Comandos úteis](#comandos-úteis)
- [Documentação detalhada](#documentação-detalhada)
## Visão Geral
Este projeto provisiona uma instância EC2 Ubuntu com Nginx instalado automaticamente via `user_data`, protegida por um Security Group e acessível via SSH com Key Pair. O estado do Terraform é armazenado remotamente em um bucket S3 com state locking via DynamoDB, seguindo as boas práticas de times que trabalham em colaboração.
O projeto está dividido em **dois diretórios independentes**: `bootstrap/` (cria a infraestrutura de remote state) e `project/` (cria a infraestrutura principal). Essa separação é necessária porque o bucket S3 precisa existir antes de ser usado como backend.
O objetivo principal é **didático**: cada arquivo, recurso e decisão de design está comentado e documentado para facilitar o aprendizado.
## Pré-requisitos
| Ferramenta | Versão mínima | Verificar com |
|---|---|---|
| Terraform | `>= 1.3.0` | `terraform version` |
| AWS CLI | `>= 2.0` | `aws --version` |
| Credenciais AWS | Configuradas | `aws sts get-caller-identity` |
| Par de chaves SSH | `~/.ssh/id_rsa.pub` | `ls ~/.ssh/` |
### Configurando credenciais AWS
```
aws configure
# AWS Access Key ID: sua_access_key
# AWS Secret Access Key: sua_secret_key
# Default region name: us-east-1
# Default output format: json
```
Ou via variáveis de ambiente:
```
export AWS_ACCESS_KEY_ID="sua_access_key"
export AWS_SECRET_ACCESS_KEY="sua_secret_key"
export AWS_DEFAULT_REGION="us-east-1"
```
## Estrutura de Arquivos
```
terraform-demo/
│
├── README.md # Este arquivo
├── .gitignore # Arquivos ignorados pelo Git
│
├── docs/
│ ├── ARCHITECTURE.md # Explicação detalhada da arquitetura
│ └── TERRAFORM_CONCEPTS.md # Conceitos Terraform usados no projeto
│
├── bootstrap/ # ⚠️ Execute PRIMEIRO — apenas uma vez
│ ├── provider.tf # Provider AWS + version constraints
│ ├── variables.tf # Variáveis do bootstrap
│ ├── locals.tf # Tags comuns
│ ├── main.tf # S3 bucket + DynamoDB table + data source
│ ├── outputs.tf # Nome do bucket e da tabela (use no backend.tf)
│ └── terraform.tfvars # Valores das variáveis do bootstrap
│
└── project/ # Infraestrutura principal
├── provider.tf # Provider AWS + version constraints
├── backend.tf # Remote state: S3 + DynamoDB
├── variables.tf # Variáveis do projeto
├── locals.tf # Tags comuns e prefixo de nomes
├── main.tf # data source AMI + Key Pair + SG + EC2
├── outputs.tf # IPs, IDs, comandos SSH prontos
└── terraform.tfvars # Valores das variáveis do projeto
```
## O que este projeto cria
### Bootstrap — Remote State (pasta `bootstrap/`)
| Recurso | Tipo Terraform | Descrição |
|---|---|---|
| Bucket S3 | `aws_s3_bucket` | Armazena o `terraform.tfstate` do projeto principal |
| Versionamento S3 | `aws_s3_bucket_versioning` | Guarda versões anteriores do state para recuperação |
| Criptografia S3 | `aws_s3_bucket_server_side_encryption_configuration` | Criptografa o state em repouso (AES256) |
| Block Public Access | `aws_s3_bucket_public_access_block` | Garante que o bucket nunca fique público |
| Tabela DynamoDB | `aws_dynamodb_table` | State locking — evita operações simultâneas |
### Infraestrutura principal (pasta `project/`)
| Recurso | Tipo Terraform | Descrição |
|---|---|---|
| AMI Ubuntu | `data.aws_ami` | Busca automática da AMI Ubuntu 22.04 mais recente |
| Key Pair | `aws_key_pair` | Par de chaves para acesso SSH à instância |
| Security Group | `aws_security_group` | Libera portas 22 (SSH) e 80 (HTTP), egress livre |
| Instância EC2 | `aws_instance` | Ubuntu t2.micro com Nginx instalado via `user_data` |
## Como executar
### Passo 1 — Bootstrap: criar o Remote State (apenas na primeira vez)
O bucket S3 e a tabela DynamoDB precisam existir **antes** de configurar o backend.
O bootstrap usa estado **local** (sem backend remoto) por design.
```
cd bootstrap/
# Ajuste as variáveis em terraform.tfvars se necessário
terraform init
terraform plan
terraform apply
```
Ao final, anote os valores exibidos nos outputs:
```
state_bucket_name = "terraform-state-demo-123456789012"
dynamodb_table_name = "terraform-state-lock"
```
### Passo 2 — Atualizar o backend.tf com o nome do bucket
Abra `project/backend.tf` e substitua o placeholder pelo nome real do bucket:
```
backend "s3" {
bucket = "terraform-state-demo-123456789012" # ← valor do output
key = "demo/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-lock"
encrypt = true
}
```
### Passo 3 — Inicializar o projeto principal
```
cd ../project/
terraform init
# O Terraform vai baixar o provider AWS e conectar ao backend S3
```
### Passo 4 — Revisar o plano de execução
```
terraform plan
# Revise tudo que será criado antes de aplicar
```
### Passo 5 — Aplicar a infraestrutura
```
terraform apply
# Digite "yes" quando solicitado
```
Ao final do apply, os outputs mostram tudo que você precisa para acessar a instância:
```
instance_public_ip = "54.71.34.19"
ssh_command = "ssh -i ~/.ssh/id_rsa ubuntu@54.71.34.19"
nginx_url = "http://54.71.34.19"
ami_id_used = "ami-0c55b159cbfafe1f0"
```
### Passo 6 — Acessar a instância
```
# Use o comando pronto do output:
terraform output -raw ssh_command
# Ou diretamente:
ssh -i ~/.ssh/id_rsa ubuntu@
```
### Passo 7 — Destruir a infraestrutura
```
# Destrói apenas o project/ (EC2, SG, Key Pair)
terraform destroy
# Para destruir o bootstrap/ (S3 + DynamoDB):
cd ../bootstrap/
terraform destroy
# ⚠️ O bucket S3 tem prevent_destroy = true — o destroy vai falhar por design.
# Para destruir de verdade: remova o lifecycle block do main.tf do bootstrap
# ou delete o bucket manualmente no console AWS.
```
## Comandos úteis
```
# Validar sintaxe dos arquivos .tf
terraform validate
# Formatar automaticamente os arquivos
terraform fmt
# Listar recursos no state
terraform state list
# Ver detalhes de um recurso específico
terraform state show aws_instance.web
# Ver todos os outputs
terraform output
# Ver o valor de um output específico (sem aspas — ideal para scripts)
terraform output -raw ssh_command
terraform output -raw nginx_url
# Ativar logs detalhados para debug
export TF_LOG=DEBUG
terraform apply
# Sobrescrever uma variável pontualmente (sem alterar o tfvars)
terraform apply -var="instance_type=t2.small"
# Verificar qual conta AWS está sendo usada antes do apply
aws sts get-caller-identity
```
## Documentação detalhada
| Documento | Conteúdo |
|---|---|
| [Arquitetura.md](docs/ARCHITECTURE.md) | Diagrama, estrutura de pastas, decisões de design, explicação de cada arquivo e recurso |
| [CONCEITOS_TERRAFORM.md](docs/TERRAFORM_CONCEPTS.md) | Conceitos do Terraform aplicados com exemplos do próprio código |
标签:Amazon EC2, AWS, DPI, DynamoDB, EC2, ECS, IaC, Nginx, S3, SSH, Terraform, user_data, 云基础设施, 安全可观测性, 安全组, 教学演示, 最佳实践, 漏洞利用检测, 漏洞探索, 版本控制, 特权提升, 状态锁定, 自动化部署, 远程状态