Provisionamento de AWS VPC base com terraform
Tags: community, aws, vpc, terraform
Published: 2024-01-29 00:20:21

A estrutura ilustrada abaixo é uma das mais convencionais para base de conectividade entre recursos AWS e internet.

Para simplicidade, representada em duas AZ’s, mas podendo ser implementada envolvendo todas as AZ’s de determinada Região e também utilizando dois NAT Gateway’s.

Implementando como código, o controle e agilidade são bem úteis.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6pgr1ake05kc2zita73n.jpg)

---

[Código terraform aqui.](https://github.com/paulofponciano/vpc-aws-auto-stack)

### Pré-requisitos

* [Terraform](https://www.terraform.io/downloads) instalado

* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) instalado

* Credenciais da conta alvo configuradas localmente

### O que esperar

* Provisionamento de uma VPC na região informada, duas subnets públicas e duas subnets privadas distribuídas entre duas zonas de disponibilidade (AZ)

* Criação de duas route tables para controlar direcionamento de saída para internet

* Provisionamento de Internet Gateway e NAT Gateway

* Associação entre rotas e subnets

### Variáveis

Entradas de informações que irão determinar como a estrutura será provisionada (Defina em ‘default’ sua necessidade):

```tf
# REGIAO DO PROVISIONAMENTO
variable "AWS_REGION" {
  default = "us-east-1"
}

# PRIMEIRA ZONA DE DISPONIBILIDATE (NAT GATEWAY PROVISIONADO NESTA AZ)
variable "az1" {
  default = "us-east-1a"
}

# SEGUNDA ZONA DE DISPONIBILIDADE
variable "az2" {
  default = "us-east-1b"
}

# USAR AQUI A IDENTIFICACAO DO AMBIENTE
variable "customer_env" {
  default = "company"
}

# CIDR VPC
variable "vpc_cidr_block" {
  default = "172.32.0.0/16"
}

# SUBNET PUBLICA (NAT GATEWAY PROVISIONADO NESTA SUBNET)
variable "subnet_public_1_cidr" {
  default = "172.32.0.0/20"
}

# SUBNET PUBLICA
variable "subnet_public_2_cidr" {
  default = "172.32.16.0/20"
}

# SUBNET PRIVADA
variable "subnet_private_1_cidr" {
  default = "172.32.32.0/20"
}

# SUBNET PRIVADA
variable "subnet_private_2_cidr" {
  default = "172.32.48.0/20"
}


```

### Construção

- Provisionamento da VPC:

```tf
# New VPC 'main-vpc'
resource "aws_vpc" "main-vpc" {
  cidr_block           = var.vpc_cidr_block
  instance_tenancy     = "default"
  enable_dns_support   = "true"
  enable_dns_hostnames = "true"
  enable_classiclink   = "false"
  tags = {
    Name = join("-",[var.customer_env, "vpc", var.AWS_REGION])
  }
}
```

- Criação de subnets entre as AZ’s:

```tf
resource "aws_subnet" "subnet-public-1" {
  vpc_id                  = aws_vpc.main-vpc.id
  cidr_block              = var.subnet_public_1_cidr
  map_public_ip_on_launch = "true"
  availability_zone       = var.az1

  tags = {
    Name = join("-",[var.customer_env, "subnet-public", var.az1])
  }
}

resource "aws_subnet" "subnet-public-2" {
  vpc_id                  = aws_vpc.main-vpc.id
  cidr_block              = var.subnet_public_2_cidr
  map_public_ip_on_launch = "true"
  availability_zone       = var.az2

  tags = {
    Name = join("-",[var.customer_env, "subnet-public", var.az2])
  }
}

resource "aws_subnet" "subnet-private-1" {
  vpc_id                  = aws_vpc.main-vpc.id
  cidr_block              = var.subnet_private_1_cidr
  map_public_ip_on_launch = "false"
  availability_zone       = var.az1

  tags = {
    Name = join("-",[var.customer_env, "subnet-private", var.az1])
  }
}

resource "aws_subnet" "subnet-private-2" {
  vpc_id                  = aws_vpc.main-vpc.id
  cidr_block              = var.subnet_private_2_cidr
  map_public_ip_on_launch = "false"
  availability_zone       = var.az2

  tags = {
    Name = join("-",[var.customer_env, "subnet-private", var.az2])
  }
}
```

- Internet Gateway:

```tf
resource "aws_internet_gateway" "main-igw" {
  vpc_id = aws_vpc.main-vpc.id

  tags = {
    Name = join("-",[var.customer_env, "igw"])
  }
}
```

- Criação de route table pública e associação com subnets públicas:

```tf
# Route table public
resource "aws_route_table" "rt-public" {
  vpc_id = aws_vpc.main-vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main-igw.id
  }

  tags = {
    Name = join("-",[var.customer_env, "rtb-public"])
  }
}

# Route associations public rt
resource "aws_route_table_association" "subnet-public-1" {
  subnet_id      = aws_subnet.subnet-public-1.id
  route_table_id = aws_route_table.rt-public.id
}

resource "aws_route_table_association" "subnet-public-2" {
  subnet_id      = aws_subnet.subnet-public-2.id
  route_table_id = aws_route_table.rt-public.id
}
```

- Criação de EIP e NAT Gateway:

```tf
# Nat Gateway for private subnets
resource "aws_eip" "eip-ngw-1" {
  vpc = true
  tags = {
    Name = join("-",[var.customer_env, "eip-ngw"])
  }
}

resource "aws_nat_gateway" "ngw-1" {
  allocation_id = aws_eip.eip-ngw-1.id
  subnet_id     = aws_subnet.subnet-public-1.id
  depends_on    = [aws_internet_gateway.main-igw]
  tags = {
    Name = join("-",[var.customer_env, "ngw"])
  }
}
```

- Criação de route table privada e associação com subnets privadas:

```tf
# Route table and route to ngw
resource "aws_route_table" "rt-private" {
  vpc_id = aws_vpc.main-vpc.id
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.ngw-1.id
  }

  tags = {
    Name = join("-",[var.customer_env, "rtb-private"])
  }
}

# Route associations private rt
resource "aws_route_table_association" "subnet-private-1" {
  subnet_id      = aws_subnet.subnet-private-1.id
  route_table_id = aws_route_table.rt-private.id
}

resource "aws_route_table_association" "subnet-private-2" {
  subnet_id      = aws_subnet.subnet-private-2.id
  route_table_id = aws_route_table.rt-private.id
}

```

Happy building!