Post

Estação de Trabalho como Código (Parte 12): Infraestrutura na AWS com Terraform

Aprenda a provisionar infraestrutura na AWS usando Terraform. Este tutorial cobre configuração do AWS CLI, criação de VPCs, instâncias EC2, grupos de segurança, módulos Terraform e como organizar seu código para múltiplos ambientes.

Estação de Trabalho como Código (Parte 12): Infraestrutura na AWS com Terraform

Tutorial Anterior: Estação de Trabalho como Código (Parte 11): Conceitos de Multi-Cloud e Equivalência de Recursos

Introdução

A Amazon Web Services (AWS) é o provedor de nuvem mais popular e maduro do mercado. Com uma ampla gama de serviços, desde computação simples até machine learning avançado, a AWS oferece flexibilidade e escalabilidade incomparáveis. Neste tutorial, vamos aprender a provisionar infraestrutura na AWS usando Terraform, começando com o essencial: VPCs, instâncias EC2, segurança e organização modular de código.

Diferente de usar AWS CLI manualmente, Terraform nos permite definir infraestrutura como código, versioná-la no Git e reutilizá-la em múltiplos ambientes.

Observação: Esta parte foca em Terraform (recomendado). Se preferir usar AWS CLI manualmente, consulte a documentação oficial. No entanto, recomendamos Terraform para automação profissional.

Objetivos desta Parte

  • Instalar e configurar o AWS CLI
  • Criar credenciais de acesso (Access Keys)
  • Configurar o provider AWS no Terraform
  • Criar uma VPC (Virtual Private Cloud) personalizada
  • Provisionar instâncias EC2 com Terraform
  • Configurar grupos de segurança e redes
  • Organizar código em módulos reutilizáveis
  • Usar variáveis para flexibilidade

Pré-requisitos

  • Conclusão da Parte 11 desta série
  • Conta AWS criada (pode usar free tier)
  • Terraform instalado (Parte 7)
  • AWS CLI instalado (Parte 11)

A quem se destina

Este tutorial é ideal para:

  • DevOps Engineers: Que precisam provisionar infraestrutura na AWS
  • Arquitetos de Nuvem: Que querem usar IaC para AWS
  • SysAdmins: Que querem expandir para a nuvem
  • Profissionais de TI: Que querem implementar IaC em AWS

Pré-conhecimento: Conhecimento de Terraform, AWS e networking (coberto nas partes anteriores) é recomendado.

Tempo Estimado

150-180 minutos

Isso inclui:

  • Leitura e compreensão: ~25 min
  • Configuração AWS CLI: ~15 min
  • Criação de estrutura Terraform: ~20 min
  • Desenvolvimento de módulos: ~50 min
  • Execução e testes: ~30 min
  • Troubleshooting: ~15 min

Dica Útil: Use o free tier da AWS para experimentar sem custos. Você tem 12 meses de free tier.


Entendendo AWS

Antes de começar, é importante entender os conceitos fundamentais.

O que é AWS?

AWS (Amazon Web Services) é uma plataforma de computação em nuvem que oferece mais de 200 serviços diferentes. Os principais são:

  • Computação: EC2, Lambda, ECS
  • Armazenamento: S3, EBS, EFS
  • Banco de Dados: RDS, DynamoDB, ElastiCache
  • Rede: VPC, ELB, Route 53
  • Segurança: IAM, KMS, Secrets Manager

Conceitos Principais

ConceitoDescrição
RegionLocalização geográfica com múltiplos datacenters
Availability ZoneDatacenter isolado dentro de uma região
VPCRede virtual isolada onde você executa recursos
SubnetSegmento de rede dentro de uma VPC
EC2Máquina virtual na AWS
Security GroupFirewall virtual para controlar tráfego
IAMGerenciamento de identidade e acesso
S3Armazenamento de objetos (arquivos)

Verificando Pré-Requisitos

Antes de começar, certifique-se de que seu ambiente está pronto.

Passo 1: Verificar Terraform

1
2
3
4
5
# Verifique se Terraform está instalado
$ terraform --version

# Você deve ver:
# Terraform v1.14.5

Passo 2: Verificar AWS CLI

1
2
3
4
5
# Verifique se AWS CLI está instalado
$ aws --version

# Você deve ver:
# aws-cli/2.33.24 Python/3.13.11 Linux/...

Passo 3: Verificar Credenciais AWS

1
2
3
4
5
6
7
8
9
# Verifique se credenciais estão configuradas
$ aws sts get-caller-identity

# Você deve ver:
# {
#     "UserId": "AIDATHLMZ5S4GCAZWUIB6",
#     "Account": "221955878072",
#     "Arn": "arn:aws:iam::221955878072:user/gmadm"
# }

Configurando AWS CLI

Passo 1: Instalar AWS CLI

1
2
3
4
5
6
7
8
# Instale AWS CLI
$ sudo apt install -y awscli

# Ou use pip
$ pip3 install awscli

# Verifique
$ aws --version

Passo 2: Criar Access Keys

  1. Acesse AWS Console
  2. Vá para IAMUsers → seu usuário
  3. Clique em Security credentials
  4. Clique em Create access key
  5. Escolha Command Line Interface (CLI)
  6. Copie Access Key ID e Secret Access Key

Passo 3: Configurar Credenciais

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Configure AWS CLI
$ aws configure

# Você será solicitado:
# AWS Access Key ID: [cole sua chave]
# AWS Secret Access Key: [cole sua chave secreta]
# Default region name: us-east-1
# Default output format: json

# Verifique
$ aws configure list

# Você deve ver:
# NAME       : VALUE                    : TYPE
# profile    : <not set>                : None
# access_key : ****************UJPK     : shared-credentials-file
# secret_key : ****************WcYF     : shared-credentials-file
# region     : us-east-1                : config-file

Criando Estrutura Terraform para AWS

Passo 1: Criar Diretórios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Crie a estrutura de diretórios
$ mkdir -p ~/workspace-as-code/terraform/providers/aws/{modules,environments}
$ cd ~/workspace-as-code/terraform/providers/aws

# Estrutura esperada:
# aws/
# ├── modules/
# │   ├── vpc/
# │   │   ├── main.tf
# │   │   ├── variables.tf
# │   │   └── outputs.tf
# │   ├── security_group/
# │   │   ├── main.tf
# │   │   ├── variables.tf
# │   │   └── outputs.tf
# │   └── ec2/
# │       ├── main.tf
# │       ├── variables.tf
# │       └── outputs.tf
# ├── environments/
# │   ├── dev/
# │   │   ├── main.tf
# │   │   ├── terraform.tfvars
# │   │   └── backend.tf
# │   ├── staging/
# │   └── prod/
# ├── main.tf
# ├── variables.tf
# ├── outputs.tf
# └── provider.tf

Passo 2: Criar Arquivo de Provider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Crie arquivo provider.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/provider.tf << 'EOF'
terraform {
  required_version = "~> 1.14.5"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = {
      Project     = var.project_name
      Environment = var.environment
      ManagedBy   = "Terraform"
      CreatedAt   = timestamp()
    }
  }
}
EOF

# Verifique
$ cat ~/workspace-as-code/terraform/providers/aws/provider.tf

Passo 3: Criar Variáveis Principais

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Crie arquivo variables.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/variables.tf << 'EOF'
variable "aws_region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "project_name" {
  description = "Project name"
  type        = string
  default     = "workspace-as-code"
}

variable "environment" {
  description = "Environment name (dev, staging, prod)"
  type        = string
  default     = "dev"
}

variable "vpc_cidr" {
  description = "CIDR block for VPC"
  type        = string
  default     = "10.0.0.0/16"
}

variable "subnet_cidr" {
  description = "CIDR block for subnet"
  type        = string
  default     = "10.0.1.0/24"
}

variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t2.micro"
}

variable "enable_public_ip" {
  description = "Enable public IP for EC2"
  type        = bool
  default     = true
}
EOF

# Verifique
$ cat ~/workspace-as-code/terraform/providers/aws/variables.tf

Criando Módulos Terraform

Módulo 1: VPC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# Crie diretório do módulo
$ mkdir -p ~/workspace-as-code/terraform/providers/aws/modules/vpc

# Crie arquivo main.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/vpc/main.tf << 'EOF'
# VPC
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "${var.project_name}-vpc"
  }
}

# Internet Gateway
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "${var.project_name}-igw"
  }
}

# Subnet Pública
resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = var.subnet_cidr
  availability_zone       = data.aws_availability_zones.available.names[0]
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.project_name}-subnet-public"
  }
}

# Route Table
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block      = "0.0.0.0/0"
    gateway_id      = aws_internet_gateway.main.id
  }

  tags = {
    Name = "${var.project_name}-rt-public"
  }
}

# Route Table Association
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

# Data source para obter AZs disponíveis
data "aws_availability_zones" "available" {
  state = "available"
}
EOF

# Crie arquivo variables.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/vpc/variables.tf << 'EOF'
variable "vpc_cidr" {
  description = "CIDR block for VPC"
  type        = string
}

variable "subnet_cidr" {
  description = "CIDR block for subnet"
  type        = string
}

variable "project_name" {
  description = "Project name"
  type        = string
}
EOF

# Crie arquivo outputs.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/vpc/outputs.tf << 'EOF'
output "vpc_id" {
  description = "VPC ID"
  value       = aws_vpc.main.id
}

output "subnet_id" {
  description = "Subnet ID"
  value       = aws_subnet.public.id
}

output "internet_gateway_id" {
  description = "Internet Gateway ID"
  value       = aws_internet_gateway.main.id
}
EOF

Módulo 2: Security Group

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# Crie diretório do módulo
$ mkdir -p ~/workspace-as-code/terraform/providers/aws/modules/security_group

# Crie arquivo main.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/security_group/main.tf << 'EOF'
resource "aws_security_group" "main" {
  name        = "${var.project_name}-sg"
  description = "Security Group for ${var.project_name}"
  vpc_id      = var.vpc_id

  # Ingress SSH
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = var.allowed_ssh_cidr
  }

  # Ingress HTTP
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # Ingress HTTPS
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # Egress (permitir tudo)
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.project_name}-sg"
  }
}
EOF

# Crie arquivo variables.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/security_group/variables.tf << 'EOF'
variable "vpc_id" {
  description = "VPC ID"
  type        = string
}

variable "project_name" {
  description = "Project name"
  type        = string
}

variable "allowed_ssh_cidr" {
  description = "CIDR blocks allowed for SSH"
  type        = list(string)
  default     = ["0.0.0.0/0"]
}
EOF

# Crie arquivo outputs.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/security_group/outputs.tf << 'EOF'
output "security_group_id" {
  description = "Security Group ID"
  value       = aws_security_group.main.id
}
EOF

Módulo 3: EC2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# Crie diretório do módulo
$ mkdir -p ~/workspace-as-code/terraform/providers/aws/modules/ec2

# Crie arquivo main.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/ec2/main.tf << 'EOF'
# Data source para obter AMI Debian mais recente
data "aws_ami" "debian" {
  most_recent = true
  owners      = ["136693071363"] # Debian official

  filter {
    name   = "name"
    values = ["debian-12-amd64-*"]
  }

  filter {
    name   = "state"
    values = ["available"]
  }
}

# Key Pair
resource "aws_key_pair" "main" {
  key_name   = "${var.project_name}-key"
  public_key = file(var.public_key_path)

  tags = {
    Name = "${var.project_name}-key"
  }
}

# EC2 Instance
resource "aws_instance" "main" {
  ami                    = data.aws_ami.debian.id
  instance_type          = var.instance_type
  subnet_id              = var.subnet_id
  vpc_security_group_ids = [var.security_group_id]
  key_name               = aws_key_pair.main.key_name

  associate_public_ip_address = var.enable_public_ip

  root_block_device {
    volume_type           = "gp3"
    volume_size           = var.root_volume_size
    delete_on_termination = true
  }

  tags = {
    Name = "${var.project_name}-instance"
  }

  depends_on = [aws_key_pair.main]
}
EOF

# Crie arquivo variables.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/ec2/variables.tf << 'EOF'
variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t2.micro"
}

variable "subnet_id" {
  description = "Subnet ID"
  type        = string
}

variable "security_group_id" {
  description = "Security Group ID"
  type        = string
}

variable "project_name" {
  description = "Project name"
  type        = string
}

variable "public_key_path" {
  description = "Path to public key file"
  type        = string
}

variable "enable_public_ip" {
  description = "Enable public IP"
  type        = bool
  default     = true
}

variable "root_volume_size" {
  description = "Root volume size in GB"
  type        = number
  default     = 20
}
EOF

# Crie arquivo outputs.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/modules/ec2/outputs.tf << 'EOF'
output "instance_id" {
  description = "EC2 Instance ID"
  value       = aws_instance.main.id
}

output "public_ip" {
  description = "Public IP address"
  value       = aws_instance.main.public_ip
}

output "private_ip" {
  description = "Private IP address"
  value       = aws_instance.main.private_ip
}

output "ami_id" {
  description = "AMI ID used"
  value       = data.aws_ami.debian.id
}
EOF

Criando Configuração Principal

Passo 1: Arquivo Main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Crie arquivo main.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/main.tf << 'EOF'
# Módulo VPC
module "vpc" {
  source = "./modules/vpc"

  vpc_cidr      = var.vpc_cidr
  subnet_cidr   = var.subnet_cidr
  project_name  = var.project_name
}

# Módulo Security Group
module "security_group" {
  source = "./modules/security_group"

  vpc_id           = module.vpc.vpc_id
  project_name     = var.project_name
  allowed_ssh_cidr = ["0.0.0.0/0"] # Mude para seu IP em produção
}

# Módulo EC2
module "ec2" {
  source = "./modules/ec2"

  instance_type      = var.instance_type
  subnet_id          = module.vpc.subnet_id
  security_group_id  = module.security_group.security_group_id
  project_name       = var.project_name
  public_key_path    = "~/.ssh/terraform-vms.pub"
  enable_public_ip   = var.enable_public_ip
}
EOF

# Verifique
$ cat ~/workspace-as-code/terraform/providers/aws/main.tf

Passo 2: Arquivo Outputs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Crie arquivo outputs.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/outputs.tf << 'EOF'
output "vpc_id" {
  description = "VPC ID"
  value       = module.vpc.vpc_id
}

output "subnet_id" {
  description = "Subnet ID"
  value       = module.vpc.subnet_id
}

output "security_group_id" {
  description = "Security Group ID"
  value       = module.security_group.security_group_id
}

output "instance_id" {
  description = "EC2 Instance ID"
  value       = module.ec2.instance_id
}

output "instance_public_ip" {
  description = "EC2 Public IP"
  value       = module.ec2.public_ip
}

output "instance_private_ip" {
  description = "EC2 Private IP"
  value       = module.ec2.private_ip
}

output "ami_id" {
  description = "AMI ID used"
  value       = module.ec2.ami_id
}
EOF

# Verifique
$ cat ~/workspace-as-code/terraform/providers/aws/outputs.tf

Criando Ambientes

Passo 1: Ambiente Dev

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# Crie diretório do ambiente
$ mkdir -p ~/workspace-as-code/terraform/providers/aws/environments/dev

# Crie arquivo terraform.tfvars
$ cat > ~/workspace-as-code/terraform/providers/aws/environments/dev/terraform.tfvars << 'EOF'
aws_region    = "us-east-1"
project_name  = "workspace-as-code"
environment   = "dev"
vpc_cidr      = "10.0.0.0/16"
subnet_cidr   = "10.0.1.0/24"
instance_type = "t2.micro"
EOF

# Crie arquivo main.tf (referencia módulos)
$ cat > ~/workspace-as-code/terraform/providers/aws/environments/dev/main.tf << 'EOF'
terraform {
  required_version = "~> 1.14.5"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

module "aws_infrastructure" {
  source = "../../"

  aws_region    = var.aws_region
  project_name  = var.project_name
  environment   = var.environment
  vpc_cidr      = var.vpc_cidr
  subnet_cidr   = var.subnet_cidr
  instance_type = var.instance_type
}
EOF

# Crie arquivo variables.tf
$ cat > ~/workspace-as-code/terraform/providers/aws/environments/dev/variables.tf << 'EOF'
variable "aws_region" {
  type = string
}

variable "project_name" {
  type = string
}

variable "environment" {
  type = string
}

variable "vpc_cidr" {
  type = string
}

variable "subnet_cidr" {
  type = string
}

variable "instance_type" {
  type = string
}
EOF

Executando Terraform

Passo 1: Inicializar Terraform

1
2
3
4
5
6
7
8
# Navegue para o diretório
$ cd ~/workspace-as-code/terraform/providers/aws

# Inicialize Terraform
$ terraform init

# Você deve ver:
# Terraform has been successfully configured!

Passo 2: Validar Configuração

1
2
3
4
5
# Valide a sintaxe
$ terraform validate

# Você deve ver:
# Success! The configuration is valid.

Passo 3: Formatar Código

1
2
3
4
# Formate o código
$ terraform fmt -recursive

# Isso vai formatar todos os arquivos .tf

Passo 4: Planejar Execução

1
2
3
4
# Crie um plano
$ terraform plan -out=tfplan

# Você verá as mudanças que serão feitas

Passo 5: Aplicar Configuração

1
2
3
4
5
# Aplique o plano
$ terraform apply tfplan

# Você verá:
# Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Passo 6: Verificar Saída

1
2
3
4
5
6
7
# Veja os outputs
$ terraform output

# Você verá:
# instance_public_ip = "54.123.45.67"
# instance_private_ip = "10.0.1.123"
# ...

Acessando a Instância EC2

Passo 1: Obter IP Público

1
2
3
4
5
# Obtenha o IP público
$ terraform output instance_public_ip

# Você verá:
# "54.123.45.67"

Passo 2: Conectar via SSH

1
2
3
4
5
6
7
8
9
10
# Conecte à instância
$ ssh -i ~/.ssh/terraform-vms debian@$(terraform output -raw instance_public_ip)

# Você deve ver:
# The authenticity of host '54.123.45.67 (54.123.45.67)' can't be established.
# Are you sure you want to continue connecting (yes/no)?

# Digite: yes

# Você deve estar conectado à instância

Passo 3: Verificar Instância

1
2
3
4
# Verifique informações da instância
$ uname -a
$ cat /etc/os-release
$ df -h

Tabela de Módulos Terraform

MóduloDescriçãoRecursos
vpcCria VPC e redeVPC, Subnet, IGW, Route Table
security_groupCria firewallSecurity Group, Ingress/Egress
ec2Cria instânciaEC2, Key Pair, AMI lookup

Troubleshooting

Erro: “InvalidKeyPair.NotFound”

Problema: Chave SSH não existe.

Solução:

1
2
3
4
5
# Verifique se chave existe
$ ls -la ~/.ssh/terraform-vms.pub

# Ou crie uma nova chave
$ ssh-keygen -t ed25519 -f ~/.ssh/terraform-vms -N ""

Erro: “UnauthorizedOperation”

Problema: Credenciais AWS inválidas ou sem permissão.

Solução:

1
2
3
4
5
# Verifique credenciais
$ aws sts get-caller-identity

# Ou reconfigure
$ aws configure

Erro: “InvalidVpcID.NotFound”

Problema: VPC não existe.

Solução:

1
2
3
4
5
# Verifique VPCs existentes
$ aws ec2 describe-vpcs

# Ou recrie com terraform apply
$ terraform apply

Erro: “InsufficientInstanceCapacity”

Problema: Tipo de instância não disponível na AZ.

Solução:

1
2
3
4
5
6
# Tente outra AZ ou tipo de instância
# Edite terraform.tfvars
instance_type = "t3.micro"

# Ou aplique novamente
$ terraform apply

Instância não responde a SSH

Problema: Security Group bloqueia SSH.

Solução:

1
2
3
4
5
6
7
8
9
# Verifique regras de segurança
$ aws ec2 describe-security-groups

# Ou adicione regra manualmente
$ aws ec2 authorize-security-group-ingress \
  --group-id sg-xxxxx \
  --protocol tcp \
  --port 22 \
  --cidr 0.0.0.0/0

Dicas e Boas Práticas

Dica 1: Use Variáveis para Flexibilidade

1
2
3
4
5
6
7
8
9
# Bom
variable "instance_type" {
  default = "t2.micro"
}

# Ruim
resource "aws_instance" "main" {
  instance_type = "t2.micro"
}

Dica 2: Organize em Módulos

1
2
3
4
modules/
├── vpc/
├── security_group/
└── ec2/

Dica 3: Use Outputs para Referências

1
2
3
output "instance_ip" {
  value = aws_instance.main.public_ip
}

Dica 4: Versione Tudo

1
2
3
$ git add .
$ git commit -m "feat: add AWS infrastructure"
$ git push origin main

Dica 5: Use Workspaces para Ambientes

1
2
3
$ terraform workspace new dev
$ terraform workspace new staging
$ terraform workspace new prod

Integrando com workspace-as-code

Passo 1: Organizar Estrutura

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Verifique a estrutura
$ tree ~/workspace-as-code/terraform/providers/aws/

# Você deve ver:
# aws/
# ├── modules/
# │   ├── vpc/
# │   ├── security_group/
# │   └── ec2/
# ├── environments/
# │   └── dev/
# ├── main.tf
# ├── variables.tf
# ├── outputs.tf
# └── provider.tf

Passo 2: Versionar no Git

1
2
3
4
5
6
7
8
# Adicione ao Git
$ cd ~/workspace-as-code
$ git add terraform/providers/aws/
$ git commit -m "feat: add AWS infrastructure with Terraform"
$ git push origin main

# Verifique
$ git log --oneline | head -5

Script de Validação

Para verificar se tudo foi configurado corretamente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/bin/bash
# Script de validação de AWS Terraform

echo "Validando AWS Terraform..."

# Verificar AWS CLI
if command -v aws &> /dev/null; then
    echo "✓ AWS CLI instalado"
else
    echo "✗ AWS CLI não instalado"
    exit 1
fi

# Verificar credenciais
if aws sts get-caller-identity &> /dev/null; then
    echo "✓ Credenciais AWS OK"
else
    echo "✗ Credenciais AWS inválidas"
    exit 1
fi

# Verificar Terraform
if command -v terraform &> /dev/null; then
    echo "✓ Terraform instalado"
else
    echo "✗ Terraform não instalado"
    exit 1
fi

# Verificar estrutura
if [ -d "terraform/providers/aws/modules" ]; then
    echo "✓ Módulos existem"
else
    echo "✗ Módulos não existem"
    exit 1
fi

# Validar Terraform
cd terraform/providers/aws
if terraform validate &> /dev/null; then
    echo "✓ Terraform válido"
else
    echo "✗ Terraform inválido"
    exit 1
fi

echo ""
echo "Validação concluída com sucesso!"

Conclusão

Você aprendeu a provisionar infraestrutura na AWS usando Terraform. Com Terraform, você pode definir infraestrutura como código, versioná-la no Git e reutilizá-la em múltiplos ambientes.

O Que Você Alcançou

✓ Instalação e configuração do AWS CLI ✓ Criação de credenciais de acesso ✓ Configuração do provider AWS no Terraform ✓ Criação de VPC e rede ✓ Provisão de instâncias EC2 ✓ Configuração de segurança ✓ Organização em módulos reutilizáveis ✓ Uso de variáveis para flexibilidade

Próximos Passos Imediatos

  1. Configure AWS CLI:
    1
    
    $ aws configure
    
  2. Crie estrutura Terraform:
    1
    
    $ mkdir -p ~/workspace-as-code/terraform/providers/aws/{modules,environments}
    
  3. Crie módulos:
    1
    
    $ mkdir -p ~/workspace-as-code/terraform/providers/aws/modules/{vpc,security_group,ec2}
    
  4. Copie arquivos dos exemplos acima

  5. Inicialize Terraform:
    1
    2
    
    $ cd ~/workspace-as-code/terraform/providers/aws
    $ terraform init
    
  6. Valide e aplique:
    1
    2
    3
    
    $ terraform validate
    $ terraform plan
    $ terraform apply
    
  7. Versione no Git:
    1
    2
    3
    
    $ git add terraform/
    $ git commit -m "feat: add AWS infrastructure"
    $ git push origin main
    

Próximo Tutorial

Com infraestrutura na AWS configurada, o próximo passo é aprender a usar Azure com Terraform.


Recursos Adicionais


Fim da Parte 12

Próxima: Infraestrutura no Azure com Terraform

This post is licensed under CC BY 4.0 by the author.