Criando uma VPC com subnets publicas e privadas para cada AZ com Terraform
Guilherme Linden
Posted on July 22, 2023
Série EKS Cluster Production Ready
Esse post faz parte de uma série onde iremos construir a infraestrutura completa de um cluster Kubernetes no EKS pronto para produção. O primeiro passo para realizarmos isso é a criação de uma VPC.
Recursos que serão criados nesse tutorial
- Uma VPC
- Uma subnet privada para cada Availability Zone na região escolhida
- Uma subnet publica para cada Availability Zone na região escolhida
- Um Internet Gateway
- Uma Route Table para rotear o tráfego das subnets publicas para a internet através do Internet Gateway
Passo 0: Estruturando o projeto terraform com S3 backend
Estaremos utilizando um bucket S3 para salvar o estado do nosso projeto terraform, dessa forma diversas pessoas podem trabalhar no mesmo projeto tendo o state file centralizado. Para isso precisamos primeiro criar um bucket, que pode ser feito pela console ou pela cli:
aws s3api create-bucket --bucket "<account-id>-terraform-state-us-west-2" --create-bucket-configuration LocationConstraint=us-west-2 --region us-west-2
Com o bucket criado é necessário criar os arquivos de configuração do terraform para que ele utilize esse bucket para armazenar o state file:
- backend.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.9.0"
}
}
backend "s3" {
encrypt = true
workspace_key_prefix = "shared/networking"
key = "terraform.tfstate"
bucket = "<account-id>-terraform-state-us-west-2"
region = "us-west-2"
}
}
- provider.tf
provider "aws" {
region = var.region
}
- variables.tf
variable "region" {
type = string
description = "The AWS region name in which to deploy resources."
default = "us-west-2"
}
Com todos os arquivos criados, basta iniciar o terraform para que ele faça o download do provider e você possa iniciar a criar os recursos, para iniciar utilize o comando:
terraform init
Passo 1: Criando a VPC
Para criar uma VPC devemos definir um bloco de IPs para ela, nesse exemplo iremos utilizar a rede "172.25.0.0/16", todas as subnets que iremos criar futuramente pertencerão a essa rede. O recurso da VPC é bastante simples de criar no terraform:
- main.tf
resource "aws_vpc" "devops" {
cidr_block = "172.25.0.0/16"
tags = {
Name = "devops"
}
}
Passo 2: Criação das subnets privadas
Nossa VPC possuirá uma subnet privada para cada Availability Zone da região escolhida. Essas subnets, como o nome dizem, não terão acesso a internet de forma direta, servindo apenas para comunicação interna dentro da VPC.
Para a criação das subnets, iremos ler todas as Availability Zones disponíveis para a região escolhida, iterar sobre elas e através da função do terraform cidrsubnet criar de forma automática, com base na rede da VPC, uma subnet com prefixo /20 para cada AZ:
Portanto, primeiro precisamos criar o recurso data que nos retorne as AZs disponíveis:
- data.tf
data "aws_availability_zones" "available_zones" {
state = "available"
filter {
name = "region-name"
values = [var.region]
}
}
Agora podemos criar as subnets:
- maint.tf
resource "aws_subnet" "private" {
count = length(data.aws_availability_zones.available_zones.names)
vpc_id = aws_vpc.devops.id
cidr_block = cidrsubnet(aws_vpc.devops.cidr_block, 6, count.index)
availability_zone = data.aws_availability_zones.available_zones.names[count.index]
}
Passo 3: Criação das subnets publicas
Como no passo anterior, também iremos criar as subnets de forma automática utilizando a mesma estrutura. A principal diferença é que daremos como base para a criação das subnets a "metade final" do bloco da VPC, a rede 172.25.128.0/17. Para calcular essa rede também iremos utilizar a função cidrsubnet .
Importante notar que essas subnets terão a opção map_public_ip_on_launch = true
habilitada, para que cada instância iniciada nessas subnets possua um IP público associado a ela.
resource "aws_subnet" "public" {
count = length(data.aws_availability_zones.available_zones.names)
vpc_id = aws_vpc.devops.id
cidr_block = cidrsubnet(cidrsubnet(aws_vpc.devops.cidr_block, 2, 2), 6, count.index)
availability_zone = data.aws_availability_zones.available_zones.names[count.index]
map_public_ip_on_launch = true
tags = {
Public = "true"
}
}
Passo 4: Criando o Internet Gateway
Para que a subnet pública tenha acesso a internet, é necessário a criação de um Internet Gateway, que servirá, como o nome diz, de gateway para a tabela de roteamento que criaremos a seguir:
- main.tf
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.devops.id
tags = {
Name = "main"
}
}
Passo 5: Criando a tabela de roteamento e associando as subnets públicas
Com o Internet Gateway criado, basta criar uma tabela de roteamento que utilize esse gateway e então associar todas as subnets públicas a essa tabela.
- main.tf
resource "aws_route_table" "public" {
vpc_id = aws_vpc.devops.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "public"
}
}
resource "aws_route_table_association" "public" {
count = length(aws_subnet.public)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
Conclusão
Dessa forma, criamos uma VPC de forma automatizada utilizando infraestrutura como código através do Terraform. Com esse código, a VPC pode ser criada em qualquer região da AWS que as subnets serão provisionadas corretamente em todas as availability zones. 🚀
⠀
Notem, que o único parâmetro de rede que passamos foi o bloco de rede da VPC (172.25.0.0/16), todos os outros cálculos de subnet foram feitos de forma automática.
⠀
Todo o código criado aqui pode ser encontrado no meu github: https://github.com/guilinden/basic-vpc
⠀
O próximo passo é transformar isso em módulo terraform para poder ser reutilizado em diversos projetos, permitindo a rápida criação da estrutura base de uma VPC.
⠀
Para a criação do módulo terraform nos vemos no próximo post 😁
Posted on July 22, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.