Networking Multi-AZ y Securizado en AWS con Terraform.
Levantando una Two Tier VPC con HA usando Terraform Modules
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
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:
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:
Ahora corremos un apply y confirmamos:
$ terraform apply
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:
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.