Olá! Bem-vindo à nossa décima terceira lição do curso.
Na lição anterior, estabelecemos a base teórica da Infraestrutura como Código (IaC), focando na abordagem declarativa do Terraform e no seu fluxo de trabalho plan/apply. Agora, é hora de transformar essa teoria em prática.
O nosso objetivo nesta lição é escrever uma configuração Terraform para definir um Cluster ECS e a sua rede subjacente (VPC e Sub-redes). Vamos construir a fundação na AWS onde nossos contêineres .NET serão executados. Você escreverá seu primeiro código HCL (HashiCorp Configuration Language) e usará os comandos do Terraform para provisionar recursos reais na nuvem.
1. Preparando o Ambiente Terraform
Antes de definirmos os recursos, precisamos configurar nosso projeto Terraform e dizer a ele como se autenticar na AWS. Como você é um desenvolvedor experiente, a prática de separar a configuração da lógica será familiar.
Estrutura do Projeto e Configuração do Provider
Vamos criar um diretório para nosso projeto e, dentro dele, três arquivos iniciais:
provider.tf: Declara os provedores que o Terraform usará (neste caso, o provedor AWS).variables.tf: Define as variáveis de entrada para nossa configuração, tornando-a reutilizável.terraform.tfvars: Atribui valores a essas variáveis. Este arquivo geralmente contém informações sensíveis ou específicas do ambiente e não deve ser versionado no Git.
O artigo a seguir demonstra exatamente essa estrutura.
Streamlining AWS ECS Infrastructure with Terraform
Vamos usar a seção "Configure Provider & Input Variables" do artigo "Streamlining AWS ECS Infrastructure with Terraform" do AWS in Plain English como nosso guia.
Leia a seção "Step 3: Configure Provider & Input Variables". Siga as instruções para criar os três arquivos: provider.tf, variables.tf, e terraform.tfvars. Por enquanto, defina apenas as variáveis aws_region e profile em variables.tf e seus respectivos valores em terraform.tfvars. Usaremos as outras variáveis mais tarde.
Seu provider.tf deve se parecer com:
provider "aws" {
region = var.aws_region
profile = var.profile
}
Seu variables.tf:
variable "aws_region" {
description = "Região da AWS para provisionar os recursos"
type = string
}
variable "profile" {
description = "Perfil da AWS CLI para usar para autenticação"
type = string
}
E seu terraform.tfvars:
aws_region = "us-east-1" // ou a região de sua preferência
profile = "default" // ou o nome do seu perfil AWS configurado
Inicializando o Terraform
Com os arquivos no lugar, abra seu terminal no diretório do projeto e execute:
terraform init
Este comando, como vimos na lição anterior, lê seu código, identifica os provedores necessários (neste caso, aws) e baixa os plugins correspondentes para o subdiretório .terraform. Você só precisa executar init quando adiciona um novo provedor ou módulo.
2. Definindo a Rede: VPC e Sub-redes
A base de qualquer infraestrutura na AWS é a rede. Para o ECS, precisamos de uma Virtual Private Cloud (VPC), que é sua rede privada e isolada na nuvem. Dentro da VPC, criaremos sub-redes:
- Sub-redes Públicas: Têm acesso direto à internet através de um Internet Gateway. Usaremos estas para o nosso Balanceador de Carga (Application Load Balancer) em uma lição futura, pois ele precisa ser acessível publicamente.
- Sub-redes Privadas: Não têm acesso direto à internet. Nossos contêineres rodarão aqui por segurança. Elas podem acessar a internet para tarefas como baixar imagens do ECR através de um NAT Gateway, que atua como um intermediário.

Escrevendo o network.tf
Vamos criar um novo arquivo, network.tf, para definir todos os nossos recursos de rede. O vídeo a seguir oferece um excelente passo a passo visual da criação de cada um desses recursos.
How to create AWS VPC with Subnets using Terraform
O vídeo "How to create AWS VPC with Subnets using Terraform" do canal Cloud Champ explica claramente como definir cada recurso de rede. Assista para entender o propósito de cada bloco de código que vamos escrever.
Assista dos timestamps 00:57 a 07:23. Foque em entender: 1) A sintaxe de um bloco resource. 2) Como o ID de um recurso (ex: aws_vpc.myvpc.id) é usado para conectar outros recursos a ele. 3) O propósito do aws_internet_gateway e do aws_route_table.
Agora, vamos escrever o código. Usaremos o código do artigo Streamlining AWS ECS Infrastructure with Terraform porque ele cria uma arquitetura robusta com sub-redes públicas e privadas em múltiplas zonas de disponibilidade, o que é uma prática recomendada para alta disponibilidade.
Adicione o seguinte conteúdo ao seu arquivo network.tf. Dividimos em partes com explicações.
Parte 1: VPC e Sub-redes
// network.tf
data "aws_availability_zones" "available" {}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "ecs-app-vpc"
}
}
resource "aws_subnet" "public" {
count = 2 // Criar 2 sub-redes públicas
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index + 2)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true // Atribui IP público automaticamente
tags = {
Name = "ecs-app-public-subnet-${count.index}"
}
}
resource "aws_subnet" "private" {
count = 2 // Criar 2 sub-redes privadas
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "ecs-app-private-subnet-${count.index}"
}
}
data "aws_availability_zones": Obtém a lista de Zonas de Disponibilidade (AZs) na sua região.resource "aws_vpc" "main": Define nossa VPC com um bloco de IPs10.0.0.0/16.resource "aws_subnet": Usamoscount = 2para criar duas sub-redes de cada tipo (pública e privada), uma em cada uma das duas primeiras AZs disponíveis, garantindo alta disponibilidade.- Referência de Recurso: Note como usamos
aws_vpc.main.idpara associar as sub-redes à nossa VPC. Esta é a sintaxe declarativa do Terraform para criar dependências.
Parte 2: Conectividade com a Internet
// network.tf (continuação)
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "ecs-app-igw"
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0" // Para todo o tráfego
gateway_id = aws_internet_gateway.gw.id // Enviar para o Internet Gateway
}
tags = {
Name = "ecs-app-public-rt"
}
}
resource "aws_route_table_association" "public" {
count = 2
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
aws_internet_gateway: Cria o gateway que permite a comunicação entre a VPC e a internet.aws_route_table: Define uma tabela de rotas que direciona todo o tráfego de saída (0.0.0.0/0) para o Internet Gateway.aws_route_table_association: Associa esta tabela de rotas às nossas sub-redes públicas.
Teste seu entendimento!
No bloco resource "aws_route_table_association" "public", estamos usando a expressão aws_subnet.public[count.index].id. Por que usamos [count.index] aqui, mas em resource "aws_internet_gateway" "gw" usamos aws_vpc.main.id diretamente?
Show answer
Usamos [count.index] porque o recurso aws_subnet.public foi definido com count = 2. Isso significa que o Terraform cria uma lista de duas sub-redes. aws_subnet.public refere-se a essa lista, e aws_subnet.public[0] e aws_subnet.public[1] referem-se aos elementos individuais. O count.index no recurso de associação itera sobre essa lista, criando uma associação para cada sub-rede.
Já o recurso aws_vpc.main foi definido sem count, então aws_vpc.main refere-se a um único objeto, e podemos acessar seus atributos (como .id) diretamente.
Neste ponto, você já tem uma rede funcional! Você pode validar seu trabalho executando terraform plan. Este comando deve mostrar que o Terraform planeja criar todos esses recursos de rede.
3. Definindo o Cluster ECS
Com a rede pronta, definir o cluster ECS é surpreendentemente simples. Um cluster ECS é um agrupamento lógico para seus serviços e tarefas. Com o Fargate, o cluster em si não tem custo nem provisiona servidores; ele atua como um namespace para organizar seus recursos de computação.
Vamos criar um novo arquivo, ecs.tf, para os recursos do ECS.
// ecs.tf
resource "aws_ecs_cluster" "main" {
name = "my-app-cluster" // Dê um nome ao seu cluster
tags = {
Name = "my-app-cluster"
}
}
Isso é tudo! Este simples bloco de código instrui o Terraform a criar um cluster ECS.
Para visualizar, o vídeo a seguir mostra a criação do cluster.
Take full control of ecs fargate using terraform
Esta seção do vídeo "Take full control of ecs fargate using terraform" demonstra a simplicidade de criar o recurso aws_ecs_cluster.
Assista do timestamp 03:55 a 04:30. Observe como o recurso aws_ecs_cluster é definido com apenas um nome.
4. Provisionando a Infraestrutura
Agora que todo o nosso código está escrito, vamos usar o fluxo de trabalho do Terraform para criar os recursos na AWS.
-
Planejar: Execute
terraform plannovamente. A saída agora deve incluir não apenas os recursos de rede, mas também oaws_ecs_cluster. Revise o plano para garantir que ele corresponde ao que você espera. -
Aplicar: Se o plano estiver correto, execute:
terraform applyO Terraform mostrará o plano novamente e pedirá sua confirmação. Digite
yese pressione Enter.
O processo pode levar alguns minutos. O Terraform provisionará a VPC, sub-redes, gateways, tabelas de rotas e o cluster ECS na sua conta AWS. Após a conclusão, você pode navegar pelo console da AWS para os serviços de VPC e ECS para ver seus novos recursos criados por código!
Conclusão
Parabéns! Você passou da teoria à prática e escreveu sua primeira configuração Terraform para provisionar uma infraestrutura de nuvem significativa.
Principais Pontos:
- Aprendemos a estruturar um projeto Terraform com
provider.tf,variables.tf, e arquivos de recursos comonetwork.tf. - Você escreveu código HCL para definir recursos da AWS, incluindo
aws_vpc,aws_subnet,aws_internet_gateway,aws_route_table, eaws_ecs_cluster. - Entendemos como referenciar atributos de um recurso para criar dependências, como usar
aws_vpc.main.idao criar uma sub-rede. - Utilizamos o fluxo de trabalho
terraform init,plan, eapplypara inicializar, visualizar e provisionar a infraestrutura.
Próxima Lição:
Nós construímos a fundação: a rede e o cluster. No entanto, ainda não há nada sendo executado. Na próxima lição, vamos definir o "o quê" e o "como" da nossa aplicação. Você aprenderá a usar o Terraform para definir uma Definição de Tarefa ECS (ECS Task Definition), que é o blueprint para nosso contêiner .NET, e um Serviço ECS (ECS Service), que é responsável por executar e manter o número desejado de instâncias da nossa tarefa no cluster.