← Volver al inicio

AWS Route 53: Implementación Avanzada con Terraform

Introducción

¿No sabes qué es Route 53 ni para qué sirve? Route 53 es el servicio de Amazon para gestionar nombres de dominio y direcciones en Internet (DNS). Es como la agenda de contactos de la nube de Amazon.

Con Route 53 puedes decidir a dónde van los visitantes cuando escriben tu dominio, y cómo se conectan tus aplicaciones.

En este artículo, te explico cómo crear y gestionar todo esto en AWS usando Terraform, una herramienta que te permite hacerlo todo con archivos de texto, aunque nunca lo hayas hecho antes.

Route 53 Architecture

Configuración de Zona Hospedada

# Zona DNS pública
resource "aws_route53_zone" "main" {
  name = "example.com"

  tags = {
    Environment = "Production"
    ManagedBy   = "Terraform"
  }
}

# Zona DNS privada
resource "aws_route53_zone" "private" {
  name = "internal.example.com"

  vpc {
    vpc_id = aws_vpc.main.id
  }

  tags = {
    Environment = "Production"
    Type        = "Private"
  }
}

Gestión de Registros DNS

# Registro A simple
resource "aws_route53_record" "www" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "www.example.com"
  type    = "A"
  ttl     = "300"
  records = ["203.0.113.1"]
}

# Registro ALIAS para ALB
resource "aws_route53_record" "alb" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "app.example.com"
  type    = "A"

  alias {
    name                   = aws_lb.main.dns_name
    zone_id                = aws_lb.main.zone_id
    evaluate_target_health = true
  }
}

# Registro de validación ACM
resource "aws_route53_record" "cert_validation" {
  for_each = {
    for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
      name    = dvo.resource_record_name
      record  = dvo.resource_record_value
      type    = dvo.resource_record_type
    }
  }

  allow_overwrite = true
  name            = each.value.name
  records         = [each.value.record]
  ttl             = 60
  type            = each.value.type
  zone_id         = aws_route53_zone.main.zone_id
}

Políticas de Enrutamiento Avanzadas

# Política de latencia
resource "aws_route53_record" "latency" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "api.example.com"
  type    = "A"

  latency_routing_policy {
    region = "us-west-2"
  }

  set_identifier = "us-west-2"
  records        = ["203.0.113.2"]
}

# Política de failover
resource "aws_route53_record" "primary" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "app.example.com"
  type    = "A"

  failover_routing_policy {
    type = "PRIMARY"
  }

  set_identifier = "primary"
  records        = ["203.0.113.3"]
  health_check_id = aws_route53_health_check.primary.id
}

resource "aws_route53_record" "secondary" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "app.example.com"
  type    = "A"

  failover_routing_policy {
    type = "SECONDARY"
  }

  set_identifier = "secondary"
  records        = ["203.0.113.4"]
}

Health Checks

resource "aws_route53_health_check" "primary" {
  fqdn              = "primary.example.com"
  port              = 443
  type              = "HTTPS"
  resource_path     = "/health"
  failure_threshold = "3"
  request_interval  = "30"

  tags = {
    Name = "primary-health-check"
  }
}

Integración con CloudFront

resource "aws_route53_record" "cdn" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "cdn.example.com"
  type    = "A"

  alias {
    name                   = aws_cloudfront_distribution.main.domain_name
    zone_id                = aws_cloudfront_distribution.main.hosted_zone_id
    evaluate_target_health = false
  }
}

Gestión Multi-región

# Política de geolocalización
resource "aws_route53_record" "geo" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "www.example.com"
  type    = "A"

  geolocation_routing_policy {
    country = "ES"
  }

  set_identifier = "spain"
  records        = ["203.0.113.5"]
}

# Política de peso
resource "aws_route53_record" "weighted" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "api.example.com"
  type    = "A"

  weighted_routing_policy {
    weight = 90
  }

  set_identifier = "primary"
  records        = ["203.0.113.6"]
}

Monitorización y Logs

resource "aws_route53_query_log" "main" {
  depends_on = [aws_cloudwatch_log_resource_policy.route53-query-logging]

  cloudwatch_log_group_arn = aws_cloudwatch_log_group.route53.arn
  zone_id                  = aws_route53_zone.main.zone_id
}

resource "aws_cloudwatch_log_group" "route53" {
  name              = "/aws/route53/${aws_route53_zone.main.name}"
  retention_in_days = 30
}

Referencias.