Levantando una Two Tier VPC con HA usando Terraform Modules

portada

Objetivos

Levantar los siguientes recursos en AWS:

  • VPC
  • Subnets
  • Tablas de Ruteo
  • IGW
  • NAT GW

Y hacerlo de manera segura, utilizando las buenas prácticas de arquitectura que propone AWS, utilizando la herramienta Terraform y sus módulos oficiales de AWS.

Pre-requisitos:

  • Una cuenta AWS + set de keys
  • Conocimiento básico de AWS VPC
  • Conocimiento básico de networking
  • Buen conocimiento del Billing de AWS (para evitar sorpresas en dólares)

Intro

Es esencial conocer y aprovechar todos los conceptos y features que podemos implementar en nuestra VPC para mantener nuestras aplicaciones seguras y al mismo tiempo tener un esquema de alta disponibilidad para distribuir mejor el tráfico en caso de picos de workloads o para que nuestros clientes sigan operando en caso de haber algún problema en alguna zona en particular de AWS. Para el primer caso, vamos a configurar un esquema de subnets públicas y privadas de 2 niveles y para el segundo caso un esquema multi-az de 3 zonas.

ARQ

arq

Si tuviéramos que construir todo esto de manera manual desde la consola web de AWS sería algo más o menos parecido a esto:

  • Crear la VPC con el CIDR correspondiente.
  • Crear cada subnet (públicas y privadas) por separado y asociarlas a la VPC.
  • Configurar las subnes publicas (auto-assign IP settings)
  • Crear un IGW y atacharlo a la VPC
  • Crear una Route Table y configurar la ruta por default para que el IGW salga a internet.
  • Asociar esa Route Table a las subnets públicas
  • Crear y configurar 3 NAT gw para que las subnets privadas puedan salir a internet.
  • Crear 3 Route Tables más para asociarlas a las subnets privadas
  • Y un par de cosas más…

Todo esto lleva bastante tiempo independientemente de que tan groso seas manejando la consola o la CLI de aws, sumado a que si se hace siempre de manera manual, existe el riesgo de cometer errores.

IaC al Rescate !!!

Gracias a herramientas de IaC como Terraform, podemos realizar la definición de nuestra arquitectura una única vez y modificarla, correrla, borrarla etc las veces que se nos ocurra, y en caso de disaster recovery, salir a producción nuevamente en unos minutos.

Vamos a crear la siguiente estructura de archivos:

tree

Con el siguiente contenido:

main.tf

provider "aws" {
    region = "${var.region}"
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
}


resource "aws_eip" "nat" {
  count = 3
  vpc = true
}

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "mymware-blog-vpc"
    cidr = "10.0.0.0/20"

  azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
  public_subnets = ["10.0.2.0/24", "10.0.4.0/24", "10.0.6.0/24"]
  private_subnets  = ["10.0.12.0/24", "10.0.13.0/24", "10.0.14.0/24"]

  enable_nat_gateway = true
  single_nat_gateway  = false
  reuse_nat_ips       = true
  external_nat_ip_ids = "${aws_eip.nat.*.id}"

  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Terraform = "true"
    Environment = "dev"
  }
}

vars.tf

variable "access_key" {
    default         = "REEMPLAZAR"
    description     = "IAM Access Key"
}

variable "secret_key" {
    default         = "REEMPLAZAR"
    description     = "IAM Secret Key"
}

variable "region" {
    default         = "REEMPLAZAR"
    description     = "AWS Region"
}

outputs.tf

output "vpc_id" {
  description = "The ID of the VPC"
  value       = module.vpc.vpc_id
}

output "vpc_cidr_block" {
  description = "The CIDR block of the VPC"
  value       = module.vpc.vpc_cidr_block
}

output "private_subnets" {
  description = "List of IDs of private subnets"
  value       = module.vpc.private_subnets
}

output "public_subnets" {
  description = "List of IDs of public subnets"
  value       = module.vpc.public_subnets
}

output "nat_public_ips" {
  description = "List of public Elastic IPs created for AWS NAT Gateway"
  value       = module.vpc.nat_public_ips
}

output "azs" {
  description = "A list of availability zones spefified as argument to this module"
  value       = module.vpc.azs
}

Parece mentira que con estos 3 simples archivos de texto vamos a levantar todos los recursos descritos en la arquitectura, pero es así, esa es la magia de Terraform, sus módulos, cuando le decimos a terraform en el file main source = “terraform-aws-modules/vpc/aws” le estamos diciendo que vaya a internet y se descargue el módulo indicado, por supuesto es un módulo oficial, podríamos construir nuestro propios recursos de manera manual, pero usaremos el módulo ya probado y optimizado de Terraform para la construccion de VPC en AWS.

Inicializamos Terraform con:

$ terraform init

veremos como se comienza a descargar los módulos indicados (en este caso el de VPC) y veremos que toda esta info se guarda en el directorio donde está nuestro código terraform:

init

code

Ahora corremos un apply y confirmamos:

$ terraform apply

apply

output

Al final Terraform nos arroja el resultado que nosotros definimos en el file outputs con la información detallada de los recursos creados en AWS

Podemos corroborar esto ingresando a la consola de AWS:

apply

output

Como viste, pudimos crear una VPC de tres capas, respetando las buenas prácticas en cuanto a alta disponibilidad y seguridad de los datos, y todo en un par de minutos tirando solo un par de comandos, y lo más importante, lo tenemos todo como código, si… tenemos nuestra infra documentada y actualizada sin la necesidad de correr herramientas de escaneo o inventario de infraestructura.

La comunidad de Terraform nos abre el código de todos sus módulos para consultarlos, usarlos, modificarlos en el momento que queramos, les dejo en la siguiente sección el enlace a los módulos para trabajar sobre el cloud AWS.

Fuentes

Modulos de Terraform para AWS

VPC y Subnets

Diseño de VPC’s

VPC Single AZ

Invitame un CaféInvitame un Café