Criando uma VPC com subnets publicas e privadas para cada AZ com Terraform

guilinden

Guilherme Linden

Posted on July 22, 2023

Criando uma VPC com subnets publicas e privadas para cada AZ com Terraform

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

  1. Uma VPC
  2. Uma subnet privada para cada Availability Zone na região escolhida
  3. Uma subnet publica para cada Availability Zone na região escolhida
  4. Um Internet Gateway
  5. 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"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • provider.tf
provider "aws" {
  region = var.region
}
Enter fullscreen mode Exit fullscreen mode
  • variables.tf
variable "region" {
  type        = string
  description = "The AWS region name in which to deploy resources."
  default     = "us-west-2"
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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]
  }
}
Enter fullscreen mode Exit fullscreen mode

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]
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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 😁

💖 💪 🙅 🚩
guilinden
Guilherme Linden

Posted on July 22, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related