tutoriales.com

Gestionando Redes y Conectividad con Terraform y AWS VPC: Una Guía Esencial

Este tutorial te guiará a través del proceso de definición y gestión de tu infraestructura de red en AWS utilizando Terraform. Cubriremos la creación de VPCs, subredes, tablas de ruteo y gateways, elementos clave para una conectividad robusta y segura. Aprenderás a construir una red escalable y eficiente desde cero.

Intermedio20 min de lectura9 views
Reportar error

🚀 Introducción a AWS VPC y Terraform

En el mundo de la computación en la nube, la red es el cimiento sobre el que se construye toda tu infraestructura. AWS Virtual Private Cloud (VPC) te permite aprovisionar una sección aislada de la nube de AWS donde puedes lanzar recursos de AWS en una red virtual que defines. Con AWS VPC, tienes control total sobre tu entorno de red virtual, incluyendo la selección de tus propios rangos de direcciones IP, la creación de subredes, la configuración de tablas de ruteo y gateways de red. Esencialmente, es tu propio centro de datos virtual en la nube.

Sin embargo, la configuración manual de una VPC y todos sus componentes puede ser una tarea tediosa y propensa a errores, especialmente en entornos complejos o en crecimiento. Aquí es donde entra en juego Terraform, una herramienta de Infraestructura como Código (IaC). Terraform te permite definir tu infraestructura de red de manera declarativa usando código, lo que facilita la automatización, la versionación y la colaboración. Con Terraform, puedes replicar tus entornos de red de forma consistente y predecible, ahorrando tiempo y reduciendo la probabilidad de fallos.

Este tutorial te proporcionará una guía completa para gestionar tu infraestructura de red en AWS utilizando Terraform, cubriendo desde los conceptos básicos hasta la configuración de componentes esenciales como subredes, gateways y tablas de ruteo.

🎯 Objetivos del Tutorial

Al finalizar este tutorial, serás capaz de:

  • Entender los componentes clave de una AWS VPC.
  • Configurar un entorno de desarrollo para Terraform.
  • Definir y aprovisionar una VPC básica en AWS usando Terraform.
  • Crear subredes públicas y privadas dentro de tu VPC.
  • Configurar un Internet Gateway para permitir la comunicación con Internet.
  • Establecer tablas de ruteo para dirigir el tráfico de red.
  • Aprovisionar una Network Address Translation (NAT) Gateway para subredes privadas.
  • Aplicar y destruir la infraestructura de red de manera segura con Terraform.
💡 Consejo: Asegúrate de tener una cuenta de AWS activa y las credenciales de AWS configuradas en tu entorno local para que Terraform pueda interactuar con tu cuenta.

🛠️ Requisitos Previos

Antes de empezar, asegúrate de tener lo siguiente:

  • Una cuenta de AWS activa.
  • AWS CLI instalado y configurado con credenciales de acceso programático. Puedes seguir la guía oficial de AWS para configurarlo.
  • Terraform instalado en tu máquina local. Descárgalo desde el sitio web de HashiCorp.
  • Un editor de texto o IDE de tu preferencia (VS Code, Sublime Text, etc.).
Requisitos Listos

🌍 Componentes Fundamentales de una AWS VPC

Antes de sumergirnos en el código, es crucial entender los bloques de construcción de una VPC. Aquí están los componentes más importantes:

CIDR Block (Bloque CIDR)

Cada VPC debe tener un rango de direcciones IP primario en forma de bloque CIDR (Classless Inter-Domain Routing). Por ejemplo, 10.0.0.0/16. Este rango define el espacio total de IP disponibles para los recursos dentro de tu VPC. Los rangos de IP privados recomendados son 10.0.0.0/8, 172.16.0.0/12 y 192.168.0.0/16.

Subredes (Subnets)

Las subredes dividen tu VPC en segmentos más pequeños. Puedes tener subredes públicas (con acceso a Internet) y subredes privadas (sin acceso directo a Internet). Cada subred reside en una única Zona de Disponibilidad (Availability Zone) para alta disponibilidad. Por ejemplo, una VPC con 10.0.0.0/16 podría tener una subred pública 10.0.1.0/24 y una subred privada 10.0.2.0/24.

Internet Gateway (IGW)

Un Internet Gateway permite la comunicación entre tu VPC y el Internet. Es un componente que debes adjuntar a tu VPC y luego dirigir el tráfico de las subredes públicas a través de él mediante una tabla de ruteo.

NAT Gateway (NGW)

Un NAT Gateway permite que instancias en una subred privada inicien conexiones salientes a Internet (o a otros servicios de AWS) sin exponerse directamente al Internet entrante. Las NAT Gateways son altamente disponibles y se configuran en una subred pública. Se les asocia una Elastic IP Address.

Tablas de Ruteo (Route Tables)

Una tabla de ruteo contiene un conjunto de reglas, llamadas rutas, que determinan dónde se dirige el tráfico de red de tu subred o gateway de subred. Cada subred debe estar asociada a una tabla de ruteo.

Grupos de Seguridad (Security Groups)

Actúan como firewalls virtuales a nivel de instancia, controlando el tráfico entrante y saliente. Son stateful, lo que significa que si permites tráfico saliente, el tráfico de respuesta se permite automáticamente.

Network Access Control Lists (ACLs de Red)

Actúan como firewalls sin estado a nivel de subred, controlando el tráfico entrante y saliente de las subredes. Son stateless, por lo que debes permitir explícitamente tanto el tráfico entrante como el saliente para cualquier conexión.

Internet Internet Gateway AWS VPC (10.0.0.0/16) Subred Pública (10.0.1.0/24) Subred Privada (10.0.2.0/24) NAT Gateway

🏗️ Creando Nuestra Primera VPC con Terraform

Comencemos a construir nuestra infraestructura de red. Crearemos una estructura de archivos limpia para nuestro proyecto de Terraform.

📁 Estructura del Proyecto

Crea una carpeta para tu proyecto, por ejemplo, aws-vpc-terraform, y dentro de ella, los siguientes archivos:

aws-vpc-terraform/
├── main.tf
├── variables.tf
└── outputs.tf

variables.tf - Definición de Variables

Las variables permiten hacer tu configuración de Terraform más flexible y reutilizable. Define las variables esenciales para la VPC:

# variables.tf

variable "region" {
  description = "La región de AWS donde se aprovisionarán los recursos."
  type        = string
  default     = "us-east-1"
}

variable "project_name" {
  description = "Nombre del proyecto para los recursos."
  type        = string
  default     = "MyVPCProject"
}

variable "vpc_cidr_block" {
  description = "El bloque CIDR para la VPC."
  type        = string
  default     = "10.0.0.0/16"
}

variable "public_subnet_cidrs" {
  description = "Lista de bloques CIDR para subredes públicas."
  type        = list(string)
  default     = [
    "10.0.1.0/24",
    "10.0.2.0/24"
  ]
}

variable "private_subnet_cidrs" {
  description = "Lista de bloques CIDR para subredes privadas."
  type        = list(string)
  default     = [
    "10.0.10.0/24",
    "10.0.11.0/24"
  ]
}

variable "availability_zones" {
  description = "Lista de Zonas de Disponibilidad a usar."
  type        = list(string)
  default     = [
    "us-east-1a",
    "us-east-1b"
  ]
}

main.tf - Configuración Principal de la VPC

Este archivo contendrá la mayor parte de nuestra configuración de infraestructura. Empezaremos por definir el proveedor de AWS y la VPC.

# main.tf

# Configuración del proveedor de AWS
provider "aws" {
  region = var.region
}

# Recursos AWS que vamos a crear

# 1. Crear una VPC
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr_block
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "${var.project_name}-VPC"
  }
}

# 2. Crear un Internet Gateway
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "${var.project_name}-IGW"
  }
}

# 3. Crear subredes públicas
resource "aws_subnet" "public" {
  count             = length(var.public_subnet_cidrs)
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.public_subnet_cidrs[count.index]
  availability_zone = var.availability_zones[count.index % length(var.availability_zones)]
  map_public_ip_on_launch = true # Para que las instancias en esta subred obtengan una IP pública

  tags = {
    Name = "${var.project_name}-PublicSubnet-${count.index + 1}"
  }
}

# 4. Crear subredes privadas
resource "aws_subnet" "private" {
  count             = length(var.private_subnet_cidrs)
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.private_subnet_cidrs[count.index]
  availability_zone = var.availability_zones[count.index % length(var.availability_zones)]

  tags = {
    Name = "${var.project_name}-PrivateSubnet-${count.index + 1}"
  }
}

# 5. Crear una Elastic IP para la NAT Gateway
resource "aws_eip" "nat_gateway_eip" {
  count = length(var.public_subnet_cidrs) > 0 ? length(var.public_subnet_cidrs) : 0 # Solo si hay subredes públicas
  vpc   = true
  tags = {
    Name = "${var.project_name}-NAT-EIP-${count.index + 1}"
  }
}

# 6. Crear una NAT Gateway
resource "aws_nat_gateway" "main" {
  count         = length(aws_eip.nat_gateway_eip) > 0 ? length(aws_eip.nat_gateway_eip) : 0
  allocation_id = aws_eip.nat_gateway_eip[count.index].id
  subnet_id     = aws_subnet.public[count.index].id # Asocia la NAT Gateway a una subred pública

  tags = {
    Name = "${var.project_name}-NATGateway-${count.index + 1}"
  }
  depends_on = [aws_internet_gateway.main]
}

# 7. Crear la tabla de ruteo pública
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name = "${var.project_name}-PublicRouteTable"
  }
}

# 8. Asociar subredes públicas a la tabla de ruteo pública
resource "aws_route_table_association" "public" {
  count          = length(var.public_subnet_cidrs)
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

# 9. Crear la tabla de ruteo privada
resource "aws_route_table" "private" {
  count  = length(var.private_subnet_cidrs)
  vpc_id = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.main[count.index % length(aws_nat_gateway.main)].id # Distribuye NAT Gateways entre subredes privadas
  }

  tags = {
    Name = "${var.project_name}-PrivateRouteTable-${count.index + 1}"
  }
}

# 10. Asociar subredes privadas a sus respectivas tablas de ruteo privadas
resource "aws_route_table_association" "private" {
  count          = length(var.private_subnet_cidrs)
  subnet_id      = aws_subnet.private[count.index].id
  route_table_id = aws_route_table.private[count.index].id
}
🔥 Importante: La lógica de `count.index % length(var.availability_zones)` y `count.index % length(aws_nat_gateway.main)` se utiliza para distribuir los recursos (subredes en AZs, NAT Gateways entre tablas de ruteo privadas) de manera equitativa cuando el número de elementos en la variable `public_subnet_cidrs` o `private_subnet_cidrs` es mayor que el número de AZs o NAT Gateways respectivamente. Esto ayuda a garantizar la alta disponibilidad.

outputs.tf - Salidas de Terraform

Los outputs de Terraform te permiten exportar valores importantes de tu infraestructura para que puedan ser utilizados por otros módulos o simplemente para que los veas fácilmente después de aplicar la configuración.

# outputs.tf

output "vpc_id" {
  description = "El ID de la VPC creada."
  value       = aws_vpc.main.id
}

output "public_subnet_ids" {
  description = "Los IDs de las subredes públicas."
  value       = aws_subnet.public[*].id
}

output "private_subnet_ids" {
  description = "Los IDs de las subredes privadas."
  value       = aws_subnet.private[*].id
}

output "internet_gateway_id" {
  description = "El ID del Internet Gateway."
  value       = aws_internet_gateway.main.id
}

output "nat_gateway_ids" {
  description = "Los IDs de las NAT Gateways."
  value       = aws_nat_gateway.main[*].id
}

output "public_route_table_id" {
  description = "El ID de la tabla de ruteo pública."
  value       = aws_route_table.public.id
}

output "private_route_table_ids" {
  description = "Los IDs de las tablas de ruteo privadas."
  value       = aws_route_table.private[*].id
}

🚀 Despliegue de la Infraestructura con Terraform

Ahora que tenemos nuestros archivos .tf listos, es hora de desplegar la infraestructura.

1. Inicializar el Directorio de Trabajo de Terraform

Abre tu terminal, navega hasta el directorio aws-vpc-terraform y ejecuta:

terraform init

Este comando descarga los plugins necesarios para el proveedor de AWS. Deberías ver un mensaje de éxito.

2. Planificar el Despliegue

Antes de aplicar cualquier cambio, es buena práctica revisar el plan de ejecución de Terraform. Esto te mostrará exactamente qué recursos se crearán, modificarán o destruirán.

terraform plan

Revisa cuidadosamente el resultado. Deberías ver una lista de recursos que Terraform planea añadir (indicado con +). Asegúrate de que todo se alinea con lo que esperas.

3. Aplicar la Configuración

Si el plan parece correcto, procede a aplicar los cambios:

terraform apply

Terraform te pedirá que confirmes escribiendo yes. Una vez que lo hagas, Terraform comenzará a aprovisionar los recursos en tu cuenta de AWS. Este proceso puede tardar unos minutos. Cuando termine, verás los outputs que definimos en outputs.tf.

Paso 1: `terraform init` (Descarga plugins)
Paso 2: `terraform plan` (Previsualiza cambios)
Paso 3: `terraform apply` (Aplica los cambios)

4. Verificación en la Consola de AWS

Después de un terraform apply exitoso, puedes iniciar sesión en la Consola de AWS y navegar al servicio de VPC para verificar que todos los recursos (VPC, subredes, IGW, NAT Gateways, tablas de ruteo) se hayan creado correctamente.

¿Qué pasa si el `terraform apply` falla? Si el `terraform apply` falla, Terraform intentará revertir los cambios o dejará la infraestructura en un estado parcial. Consulta los mensajes de error en la terminal para diagnosticar el problema. Los errores comunes incluyen credenciales de AWS incorrectas, cuotas de servicio excedidas o bloques CIDR superpuestos.

🛡️ Consideraciones de Seguridad

La seguridad de tu red es primordial. Aunque este tutorial se centra en la conectividad básica, es importante tener en cuenta los siguientes aspectos:

  • Grupos de Seguridad y ACLs de Red: Complementa esta configuración de red con Grupos de Seguridad para tus instancias EC2 y ACLs de Red para tus subredes para controlar el tráfico a un nivel más granular.
  • VPC Flow Logs: Habilita los Flow Logs para monitorear el tráfico de tu VPC y ayudar en la detección de anomalías o problemas de seguridad.
  • Endpoint de VPC: Para servicios de AWS que no requieren acceso a Internet, considera usar VPC Endpoints para mantener el tráfico dentro de la red de AWS, mejorando la seguridad y reduciendo los costos de transferencia de datos.
AWS VPC Network ACLs Subnet A Subnet B EC2 Instance Security Groups Esquema de Seguridad en Capas (NACL: Subred | SG: Instancia)

🧹 Limpieza de Recursos

Es crucial limpiar los recursos de AWS que has creado para evitar cargos innecesarios. Terraform facilita esta tarea con el comando destroy.

Desde el directorio aws-vpc-terraform, ejecuta:

terraform destroy

Al igual que con apply, Terraform te mostrará un plan de lo que se destruirá (indicado con -) y te pedirá confirmación (yes). Confirma para que Terraform elimine todos los recursos que aprovisionó.

⚠️ Advertencia: El comando `terraform destroy` eliminará *todos* los recursos gestionados por esta configuración de Terraform. Asegúrate de que no estás destruyendo recursos en producción o que sean críticos.

📈 Escalabilidad y Reutilización

Módulos de Terraform

Para proyectos más grandes, es muy recomendable usar módulos de Terraform. Un módulo es una colección de archivos .tf almacenados en un directorio, que pueden ser reutilizados. Por ejemplo, podrías crear un módulo de VPC genérico que acepte variables y genere una VPC completa con subredes públicas y privadas, y luego reutilizar ese módulo en diferentes proyectos o entornos (desarrollo, staging, producción).

.aws-vpc-project/
├── main.tf
├── modules/
│   └── vpc/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── ...

En tu main.tf principal, podrías invocar el módulo así:

# En el main.tf de tu proyecto principal

module "my_application_vpc" {
  source = "./modules/vpc"

  project_name        = "AppEnv"
  vpc_cidr_block      = "10.10.0.0/16"
  public_subnet_cidrs = ["10.10.1.0/24"]
  private_subnet_cidrs = ["10.10.2.0/24"]
  availability_zones  = ["us-east-1a"]
}

module "another_application_vpc" {
  source = "./modules/vpc"

  project_name        = "OtherAppEnv"
  vpc_cidr_block      = "10.20.0.0/16"
  public_subnet_cidrs = ["10.20.1.0/24"]
  private_subnet_cidrs = ["10.20.2.0/24"]
  availability_zones  = ["us-east-1a", "us-east-1b"]
}

Esto promueve la metodología DRY (Don't Repeat Yourself) y asegura consistencia en tus despliegues de red.

Terraform Workspaces

Los workspaces de Terraform permiten gestionar múltiples entornos (ej. dev, staging, prod) dentro de la misma configuración de Terraform, utilizando el mismo código pero con diferentes estados. Esto es útil para probar cambios en un entorno aislado antes de aplicarlos a producción.

terraform workspace new dev
terraform workspace new staging
terraform workspace new prod

terraform workspace select dev
# ... apply changes for dev ...

terraform workspace select prod
# ... apply changes for prod ...
📌 Nota: Los workspaces no son un reemplazo para las diferentes carpetas o módulos cuando las configuraciones son muy dispares, pero son muy útiles para entornos que son estructuralmente idénticos pero con ligeras variaciones (como el tamaño de las instancias o el recuento de recursos).

Conclusión

Has completado una inmersión profunda en la gestión de redes en AWS utilizando Terraform. Ahora tienes las herramientas y el conocimiento para definir, desplegar y gestionar tu propia infraestructura de VPC de manera programática. Dominar Terraform para la gestión de VPCs es una habilidad invaluable que te permitirá construir entornos de nube escalables, seguros y fácilmente replicables. ¡Sigue experimentando y construyendo!

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!