Alojar nuestro sitio estático sobre SSL con S3, ACM, CloudFront y Terraform
INFO
Esta publicación fue escrita originalmente el 4 de marzo de 2018
Publicación original: https://medium.com/runatlantis/hosting-our-static-site-over-ssl-with-s3-acm-cloudfront-and-terraform-513b799aec0f
En esta publicación cubro cómo alojé <www.runatlantis.io> usando
- S3 — para almacenar el sitio estático
- CloudFront — para servir el sitio estático sobre SSL
- AWS Certificate Manager — para generar los certificados SSL
- Route53 — para enrutar el nombre de dominio <www.runatlantis.io> a la ubicación correcta
Elegí Terraform en este caso porque Atlantis es una herramienta para automatizar y colaborar en Terraform en un equipo (ver github.com/runatlantis/atlantis), y por eso obviamente tenía sentido alojar nuestra página principal usando Terraform, pero también porque ahora es mucho más fácil de administrar. No tengo que entrar en la consola de AWS y hacer clic por todos lados para encontrar qué configuraciones quiero cambiar. En su lugar, simplemente puedo mirar ~100 líneas de código, hacer un cambio y ejecutar terraform apply.
INFO
NOTA: 4 meses después de este escrito, moví el sitio a Netlify porque compila automáticamente desde mi rama master ante cualquier cambio, actualiza más rápido ya que no necesito esperar a que expire la caché de Cloudfront y me da deploy previews de los cambios. Los registros DNS todavía están alojados en AWS.
Resumen
Hay una cantidad sorprendente de componentes requeridos para hacer que todo esto funcione, así que voy a comenzar con un resumen de para qué se necesita cada uno. Así es como se ve la arquitectura final:

Así es como se ve el producto final, pero comencemos con los pasos requeridos para llegar allí.
Paso 1 — Generar el sitio
El primer paso es tener un sitio generado. Nuestro sitio usa Hugo, un generador de sitios de Golang. Una vez que está configurado, solo necesitas ejecutar hugo y generará un directorio con HTML y todo tu contenido listo para alojar.
Paso 2 — Alojar el contenido
Una vez que tienes un sitio web, necesitas que sea accesible en internet. Usé S3 para esto porque es extremadamente barato y se integra bien con todos los otros componentes necesarios. Simplemente subo la carpeta de mi sitio web al bucket de S3.
Paso 3 — Generar un certificado SSL
Necesitaba generar un certificado SSL para https://www.runatlantis.io. Usé AWS Certificate Manager para esto porque es gratis y está integrado fácilmente con el resto del sistema.
Paso 4 — Configurar DNS
Como voy a alojar el sitio en servicios de AWS, necesito que las solicitudes a <www.runatlantis.io> sean enrutadas a esos servicios. Route53 es la solución obvia.
Paso 5 — Alojar con CloudFront
En este punto, hemos generado un certificado SSL para <www.runatlantis.io> y nuestro sitio web está disponible en internet a través de su URL de S3, así que ¿no podemos simplemente hacer un CNAME al bucket de S3 y darlo por terminado? Desafortunadamente no.
Como generamos nuestro propio certificado, necesitaríamos que S3 firme sus respuestas usando nuestro certificado. S3 no soporta esto y por lo tanto necesitamos CloudFront. CloudFront soporta usar nuestro propio certificado SSL y simplemente obtendrá sus datos del bucket de S3.
Momento de Terraform
Ahora que sabemos cómo debe verse nuestra arquitectura, simplemente es cuestión de escribir el Terraform.
Configuración inicial
Crea un nuevo archivo main.tf:
@include: ./publichosting-our-static-site/code/main.tf
Bucket de S3
Asumiendo que ya hemos generado el contenido de nuestro sitio, necesitamos crear un bucket de S3 para alojar el contenido.
@include: /publichosting-our-static-site/code/s3-bucket.tf
Ahora deberíamos poder ejecutar Terraform para crear el bucket de S3
terraform init
`terraform apply`
Ahora queremos subir nuestro contenido al bucket de S3:
$ cd dir/with/website
# generate the HTML
$ hugo -d generated
$ cd generated
# send it to our S3 bucket
$ aws s3 sync . s3://www.runatlantis.io/ # change this to your bucketAhora necesitamos la URL de S3 para ver nuestro contenido:
$ terraform state show aws_s3_bucket.www | grep website_endpoint
website_endpoint = www.runatlantis.io.s3-website-us-east-1.amazonaws.com¡Deberías ver tu sitio alojado en esa URL!
Certificado SSL
Usemos AWS Certificate Manager para crear nuestro certificado SSL.
@include hosting-our-static-site/code/ssl-cert.tf
Antes de ejecutar terraform apply, asegúrate de estar reenviando cualquiera de
administrator@your_domain_namehostmaster@your_domain_namepostmaster@your_domain_namewebmaster@your_domain_nameadmin@your_domain_name
A una dirección de correo electrónico a la que puedas acceder. Luego, ejecuta terraform apply y deberías recibir un correo electrónico de AWS para confirmar que eres propietario de este dominio, donde necesitarás hacer clic en el enlace.
CloudFront
Ahora estamos listos para que CloudFront aloje nuestro sitio web usando el bucket de S3 para el contenido y usando nuestro certificado SSL. ¡Advertencia! Hay mucho código más adelante, pero la mayor parte son solo valores predeterminados.
@include: hosting-our-static-site/code/cloudfront.tf
Aplica los cambios con terraform apply y luego encuentra el nombre de dominio que CloudFront nos da:
$ terraform state show aws_cloudfront_distribution.www_distribution | grep ^domain_name
domain_name = d1l8j8yicxhafq.cloudfront.netProbablemente obtendrás un error si vas a esa URL de inmediato. Necesitas esperar un par de minutos para que CloudFront se configure. A mí me tomó 10 minutos. Puedes ver su progreso en la consola: https://console.aws.amazon.com/cloudfront/home
DNS
¡Ya casi terminamos! Tenemos CloudFront alojando nuestro sitio, ahora necesitamos apuntar nuestro DNS hacia él.
@include: hosting-our-static-site/code/dns.tf
Si compraste tu dominio en otro lugar como Namecheap, necesitarás apuntar tu DNS a los nameservers listados en el state de la zona de Route53 que creaste. Primero terraform apply (lo que puede tardar un poco), luego averigua tus nameservers.
$ terraform state show aws_route53_zone.zone
id = Z2FNAJGFW912JG
comment = Managed by Terraform
force_destroy = false
name = runatlantis.io
name_servers.# = 4
name_servers.0 = ns-1349.awsdns-40.org
name_servers.1 = ns-1604.awsdns-08.co.uk
name_servers.2 = ns-412.awsdns-51.com
name_servers.3 = ns-938.awsdns-53.net
tags.% = 0
zone_id = Z2FNAJGFW912JGLuego revisa la documentación de tu dominio para saber cómo cambiar tus nameservers a los 4 listados.
¿Eso es todo...?
Una vez que el DNS se propague deberías ver tu sitio en https://www.yourdomain. Pero, ¿qué pasa con https://yourdomain? Es decir, sin el www.. ¿No debería esto redirigir a https://www.yourdomain?
Dominio raíz
Resulta que necesitamos crear un bucket de S3, una distribución de CloudFront y un registro de Route53 completamente nuevos solo para que esto ocurra. Eso es porque aunque S3 puede servir una redirección a la versión www de tu sitio, no puede alojar certificados SSL y por eso necesitas CloudFront. He incluido abajo todo el Terraform necesario para eso.
¡Felicitaciones! ¡Terminaste!
Si estás usando Terraform en un equipo, revisa Atlantis: https://github.com/runatlantis/atlantis para automatización y colaboración para hacer a tu equipo más feliz.
Aquí está el Terraform necesario para redirigir tu dominio raíz:
@include: hosting-our-static-site/code/full.tf