DevOps desde Cero: DNS, TLS, y Como Hacer Tu App Accesible

2026-05-18 | Gabriel Garrido | 22 min de lectura
Share:

Apoya este blog

Si te resulta util este contenido, considera apoyar el blog.

Introduccion

Bienvenido al articulo diez de la serie DevOps desde Cero. En el articulo ocho deployeamos nuestra API TypeScript a ECS con Fargate y pusimos un Application Load Balancer adelante. Esa configuracion funciona, pero ahora mismo la unica forma de llegar a la API es a traves de un hostname auto-generado del ALB como task-api-alb-123456789.us-east-1.elb.amazonaws.com. Nadie quiere escribir eso en un navegador, y nadie deberia estar mandando trafico real por HTTP plano.


En este articulo vamos a resolver esos dos problemas. Vamos a registrar un dominio, configurar DNS para que una URL limpia como api.tudominio.com apunte a nuestro load balancer, y configurar TLS para que todo el trafico este cifrado con HTTPS. Al final, tu aplicacion va a ser accesible desde un dominio real con un certificado valido, exactamente como deberia ser un servicio en produccion.


Vamos a meternos de lleno.


Fundamentos de DNS: como tu navegador encuentra un servidor

DNS (Domain Name System) es la guia telefonica de internet. Cuando escribis google.com en tu navegador, tu computadora no sabe magicamente a que direccion IP conectarse. Le pregunta al sistema DNS, y DNS traduce ese nombre legible para humanos en una direccion IP legible para maquinas.


Aca esta el flujo simplificado de lo que pasa cuando visitas api.tudominio.com:


1. El navegador pregunta: "Cual es la IP de api.tudominio.com?"
2. Tu SO revisa su cache local. No la encuentra.
3. Tu SO le pregunta al resolver recursivo de tu ISP.
4. El resolver le pregunta a un nameserver raiz: "Quien maneja .com?"
5. El raiz dice: "Preguntale al nameserver TLD de .com."
6. El resolver le pregunta al TLD de .com: "Quien maneja tudominio.com?"
7. El TLD dice: "Preguntale a ns-1234.awsdns-56.org (el nameserver autoritativo)."
8. El resolver le pregunta al nameserver autoritativo: "Que es api.tudominio.com?"
9. El nameserver autoritativo responde: "Es un registro A apuntando a 54.23.45.67."
10. El navegador se conecta a 54.23.45.67.

Todo este proceso generalmente tarda menos de 100 milisegundos. Una vez resuelto, el resultado se cachea en multiples niveles para que las peticiones siguientes sean casi instantaneas.


Tipos de registros DNS que necesitas conocer

DNS no se trata solo de mapear nombres a direcciones IP. Hay varios tipos de registros, cada uno con un proposito diferente:


  • Registro A: Mapea un nombre de dominio a una direccion IPv4. Ejemplo: api.tudominio.com -> 54.23.45.67. Este es el tipo de registro mas basico.
  • Registro AAAA: Igual que A, pero para direcciones IPv6. Ejemplo: api.tudominio.com -> 2600:1f18:243:.... A medida que crece la adopcion de IPv6, vas a ver mas de estos.
  • Registro CNAME: Mapea un nombre de dominio a otro nombre de dominio (un alias). Ejemplo: www.tudominio.com -> tudominio.com. El resolver sigue la cadena hasta llegar a un registro A. Importante: no podes usar un CNAME en el apex de zona (el dominio pelado como tudominio.com).
  • Registro NS: Especifica los nameservers autoritativos para un dominio. Cuando registras un dominio, el registrador necesita saber que nameservers tienen los registros DNS de ese dominio.
  • Registro MX: Especifica los servidores de correo para un dominio. No es relevante para este articulo, pero te los vas a cruzar si alguna vez configuras email.
  • Registro TXT: Contiene texto arbitrario. Se usa para verificacion de dominio (probar que sos duenio de un dominio), registros SPF para email y validacion de certificados TLS (que vamos a usar mas adelante).

TTL: cuanto tiempo se cachean las respuestas DNS

Cada registro DNS tiene un TTL (Time To Live), medido en segundos. Le dice a los resolvers cuanto tiempo cachear la respuesta antes de volver a preguntar.


  • TTL alto (86400 = 24 horas): Bueno para registros que rara vez cambian. Reduce consultas DNS, mas rapido para los usuarios. Malo para cambios rapidos porque tenes que esperar a que expiren los caches.
  • TTL bajo (60 = 1 minuto): Bueno cuando esperas cambiar registros frecuentemente (durante migraciones, failovers). Mas consultas DNS, latencia ligeramente mayor en la primera peticion.
  • Estrategia comun: Mantene el TTL alto para operaciones normales. Antes de una migracion planificada, baja el TTL uno o dos dias antes, hace el cambio, verifica que funciona, y despues subi el TTL de vuelta.

Un error comun es olvidarse del TTL cuando haces una migracion. Si tu TTL es de 24 horas y cambias un registro A, algunos usuarios van a seguir pegandole a la IP vieja hasta por 24 horas. Planifica con anticipacion.


Route53: el servicio DNS de AWS

Route53 es el servicio de DNS gestionado de AWS. Es altamente disponible, distribuido globalmente y se integra nativamente con otros servicios de AWS. El nombre viene del hecho de que DNS usa el puerto 53.


El concepto central en Route53 es la hosted zone. Una hosted zone es un contenedor para registros DNS que pertenecen a un solo dominio. Cuando creas una hosted zone para tudominio.com, Route53 le asigna cuatro nameservers. Despues configuras tu registrador de dominios para que apunte a esos nameservers.


Hay dos tipos de hosted zones:


  • Hosted zone publica: Resuelve consultas desde internet publico. Esto es lo que necesitas para tu aplicacion de cara al usuario.
  • Hosted zone privada: Resuelve consultas solo dentro de una VPC. Util para service discovery interno (por ejemplo, database.internal.tudominio.com).

Politicas de ruteo de Route53

Route53 soporta varias politicas de ruteo que van mas alla de la simple resolucion “nombre a IP”:


  • Ruteo simple: Un registro, uno o mas valores. Route53 devuelve todos los valores en orden aleatorio. Este es el predeterminado y el que vamos a usar en este articulo.
  • Ruteo ponderado: Distribuye trafico entre multiples recursos por peso. Por ejemplo, mandar 90% del trafico a la version 1 y 10% a la version 2. Genial para deployments canary.
  • Ruteo por failover: Configuracion activo-pasivo. Route53 manda trafico al recurso primario. Si un health check falla, automaticamente cambia al recurso secundario.
  • Ruteo por latencia: Rutea usuarios a la region con menor latencia. Si tenes servidores en us-east-1 y eu-west-1, los usuarios europeos se rutean automaticamente a eu-west-1.
  • Ruteo por geolocalizacion: Rutea segun la ubicacion geografica del usuario. Util para compliance (mantener datos de usuarios de la UE en la UE) o servir contenido localizado.

Para la mayoria de las aplicaciones que recien arrancan, el ruteo simple es todo lo que necesitas. A medida que crecas y deployees en multiples regiones, las otras politicas se vuelven increiblemente valiosas.


Registro de dominio y delegacion de nameservers

Antes de poder usar Route53 para DNS, necesitas un nombre de dominio. Tenes dos opciones:


  • Registrar a traves de Route53: AWS actua como registrador y proveedor de DNS. Esta es la opcion mas simple porque la delegacion de nameservers pasa automaticamente.
  • Registrar en otro lado y delegar a Route53: Comprar tu dominio en un registrador como Namecheap, GoDaddy o Cloudflare, y despues actualizar los nameservers para que apunten a los registros NS de la hosted zone de Route53.

Si registraste tu dominio en otro lado, el proceso se ve asi:


1. Crear una hosted zone en Route53 para tudominio.com
2. Route53 asigna cuatro registros NS (ej: ns-1234.awsdns-56.org)
3. Ir al dashboard de tu registrador
4. Reemplazar los nameservers predeterminados con los cuatro NS de Route53
5. Esperar la propagacion (puede tardar hasta 48 horas, generalmente mucho mas rapido)
6. Ahora Route53 es autoritativo para tudominio.com

Una vez que la delegacion esta completa, cualquier registro DNS que crees en tu hosted zone de Route53 va a ser el que internet vea.


Registros Alias de Route53: una feature especial de AWS

El DNS estandar tiene una limitacion: no podes poner un registro CNAME en el apex de zona (el dominio pelado como tudominio.com). Esto es un problema porque los recursos de AWS como los ALBs y las distribuciones de CloudFront no tienen direcciones IP estaticas, asi que tampoco podes usar un registro A.


Route53 resuelve esto con los registros Alias. Un registro Alias se ve como un registro A o AAAA para los clientes DNS, pero detras de escena resuelve a otro recurso de AWS. Pensalo como un CNAME que funciona en el apex de zona.


  • Sin costo: Route53 no cobra por consultas a registros Alias que apuntan a recursos de AWS.
  • Compatible con apex de zona: Podes crear un registro Alias para tudominio.com apuntando a tu ALB.
  • Health check integrado: Los registros Alias pueden heredar health checks del recurso destino.

Vamos a usar un registro Alias para apuntar nuestro dominio a nuestro Application Load Balancer.


TLS/SSL: por que importa HTTPS

Ahora mismo nuestro ALB esta sirviendo trafico por HTTP en el puerto 80. Cada peticion y respuesta viaja por internet en texto plano. Cualquier persona entre el usuario y tu servidor (ISPs, operadores de Wi-Fi, cualquiera en la misma red) puede leer los datos, modificarlos o inyectar contenido.


TLS (Transport Layer Security) cifra la conexion entre el navegador del usuario y tu servidor. Cuando ves el icono del candado y https:// en tu navegador, eso significa que TLS esta en uso.


Por que importa HTTPS:


  • Confidencialidad: Los datos en transito estan cifrados. Passwords, API keys, informacion personal, todo esta protegido.
  • Integridad: Los datos no pueden ser modificados en transito. Nadie puede inyectar publicidad, malware o scripts de tracking en tus respuestas.
  • Autenticacion: El certificado prueba que el servidor es quien dice ser. Esto previene ataques man-in-the-middle.
  • SEO y confianza: Google usa HTTPS como senal de ranking desde 2014. Los navegadores marcan sitios HTTP como “No Seguro.” Los usuarios confian mas en sitios HTTPS.
  • Requerido para features modernas: HTTP/2, service workers, API de geolocalizacion y muchas otras features del navegador requieren HTTPS.

En resumen, no hay ninguna buena razon para servir trafico de produccion por HTTP.


Como funciona TLS (la version corta)

Cuando tu navegador se conecta a un servidor HTTPS, un proceso llamado TLS handshake ocurre antes de que se intercambie cualquier dato de aplicacion:


Cliente                              Servidor
  |                                    |
  |--- ClientHello (cifrados soportados) -->|
  |                                    |
  |<-- ServerHello + Certificado -------|
  |                                    |
  |--- Material de intercambio de claves -->|
  |                                    |
  |<-- Material de intercambio de claves ---|
  |                                    |
  |   (Ambos lados derivan clave de sesion) |
  |                                    |
  |<== Datos de aplicacion cifrados ===>|

  • ClientHello: El navegador envia las versiones de TLS y suites de cifrado que soporta.
  • ServerHello: El servidor elige una suite de cifrado y envia su certificado (que contiene la clave publica del servidor).
  • Validacion del certificado: El navegador verifica que el certificado fue emitido por una Autoridad Certificadora (CA) confiable, no esta expirado y coincide con el nombre de dominio.
  • Intercambio de claves: Ambos lados intercambian material de claves y derivan una clave de sesion compartida.
  • Comunicacion cifrada: Todos los datos subsiguientes se cifran con la clave de sesion usando cifrado simetrico (mucho mas rapido que el asimetrico).

Lo importante que te tenes que llevar es que necesitas un certificado TLS valido para tu dominio. Ahi es donde entra AWS Certificate Manager.


AWS Certificate Manager (ACM)

ACM es un servicio gratuito que te permite provisionar, gestionar y deployear certificados TLS para usar con servicios de AWS como ALB, CloudFront y API Gateway.


Los beneficios clave:


  • Gratis: Los certificados publicos son gratis cuando se usan con servicios de AWS. No necesitas pagarle a una CA.
  • Auto-renovacion: ACM renueva automaticamente los certificados antes de que expiren. Se acabaron los pages a las 3 AM porque un certificado expiro.
  • Validacion por DNS: Probas que sos duenio del dominio agregando un registro CNAME a tu DNS. Esto es completamente automatizable con Terraform.
  • Claves privadas gestionadas: ACM guarda la clave privada de forma segura. Nunca tenes que manejarla vos mismo.

El proceso para obtener un certificado con ACM se ve asi:


1. Solicitar un certificado para api.tudominio.com (y opcionalmente *.tudominio.com)
2. ACM te da un registro CNAME para agregar a tu DNS
3. Agregas el registro CNAME a tu hosted zone de Route53
4. ACM valida que sos duenio del dominio
5. El certificado se emite (generalmente en minutos)
6. ACM lo auto-renueva cada 13 meses

La validacion por DNS es preferible a la validacion por email porque se puede automatizar completamente y no requiere que alguien haga click en un link en un email.


Conectando todo: el panorama completo

Vamos a juntar todo lo que discutimos. Asi es como todas las piezas se conectan para hacer tu aplicacion accesible por HTTPS en un dominio real:


Navegador del usuario
     |
     | (Consulta DNS: api.tudominio.com)
     v
Hosted zone de Route53
     |
     | (Registro Alias -> ALB)
     v
Application Load Balancer
     |
     |--- Puerto 443 (HTTPS) -> Forward al target group (con certificado ACM)
     |--- Puerto 80  (HTTP)  -> Redirect a HTTPS
     |
     v
Tareas ECS Fargate (tus containers de la API)

  • Route53 resuelve api.tudominio.com a la direccion del ALB usando un registro Alias.
  • ACM provee el certificado TLS que el ALB usa para terminacion HTTPS.
  • ALB termina TLS, lo que significa que la conexion cifrada termina en el ALB. El trafico entre el ALB y tus tareas ECS viaja por HTTP dentro de tu VPC (lo cual esta bien porque es una red privada).
  • Redirect HTTP a HTTPS: El ALB escucha en el puerto 80 y automaticamente redirige al puerto 443, asi que usuarios que escriben http:// igual terminan en HTTPS.

Terraform: hosted zone de Route53

Escribamos el codigo Terraform. Vamos a construir sobre la infraestructura del articulo ocho. Primero, la hosted zone de Route53:


# dns.tf
variable "domain_name" {
  description = "The root domain name"
  type        = string
  default     = "yourdomain.com"
}

variable "api_subdomain" {
  description = "Subdomain for the API"
  type        = string
  default     = "api"
}

resource "aws_route53_zone" "main" {
  name = var.domain_name

  tags = {
    Name = var.domain_name
  }
}

Esto crea una hosted zone publica. Route53 automaticamente crea los registros NS y SOA. Despues de aplicar esto, necesitas copiar los cuatro registros NS y configurarlos en tu registrador de dominios. Solo necesitas hacer esto una vez.


Podes hacer output de los nameservers para saber que configurar:


output "nameservers" {
  description = "Nameservers for the hosted zone. Set these at your registrar."
  value       = aws_route53_zone.main.name_servers
}

Terraform: certificado ACM con validacion DNS

Despues, solicitamos un certificado TLS y lo validamos automaticamente a traves de DNS:


# acm.tf
resource "aws_acm_certificate" "app" {
  domain_name               = "${var.api_subdomain}.${var.domain_name}"
  subject_alternative_names = ["*.${var.domain_name}"]
  validation_method         = "DNS"

  lifecycle {
    create_before_destroy = true
  }

  tags = {
    Name = "${var.api_subdomain}.${var.domain_name}"
  }
}

resource "aws_route53_record" "acm_validation" {
  for_each = {
    for dvo in aws_acm_certificate.app.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
}

resource "aws_acm_certificate_validation" "app" {
  certificate_arn         = aws_acm_certificate.app.arn
  validation_record_fqdns = [for record in aws_route53_record.acm_validation : record.fqdn]
}

Desglosemos esto:


  • aws_acm_certificate solicita el certificado. Lo pedimos para api.tudominio.com con un SAN wildcard (*.tudominio.com) para que cubra cualquier subdominio.
  • validation_method = "DNS" le dice a ACM que vamos a probar ownership del dominio agregando registros DNS.
  • create_before_destroy = true asegura que al renovar, el nuevo certificado se crea antes de destruir el viejo. Esto previene downtime.
  • aws_route53_record.acm_validation crea los registros CNAME que ACM requiere para validacion. El loop for_each maneja el caso donde el certificado cubre multiples nombres de dominio.
  • aws_acm_certificate_validation es un recurso que espera. Terraform va a bloquear aca hasta que ACM confirme que el certificado esta validado y emitido. Esto generalmente tarda 2-5 minutos.

Terraform: listener HTTPS del ALB y redirect HTTP

En el articulo ocho, creamos un ALB con solo un listener HTTP. Ahora vamos a agregar un listener HTTPS y cambiar el listener HTTP para que redirija a HTTPS:


# alb.tf (actualizado)

# Cambiar el listener HTTP existente para redirigir
resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.app.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

# Agregar listener HTTPS
resource "aws_lb_listener" "https" {
  load_balancer_arn = aws_lb.app.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = aws_acm_certificate_validation.app.certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app.arn
  }
}

Detalles importantes:


  • El listener HTTP ahora devuelve un redirect 301 a HTTPS. Es un redirect permanente, asi que los navegadores y motores de busqueda lo van a recordar e ir directo a HTTPS la proxima vez.
  • El listener HTTPS referencia el certificado ACM validado. Nota que referenciamos aws_acm_certificate_validation.app.certificate_arn, no el certificado directamente. Esto asegura que Terraform espere a que la validacion se complete antes de crear el listener.
  • ssl_policy controla que versiones de TLS y suites de cifrado acepta el ALB. ELBSecurityPolicy-TLS13-1-2-2021-06 soporta TLS 1.2 y 1.3, que es la mejor practica actual. Politicas viejas que permiten TLS 1.0 o 1.1 no deberian usarse.

Tambien necesitas actualizar el security group del ALB para permitir trafico HTTPS:


# security_groups.tf (actualizado)
resource "aws_security_group" "alb" {
  name        = "${var.project_name}-alb-sg"
  description = "Security group for the Application Load Balancer"
  vpc_id      = aws_vpc.main.id

  ingress {
    description = "HTTP from anywhere (for redirect)"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "HTTPS from anywhere"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.project_name}-alb-sg"
  }
}

Mantenemos el puerto 80 abierto para que el redirect funcione. Si cerras el puerto 80, los usuarios que escriban http:// van a recibir un timeout de conexion en lugar de un redirect.


Terraform: registro Route53 apuntando al ALB

Finalmente, creamos el registro DNS que apunta nuestro dominio al load balancer:


# dns.tf (continuacion)
resource "aws_route53_record" "api" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "${var.api_subdomain}.${var.domain_name}"
  type    = "A"

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

Este es un registro Alias. Aunque es type = "A", no contiene una direccion IP hardcodeada. En cambio, apunta al DNS name del ALB. Route53 resuelve las direcciones IP actuales del ALB detras de escena y se las devuelve al cliente.


evaluate_target_health = true significa que si el ALB no tiene targets saludables, Route53 no va a devolver este registro en consultas DNS. Esto es util en configuraciones multi-region con ruteo por failover.


Health checks

Los health checks son la forma en que AWS determina si tu aplicacion esta realmente funcionando. Hay dos niveles de health checks en nuestra configuracion:


Health checks del target group del ALB


Ya los configuramos en el articulo ocho. El ALB periodicamente envia peticiones HTTP a tus tareas ECS en un path que vos definis (como /health). Si una tarea falla checks consecutivos, el ALB deja de mandarle trafico y ECS la reemplaza.


# Ya esta en nuestro target group del articulo 8
health_check {
  enabled             = true
  healthy_threshold   = 3
  unhealthy_threshold = 3
  timeout             = 5
  interval            = 30
  path                = "/health"
  protocol            = "HTTP"
  matcher             = "200"
}

Health checks de Route53


Los health checks de Route53 operan a nivel DNS. Monitorean un endpoint y pueden triggear failover DNS si el endpoint se cae. Son particularmente utiles cuando tenes recursos en multiples regiones:


# route53_health.tf
resource "aws_route53_health_check" "api" {
  fqdn              = "${var.api_subdomain}.${var.domain_name}"
  port               = 443
  type               = "HTTPS"
  resource_path      = "/health"
  failure_threshold  = 3
  request_interval   = 30
  measure_latency    = true

  tags = {
    Name = "${var.api_subdomain}.${var.domain_name}-health-check"
  }
}

  • type = "HTTPS" significa que Route53 se conecta por TLS para verificar el endpoint.
  • failure_threshold = 3 significa que tres fallas consecutivas marcan el endpoint como unhealthy.
  • request_interval = 30 verifica cada 30 segundos. Podes ponerlo en 10 para deteccion mas rapida, pero cuesta mas.
  • measure_latency = true trackea metricas de latencia en CloudWatch.

Para una configuracion de una sola region, los health checks de Route53 son opcionales pero estan buenos para monitoreo. Para multi-region con ruteo por failover, son esenciales.


La configuracion Terraform completa

Juntemos todo en una sola vista para que puedas ver como las piezas se conectan:


# Full dns.tf
variable "domain_name" {
  description = "The root domain name"
  type        = string
  default     = "yourdomain.com"
}

variable "api_subdomain" {
  description = "Subdomain for the API"
  type        = string
  default     = "api"
}

# Hosted zone
resource "aws_route53_zone" "main" {
  name = var.domain_name

  tags = {
    Name = var.domain_name
  }
}

# Certificado ACM
resource "aws_acm_certificate" "app" {
  domain_name               = "${var.api_subdomain}.${var.domain_name}"
  subject_alternative_names = ["*.${var.domain_name}"]
  validation_method         = "DNS"

  lifecycle {
    create_before_destroy = true
  }

  tags = {
    Name = "${var.api_subdomain}.${var.domain_name}"
  }
}

# Registros de validacion DNS para ACM
resource "aws_route53_record" "acm_validation" {
  for_each = {
    for dvo in aws_acm_certificate.app.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
}

# Esperar validacion del certificado
resource "aws_acm_certificate_validation" "app" {
  certificate_arn         = aws_acm_certificate.app.arn
  validation_record_fqdns = [for record in aws_route53_record.acm_validation : record.fqdn]
}

# Registro DNS apuntando al ALB
resource "aws_route53_record" "api" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "${var.api_subdomain}.${var.domain_name}"
  type    = "A"

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

# Outputs
output "nameservers" {
  description = "Nameservers for the hosted zone. Set these at your registrar."
  value       = aws_route53_zone.main.name_servers
}

output "app_url" {
  description = "The HTTPS URL for the API"
  value       = "https://${var.api_subdomain}.${var.domain_name}"
}

Aplicando los cambios

Ejecuta terraform plan primero para ver que se va a crear:


terraform plan

Deberias ver nuevos recursos para la hosted zone, certificado ACM, registros de validacion, listener HTTPS y el registro DNS. Una vez que estes conforme con el plan:


terraform apply

El recurso aws_acm_certificate_validation va a bloquear hasta que el certificado este validado. Esto generalmente tarda 2-5 minutos. Si tarda mas de 10 minutos, verifica que los registros CNAME de validacion se crearon correctamente en la hosted zone y que tus nameservers estan correctamente delegados.


Despues de que el apply se complete, actualiza tus nameservers en tu registrador si todavia no lo hiciste. Despues verifica que todo funcione:


# Verificar resolucion DNS
dig api.tudominio.com

# Probar HTTPS
curl -v https://api.tudominio.com/health

# Probar redirect HTTP
curl -v http://api.tudominio.com/health
# Deberia devolver un redirect 301 a https://

Debuggeando problemas de DNS

Los problemas de DNS son de los mas frustrantes de debuggear por el caching. Aca estan las herramientas y tecnicas que necesitas:


# Consultar un nameserver especifico directamente (saltear cache)
dig @ns-1234.awsdns-56.org api.tudominio.com

# Verificar todos los tipos de registro
dig api.tudominio.com ANY

# Trazar el camino completo de resolucion
dig +trace api.tudominio.com

# Verificar delegacion de nameservers
dig tudominio.com NS

# Verificar registros TXT (util para validacion ACM)
dig _acme-challenge.api.tudominio.com TXT

Problemas comunes y como solucionarlos:


  • “NXDOMAIN” (dominio no encontrado): Tus nameservers no estan correctamente delegados. Verifica los registros NS en tu registrador.
  • Se devuelve IP vieja: Caching de DNS. Espera a que expire el TTL, o usa dig @8.8.8.8 para verificar los resolvers de Google directamente.
  • Validacion ACM trabada: El nombre y valor del registro CNAME deben coincidir exactamente con lo que ACM espera. Verifica puntos al final o typos.
  • Certificado no valido para el dominio: El Common Name o SAN del certificado no coincide con el dominio. Asegurate de haber solicitado el certificado para el nombre de dominio correcto.

Una nota sobre CloudFront (CDN)

Hasta ahora conectamos usuarios directamente a nuestro ALB a traves de Route53. Esto funciona bien, pero para aplicaciones que sirven assets estaticos (imagenes, CSS, JavaScript) o tienen usuarios distribuidos por todo el mundo, deberias considerar poner CloudFront adelante de tu ALB.


CloudFront es el CDN (Content Delivery Network) de AWS. Cachea tu contenido en edge locations alrededor del mundo, asi que los usuarios reciben respuestas de un servidor que esta geograficamente cerca de ellos en lugar de desde tu region de origen.


Sin CloudFront:
  Usuario en Tokio -> Route53 -> ALB en us-east-1 (200ms de latencia)

Con CloudFront:
  Usuario en Tokio -> Route53 -> Edge de CloudFront en Tokio (cacheado, 20ms)
                                    |
                                    v (solo en cache miss)
                              ALB en us-east-1

Beneficios de CloudFront:


  • Menor latencia: Contenido servido desde la edge location mas cercana.
  • Menor carga en el origen: Las respuestas cacheadas no pegan en tu ALB ni en tus tareas ECS.
  • Proteccion DDoS: CloudFront se integra con AWS Shield para mitigacion de DDoS.
  • Certificados ACM gratis: CloudFront usa certificados ACM de us-east-1 (esto es un requisito, el certificado debe estar en us-east-1 sin importar donde este tu origen).

No vamos a configurar CloudFront en este articulo ya que merece su propio deep dive, pero tenelo en mente para cuando necesites optimizar performance para una audiencia global.


Desglose de costos

Veamos cuanto cuesta esta configuracion:


  • Hosted zone de Route53: $0.50/mes por hosted zone.
  • Consultas Route53: $0.40 por millon de consultas. Para la mayoria de las aplicaciones esto es despreciable.
  • Health checks de Route53: $0.50/mes para un health check HTTPS basico. $1.00/mes con medicion de latencia.
  • Certificados ACM: Gratis cuando se usan con servicios de AWS (ALB, CloudFront, API Gateway).
  • ALB: El ALB ya era parte de nuestra configuracion ECS. Sin costo adicional por terminacion HTTPS.

Costo adicional total por DNS y TLS: aproximadamente $1-2/mes. Esta es una de las mejoras mas baratas y de mayor valor que podes hacer a tu infraestructura.


Mejores practicas de seguridad

Antes de cerrar, aca van algunas practicas de seguridad a tener en cuenta:


  • Siempre redirigir HTTP a HTTPS: Nunca sirvas trafico de produccion por HTTP plano.
  • Usar una politica TLS moderna: ELBSecurityPolicy-TLS13-1-2-2021-06 o mas nueva. Deshabilitar TLS 1.0 y 1.1.
  • Habilitar HSTS: Agrega el header Strict-Transport-Security en tu aplicacion para decirle a los navegadores que siempre usen HTTPS. Esto previene ataques de downgrade.
  • Usar certificados separados por entorno: No reutilices certificados de produccion en staging. ACM es gratis, asi que no hay razon para no tener certificados separados.
  • Monitorear expiracion de certificados: Aunque ACM auto-renueva, configura una alarma de CloudWatch para la expiracion del certificado como red de seguridad. Si la validacion DNS falla por alguna razon, la auto-renovacion va a fallar silenciosamente.

Notas de cierre

Tu aplicacion ahora es accesible en un dominio real por HTTPS. Cubrimos mucho terreno en este articulo: fundamentos de DNS y tipos de registros, hosted zones y politicas de ruteo de Route53, certificados TLS con ACM, terminacion HTTPS en el ALB, redirects de HTTP a HTTPS, health checks tanto a nivel ALB como DNS, y el codigo Terraform para provisionar todo.


Este es un hito en la serie. Tu API TypeScript ahora esta corriendo en containers en ECS, detras de un load balancer, con auto-scaling, accesible en una URL limpia por una conexion cifrada. Eso es una configuracion de grado produccion.


En el proximo articulo, vamos a ver monitoreo y observabilidad para que puedas ver que esta haciendo tu aplicacion en produccion y detectar problemas antes de que lo hagan tus usuarios.


Espero que te haya resultado util y que lo hayas disfrutado, hasta la proxima!


Errata

Si encontras algun error o tenes alguna sugerencia, por favor mandame un mensaje para que se corrija.

Tambien, podes revisar el codigo fuente y los cambios en los fuentes aca



$ Comentarios

Online: 0

Por favor inicie sesión para poder escribir comentarios.

2026-05-18 | Gabriel Garrido