tutoriales.com

Aprovisionando y Gestionando Redes de Contenido (CDN) con Terraform y AWS CloudFront

Este tutorial detalla cómo utilizar Terraform para automatizar el aprovisionamiento y la gestión de distribuciones de AWS CloudFront, mejorando la entrega de contenido y reduciendo la latencia para tus usuarios globales. Exploraremos la configuración de orígenes S3, funciones Lambda@Edge y certificados SSL para una CDN robusta y segura.

Intermedio25 min de lectura12 views
Reportar error

🚀 Introducción a la Gestión de CDN con Terraform en AWS CloudFront

En la era digital actual, la velocidad y la fiabilidad son cruciales para la experiencia del usuario. Las Redes de Distribución de Contenido (CDN) son una herramienta indispensable para lograrlo, al acercar el contenido estático y dinámico a los usuarios finales, reduciendo la latencia y la carga en los servidores de origen. AWS CloudFront es una de las CDN más potentes y ampliamente utilizadas, ofreciendo integración profunda con otros servicios de AWS.

Tradicionalmente, configurar y gestionar CloudFront podía ser un proceso manual propenso a errores y difícil de escalar. Aquí es donde Terraform, la herramienta de Infraestructura como Código (IaC) de HashiCorp, se convierte en un aliado invaluable. Terraform nos permite definir la infraestructura de nuestra CDN de manera declarativa, versionarla, automatizar su despliegue y replicarla fácilmente en diferentes entornos. Esto no solo mejora la eficiencia, sino que también garantiza la consistencia y reduce el riesgo de configuraciones erróneas.

En este tutorial, exploraremos cómo utilizar Terraform para aprovisionar y gestionar una distribución de AWS CloudFront completa, incluyendo la configuración de orígenes (como buckets de S3), comportamientos de caché, certificados SSL/TLS, y funciones de borde para personalización avanzada con Lambda@Edge. Prepárate para dominar la gestión de tu CDN como un verdadero profesional de DevOps. 🛠️

¿Por qué Terraform para CloudFront? 🤔

La adopción de IaC con Terraform para gestionar CloudFront ofrece múltiples ventajas:

  • Consistencia: Asegura que tus configuraciones de CDN sean idénticas en todos los entornos (desarrollo, staging, producción), eliminando las desviaciones manuales.
  • Versionamiento: Tu infraestructura se gestiona como código, permitiendo el control de versiones, auditorías de cambios y la capacidad de revertir a estados anteriores si es necesario.
  • Automatización: Reduce el esfuerzo manual y los errores asociados con la configuración de una CDN compleja.
  • Escalabilidad: Despliega nuevas distribuciones o modifica las existentes con facilidad, adaptándote rápidamente a las necesidades de tu negocio.
  • Colaboración: Facilita el trabajo en equipo, ya que la definición de la infraestructura es un artefacto compartido y legible.

📋 Prerrequisitos

Antes de sumergirnos en el código, asegúrate de tener lo siguiente:

  • Cuenta de AWS: Una cuenta activa de Amazon Web Services.
  • Credenciales de AWS configuradas: Acceso a AWS CLI o variables de entorno AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY configuradas con los permisos adecuados para crear recursos de CloudFront, S3 y ACM.
  • Terraform instalado: La versión más reciente de Terraform (se recomienda la 1.0 o superior).
  • Dominio registrado: Un nombre de dominio personalizado (ej. miweb.com) si deseas utilizar un certificado SSL/TLS con tu distribución de CloudFront. Necesitarás tener control sobre este dominio para validar el certificado.
  • S3 Bucket para origen: Un bucket de S3 configurado para servir contenido estático. Si no lo tienes, lo crearemos como parte del tutorial.
💡 Consejo: Asegúrate de que tus credenciales de AWS tengan los permisos necesarios para IAM, S3, CloudFront y ACM (Amazon Certificate Manager). Los permisos excesivos son un riesgo de seguridad, pero para un tutorial, un perfil con permisos de administrador simplificará el proceso. En producción, aplica el principio de mínimo privilegio.

🎯 Paso 1: Configuración Inicial de Terraform y Proveedor AWS

Primero, crearemos la estructura de nuestro proyecto Terraform y definiremos el proveedor de AWS.

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

mkdir terraform-cloudfront-cdn
cd terraform-cloudfront-cdn
touch main.tf variables.tf outputs.tf

main.tf (Configuración del proveedor)

En main.tf, define el proveedor de AWS y la región en la que deseas desplegar tus recursos.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = ">= 1.0.0"
}

provider "aws" {
  region = var.aws_region
}

variables.tf (Definición de variables)

Aquí declararemos las variables que utilizaremos a lo largo de nuestra configuración. Esto hace que nuestro código sea más flexible y reutilizable.

variable "aws_region" {
  description = "La región de AWS donde se desplegarán los recursos."
  type        = string
  default     = "us-east-1" # CloudFront requiere certificados en us-east-1 para dominios personalizados
}

variable "domain_name" {
  description = "El nombre de dominio personalizado para la distribución de CloudFront (ej. miweb.com)."
  type        = string
}

variable "subdomain" {
  description = "El subdominio para la distribución de CloudFront (ej. cdn.miweb.com)."
  type        = string
  default     = "cdn"
}

variable "s3_bucket_name_prefix" {
  description = "Prefijo para el nombre del bucket S3."
  type        = string
  default     = "my-cloudfront-origin"
}

⚠️ Advertencia: Para que CloudFront use un certificado SSL/TLS personalizado, el certificado **debe** aprovisionarse en la región `us-east-1` (N. Virginia). Incluso si tu origen S3 o EC2 está en otra región, el certificado ACM debe estar en `us-east-1`. Por eso la variable `aws_region` por defecto es `us-east-1`.

outputs.tf (Valores de salida)

En este archivo, definiremos qué información queremos que Terraform nos muestre después de un despliegue exitoso, como el nombre de dominio de CloudFront.

output "cloudfront_distribution_domain_name" {
  description = "El nombre de dominio de la distribución de CloudFront."
  value       = aws_cloudfront_distribution.s3_distribution.domain_name
}

output "s3_bucket_website_endpoint" {
  description = "El endpoint del sitio web S3."
  value       = aws_s3_bucket_website_configuration.s3_website_config.website_endpoint
}

output "cloudfront_distribution_id" {
  description = "ID de la distribución de CloudFront."
  value       = aws_cloudfront_distribution.s3_distribution.id
}


🛠️ Paso 2: Aprovisionamiento de Origen S3 y Certificado SSL/TLS

Antes de configurar CloudFront, necesitamos un origen para servir el contenido y un certificado SSL/TLS para HTTPS si queremos usar un dominio personalizado.

Configuración del Bucket S3 para Contenido Estático

Agregaremos las siguientes configuraciones a main.tf.

# Bucket S3 para el contenido estático
resource "aws_s3_bucket" "content_bucket" {
  bucket = "${var.s3_bucket_name_prefix}-${random_id.bucket_suffix.hex}"

  tags = {
    Name        = "CloudFront Content Bucket"
    Environment = "Production"
  }
}

# Generar un sufijo aleatorio para el nombre del bucket
resource "random_id" "bucket_suffix" {
  byte_length = 8
}

# Habilitar el hosting de sitios web estáticos en el bucket S3
resource "aws_s3_bucket_website_configuration" "s3_website_config" {
  bucket = aws_s3_bucket.content_bucket.id

  index_document {
    suffix = "index.html"
  }

  error_document {
    key = "error.html"
  }
}

# Bloquear el acceso público al bucket S3 por defecto para mayor seguridad
resource "aws_s3_bucket_public_access_block" "content_bucket_public_access_block" {
  bucket                  = aws_s3_bucket.content_bucket.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# Política de bucket S3 para permitir el acceso desde CloudFront OAI (Origin Access Identity)
# Esto se actualizará después de crear el OAI
resource "aws_s3_bucket_policy" "content_bucket_policy" {
  bucket = aws_s3_bucket.content_bucket.id
  policy = data.aws_iam_policy_document.s3_policy.json
}

📌 Nota: Utilizamos random_id para garantizar que el nombre del bucket sea globalmente único, ya que los nombres de los buckets de S3 deben serlo. La política del bucket se definirá con un data block IAM para permitir el acceso solo desde CloudFront, garantizando que el bucket no sea públicamente accesible directamente.

Certificado SSL/TLS con AWS Certificate Manager (ACM)

Para usar HTTPS con tu propio dominio, necesitamos un certificado. Terraform puede solicitar y validar certificados a través de ACM.

# Solicitar un certificado SSL/TLS con AWS Certificate Manager (ACM)
resource "aws_acm_certificate" "cdn_certificate" {
  domain_name       = var.domain_name
  subject_alternative_names = ["*.${var.domain_name}"]
  validation_method = "DNS"

  tags = {
    Name        = "CDN Custom Domain Certificate"
    Environment = "Production"
  }

  lifecycle {
    create_before_destroy = true
  }
}

# Crear registros DNS para la validación del certificado ACM (si usas Route 53)
resource "aws_route53_record" "cdn_cert_validation" {
  for_each = {
    for dvo in aws_acm_certificate.cdn_certificate.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      type   = dvo.resource_record_type
      value  = dvo.resource_record_value
    }
  }

  zone_id = data.aws_route53_zone.selected.zone_id
  name    = each.value.name
  type    = each.value.type
  ttl     = 60
  records = [each.value.value]
}

# Esperar la validación del certificado
resource "aws_acm_certificate_validation" "cdn_certificate_validation" {
  certificate_arn         = aws_acm_certificate.cdn_certificate.arn
  validation_record_fqdns = [for record in aws_route53_record.cdn_cert_validation : record.fqdn]
}

# Obtener la zona de Route 53 para la validación del certificado
data "aws_route53_zone" "selected" {
  name         = "${var.domain_name}."
  private_zone = false
}

🔥 Importante: La validación de certificados con Route 53 (usando aws_route53_record) solo funciona si tu dominio está alojado en Route 53. Si tu proveedor de DNS es otro, deberás crear manualmente los registros CNAME que te proporcione ACM después de aplicar Terraform por primera vez o usar validation_method = "EMAIL" (menos recomendado para automatización).

¿Qué es subject_alternative_names?Las *Subject Alternative Names* (SANs) permiten que un certificado SSL proteja múltiples nombres de host (dominios y subdominios). En este caso, `*.${var.domain_name}` asegura que el certificado sea válido tanto para el dominio raíz como para cualquier subdominio, como `cdn.miweb.com`.

✨ Paso 3: Configuración de la Distribución de CloudFront

Ahora viene la parte principal: definir la distribución de CloudFront en main.tf.

Origin Access Identity (OAI)

CloudFront necesita una identidad para acceder de forma segura a tu bucket S3, sin que el bucket sea público. Esto se logra con una Origin Access Identity (OAI).

# Crear una Origin Access Identity (OAI) para CloudFront
resource "aws_cloudfront_origin_access_identity" "s3_oai" {
  comment = "OAI para acceso a bucket S3 de CloudFront"
}

# Actualizar la política del bucket S3 para permitir el acceso solo desde la OAI de CloudFront
data "aws_iam_policy_document" "s3_policy" {
  statement {
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.content_bucket.arn}/*"]

    principals {
      type        = "AWS"
      identifiers = [aws_cloudfront_origin_access_identity.s3_oai.iam_arn]
    }
  }
}

Definición de la Distribución de CloudFront

resource "aws_cloudfront_distribution" "s3_distribution" {
  # Habilitar la distribución
  enabled = true

  # Comentario para identificar la distribución
  comment = "Distribución CloudFront para ${var.domain_name}"

  # Orígenes (dónde CloudFront buscará el contenido)
  origin {
    domain_name = aws_s3_bucket.content_bucket.bucket_regional_domain_name
    origin_id   = "s3-origin-${aws_s3_bucket.content_bucket.id}"

    # Acceso seguro al bucket S3 a través de OAI
    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.s3_oai.cloudfront_access_identity_path
    }
  }

  # Configuración del comportamiento por defecto de caché
  default_cache_behavior {
    target_origin_id       = "s3-origin-${aws_s3_bucket.content_bucket.id}"
    viewer_protocol_policy = "redirect-to-https" # Forzar HTTPS
    allowed_methods        = ["GET", "HEAD", "OPTIONS"]
    cached_methods         = ["GET", "HEAD", "OPTIONS"]

    # Configuración de reenvío de cookies, encabezados y cadenas de consulta
    forwarded_values {
      query_string = false
      headers      = ["Origin", "Authorization"] # Ej. de encabezados a reenviar
      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 86400 # 24 horas
    max_ttl                = 31536000 # 1 año

    # Niveles de seguridad
    compress = true # Habilitar compresión Gzip
  }

  # Definir los nombres de dominio alternativos (CNAMEs) para tu CDN
  aliases = ["${var.subdomain}.${var.domain_name}"]

  # Configuración del visor
  viewer_certificate {
    cloudfront_default_certificate = false
    acm_certificate_arn            = aws_acm_certificate_validation.cdn_certificate_validation.certificate_arn
    ssl_support_method             = "sni-only"
    minimum_protocol_version       = "TLSv1.2_2021"
  }

  # Deshabilitar IPv6 si no es necesario (opcional)
  # is_ipv6_enabled = false

  # Registro de acceso (opcional, útil para análisis)
  # logging_config {
  #   bucket          = "mylogsbucket.s3.amazonaws.com"
  #   include_cookies = false
  #   prefix          = "cloudfront/"
  # }

  # WAF Web ACL (opcional, para mayor seguridad)
  # web_acl_id = aws_wafv2_web_acl.example.arn

  restrictions {
    geo_restriction {
      restriction_type = "none" # O "whitelist", "blacklist"
      # locations        = ["US", "CA"] # Si usas whitelist/blacklist
    }
  }

  # Habilitar el despliegue de IPv6
  is_ipv6_enabled = true

  price_class = "PriceClass_100" # O "PriceClass_200", "PriceClass_All" (más caro)

  # Para evitar problemas con el estado de despliegue al actualizar
  wait_for_deployment = false

  tags = {
    Name        = "CDN-${var.subdomain}"
    Environment = "Production"
  }
}

# Finalmente, crear el registro CNAME en Route 53 para apuntar el subdominio a CloudFront
resource "aws_route53_record" "cdn_cname" {
  zone_id = data.aws_route53_zone.selected.zone_id
  name    = "${var.subdomain}.${var.domain_name}"
  type    = "A"
  alias {
    name                   = aws_cloudfront_distribution.s3_distribution.domain_name
    zone_id                = aws_cloudfront_distribution.s3_distribution.hosted_zone_id
    evaluate_target_health = false
  }
}

💡 Consejo: La price_class determina el alcance geográfico de la CDN y, por lo tanto, el costo. PriceClass_100 utiliza los puntos de presencia de CloudFront con menor costo (principalmente EE. UU. y Europa), mientras que PriceClass_All utiliza todos los puntos de presencia globales, lo que reduce la latencia pero aumenta el costo significativamente. Elige según tus necesidades y presupuesto.


🔄 Paso 4: Despliegue y Validación

Una vez que todos los archivos están configurados, es hora de inicializar Terraform, planificar los cambios y aplicarlos.

Inicializar Terraform

Abre tu terminal en la carpeta terraform-cloudfront-cdn y ejecuta:

terraform init

Esto descargará los plugins necesarios para AWS.

Planificar y Aplicar Cambios

Antes de aplicar, siempre es una buena práctica revisar el plan de ejecución para entender qué recursos se crearán, modificarán o destruirán.

terraform plan -var="domain_name=tudominio.com" -var="subdomain=cdn"

Reemplaza tudominio.com con tu nombre de dominio real. Si todo se ve bien, aplica los cambios:

terraform apply -var="domain_name=tudominio.com" -var="subdomain=cdn"

Terraform te pedirá confirmación. Escribe yes y presiona Enter.

🔥 Importante: La validación del certificado ACM y el despliegue de CloudFront pueden tardar varios minutos (a veces hasta 20-30 minutos o más). Sé paciente. Si ves errores de validación, asegúrate de que los registros CNAME de ACM se hayan propagado correctamente en tu DNS.

Cargar Contenido en el Bucket S3

Mientras CloudFront se despliega, puedes cargar algunos archivos estáticos a tu bucket S3 para probar la CDN.

Crea un simple archivo index.html:

<!DOCTYPE html>
<html>
<head>
    <title>¡Mi CDN Funciona!</title>
</head>
<body>
    <h1>Hola desde mi CDN de CloudFront!</h1>
    <p>Este contenido se está sirviendo a través de S3 y CloudFront, gestionado con Terraform.</p>
</body>
</html>

Sube este archivo al bucket S3 que Terraform creó (puedes encontrar el nombre del bucket en los outputs o en la consola de S3).

aws s3 cp index.html s3://$(terraform output -raw s3_bucket_website_endpoint | cut -d'.' -f1)/

(Ajusta el comando aws s3 cp si tu s3_bucket_website_endpoint no es solo el nombre del bucket).

Validar la CDN

Una vez que la distribución de CloudFront esté completamente desplegada (su estado en la consola de AWS cambiará a Deployed), puedes acceder a tu contenido a través del nombre de dominio de CloudFront.

# Obtén el nombre de dominio de CloudFront
terraform output cloudfront_distribution_domain_name

# O si usaste un dominio personalizado:
echo "https://$(terraform output -raw cloudfront_distribution_domain_name)"
echo "https://${var.subdomain}.${var.domain_name}"

Visita https://cdn.tudominio.com/index.html (o el CNAME que configuraste) en tu navegador. Deberías ver el contenido de tu index.html servido de forma segura.

📌 Nota: Para verificar que el contenido se sirve desde CloudFront, puedes inspeccionar los encabezados de respuesta HTTP en el navegador (pestaña 'Red' en las herramientas de desarrollo). Deberías ver un encabezado como `x-cache: Hit from cloudfront` o `x-amz-cf-id`.
Origen (S3 Bucket) CloudFront Distribution Route 53 (CNAME / DNS) Usuario Final Dispositivo Flujo de Funcionamiento de CDN Flujo de Solicitud / Respuesta de Contenido
graph TD
    A[Usuario Final] -->|1. Solicita contenido| B(Navegador)
    B -->|2. Resolución DNS (Route 53)| C{DNS -> CloudFront CNAME}
    C -->|3. Redirige a CloudFront Edge Location| D[CloudFront Edge Location]
    D -->|4. Contenido en caché?| E{Cache Hit?}
    E -->|Sí| A
    E -->|No| F[CloudFront Origin Request]
    F -->|5. Solicita a Origen (S3)| G[S3 Bucket]
    G -->|6. Devuelve contenido a CloudFront| F
    D -->|7. Almacena en caché y entrega| A

⚙️ Paso 5: Personalización Avanzada con Comportamientos de Caché y Lambda@Edge (Opcional)

CloudFront permite una gran flexibilidad a través de comportamientos de caché adicionales y funciones Lambda@Edge. Esto va más allá de un simple default_cache_behavior.

Comportamientos de Caché Específicos

Puedes definir diferentes comportamientos de caché para rutas URL específicas. Por ejemplo, para un directorio /images/* o para APIs /api/*.

  ordered_cache_behavior {
    path_pattern           = "/images/*"
    target_origin_id       = "s3-origin-${aws_s3_bucket.content_bucket.id}"
    viewer_protocol_policy = "redirect-to-https"
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    compress               = true
    default_ttl            = 604800 # Imágenes en caché por una semana
    max_ttl                = 2592000 # 30 días

    forwarded_values {
      query_string = false
      headers      = []
      cookies {
        forward = "none"
      }
    }
  }

  ordered_cache_behavior {
    path_pattern           = "/api/*"
    target_origin_id       = "s3-origin-${aws_s3_bucket.content_bucket.id}" # Podría ser un origen diferente para API
    viewer_protocol_policy = "https-only"
    allowed_methods        = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods         = ["GET", "HEAD", "OPTIONS"]
    compress               = true
    default_ttl            = 0 # No cachear API por defecto
    max_ttl                = 0
    min_ttl                = 0

    forwarded_values {
      query_string = true # Reenviar query strings para API
      headers      = ["Authorization", "Content-Type", "Accept"]
      cookies {
        forward = "all" # Reenviar todas las cookies para API
      }
    }
  }

Estos ordered_cache_behavior se definen dentro del bloque aws_cloudfront_distribution.

⚠️ Advertencia: El orden de los `ordered_cache_behavior` importa. CloudFront evalúa los comportamientos en el orden en que aparecen y usa el primero que coincide con la ruta. Asegúrate de que los patrones más específicos estén antes que los más generales.

Integración con Lambda@Edge

Lambda@Edge permite ejecutar funciones AWS Lambda en los puntos de presencia de CloudFront, cerca de tus usuarios, para personalizar el contenido. Esto es ideal para manipulación de encabezados, reescritura de URLs, autenticación y más.

Para usar Lambda@Edge con Terraform, primero necesitas definir tu función Lambda.

# Asegúrate de tener el proveedor de AWS configurado para us-east-1 para Lambda@Edge
provider "aws" {
  alias  = "virginia"
  region = "us-east-1"
}

# Crear un rol IAM para la función Lambda@Edge
resource "aws_iam_role" "lambda_edge_role" {
  name = "lambda_edge_cloudfront_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          Service = [
            "lambda.amazonaws.com",
            "edgelambda.amazonaws.com"
          ]
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "lambda_edge_policy" {
  role       = aws_iam_role.lambda_edge_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

# Crear el código de la función Lambda (ejemplo: añadir un encabezado de seguridad)
resource "aws_lambda_function" "edge_function" {
  filename      = "lambda_function_payload.zip"
  function_name = "add-security-headers-edge"
  role          = aws_iam_role.lambda_edge_role.arn
  handler       = "index.handler"
  runtime       = "nodejs18.x"
  publish       = true # Esencial para Lambda@Edge

  # Crear un archivo ZIP con el código de la función
  # En un entorno real, usarías un build step o un S3 bucket para el código
  source_code_hash = filebase64sha256("lambda_function_payload.zip")

  # Timeout y memoria
  timeout     = 5
  memory_size = 128

  # Asegurarse de que el rol IAM esté disponible antes de crear la función
  depends_on = [aws_iam_role_policy_attachment.lambda_edge_policy]

  provider = aws.virginia # Usar el proveedor con alias para us-east-1
}

# Contenido del archivo lambda_function_payload.zip (crea este ZIP localmente)
# Dentro del ZIP, un archivo `index.js` podría contener:
#
# exports.handler = async (event) => {
#     const response = event.Records[0].cf.response;
#     const headers = response.headers;
#
#     // Añadir encabezados de seguridad
#     headers['strict-transport-security'] = [{
#         key: 'Strict-Transport-Security',
#         value: 'max-age=63072000; includeSubdomains; preload'
#     }];
#     headers['x-frame-options'] = [{
#         key: 'X-Frame-Options',
#         value: 'DENY'
#     }];
#     headers['x-xss-protection'] = [{
#         key: 'X-XSS-Protection',
#         value: '1; mode=block'
#     }];
#     headers['x-content-type-options'] = [{
#         key: 'X-Content-Type-Options',
#         value: 'nosniff'
#     }];
#     headers['referrer-policy'] = [{
#         key: 'Referrer-Policy',
#         value: 'no-referrer-when-downgrade'
#     }];
#
#     return response;
# };
#

Una vez que la función Lambda está desplegada, puedes asociarla a tu distribución de CloudFront dentro del bloque default_cache_behavior o en un ordered_cache_behavior:

  default_cache_behavior {
    # ... (otras configuraciones de default_cache_behavior)

    lambda_function_association {
      event_type   = "viewer-response" # O "viewer-request", "origin-request", "origin-response"
      lambda_arn   = aws_lambda_function.edge_function.qualified_arn
      include_body = false # Si necesitas el cuerpo de la solicitud/respuesta
    }
  }
90% Completado
Lambda@Edge es una característica avanzada que requiere un profundo conocimiento de los eventos de CloudFront y puede incurrir en costos adicionales. Úsala con precaución y pruebas exhaustivas.

🧹 Paso 6: Limpieza de Recursos

Cuando ya no necesites tus recursos de CloudFront y S3, es crucial eliminarlos para evitar cargos innecesarios en AWS.

Antes de ejecutar terraform destroy, asegúrate de que el bucket S3 esté vacío. CloudFront no se puede destruir si el bucket de origen tiene objetos, y Terraform tampoco puede eliminar un bucket no vacío por defecto.

Vaciar el Bucket S3

aws s3 rm s3://$(terraform output -raw s3_bucket_website_endpoint | cut -d'.' -f1)/ --recursive

Deshabilitar la Distribución de CloudFront (Opcional, a veces necesario para el destroy)

A veces, Terraform puede tener dificultades para destruir una distribución de CloudFront activa. Puedes deshabilitarla primero y luego destruirla. Esto podría implicar modificar enabled = false en main.tf y aplicar, y luego destruir.

# En main.tf, cambia enabled = true a enabled = false para aws_cloudfront_distribution.s3_distribution
# Aplica el cambio:
terraform apply -var="domain_name=tudominio.com" -var="subdomain=cdn"

# Espera a que el estado de la distribución sea 'Deployed' (deshabilitada)

# Luego, destruye:
terraform destroy -var="domain_name=tudominio.com" -var="subdomain=cdn"

Confirma con yes.

Paso 1: Vaciar S3 Bucket - Elimina todos los objetos para permitir la eliminación del bucket.
Paso 2: Deshabilitar CloudFront (Opcional) - Marca la distribución como `enabled = false` en Terraform y aplica los cambios.
Paso 3: Ejecutar `terraform destroy` - Elimina todos los recursos definidos por Terraform.

📚 Conclusión

En este tutorial, hemos recorrido el camino completo para aprovisionar y gestionar una potente Red de Distribución de Contenido (CDN) utilizando AWS CloudFront y Terraform. Hemos cubierto desde la configuración inicial del proveedor AWS y la creación de un origen S3, hasta la solicitud y validación de certificados SSL/TLS con ACM, la configuración de la distribución de CloudFront con acceso seguro vía OAI, y la integración de comportamientos de caché avanzados e incluso funciones Lambda@Edge para una personalización a nivel de borde.

La infraestructura como código con Terraform no solo simplifica la complejidad de CloudFront, sino que también te empodera para construir, modificar y replicar tu CDN de manera consistente y eficiente. Esta habilidad es fundamental en el mundo de DevOps, donde la automatización y la repetibilidad son clave para desplegar aplicaciones de alto rendimiento y disponibles globalmente.

¡Felicidades! Ahora tienes las herramientas y el conocimiento para llevar tus despliegues de contenido a un nuevo nivel de optimización y seguridad. Sigue experimentando con diferentes configuraciones de caché, orígenes múltiples y funciones Lambda@Edge para exprimir al máximo el potencial de tu CDN. El mundo digital es rápido, ¡y tu contenido también debería serlo! 🚀✅

Tutoriales relacionados

Comentarios (0)

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