AWS Route 53: Implementación Avanzada con Terraform
Introducción
AWS Route 53 es un servicio de DNS altamente disponible y escalable. En este artículo, exploraremos cómo implementar y gestionar una infraestructura DNS completa en AWS utilizando Terraform.

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
}