Alojar web estáticas usando S3 y Cloudfront (Con Terraform)
En el mundo digital de hoy, la velocidad y la confiabilidad son fundamentales para el éxito de cualquier sitio web. En este contexto, la arquitectura de sitios web estáticos ha ganado popularidad gracias a su simplicidad y eficiencia. Para llevar esta eficiencia al siguiente nivel, Amazon Web Services (AWS) ofrece un conjunto de servicios que se combinan perfectamente: AWS S3 y CloudFront. En este artículo, exploraremos la importancia de utilizar este stack para servir sitios web estáticos.
AWS S3, o Simple Storage Service, es el pilar inicial de esta poderosa arquitectura. S3 proporciona un almacenamiento altamente duradero y escalable, ideal para almacenar archivos estáticos como HTML, CSS, imágenes y archivos JavaScript. La simplicidad de S3 permite a los desarrolladores cargar y descargar fácilmente archivos, y su escalabilidad garantiza que los sitios web puedan crecer sin problemas con el tiempo.
La red de entrega de contenido (CDN) es esencial para garantizar que los usuarios de todo el mundo experimenten tiempos de carga rápidos. Aquí es donde entra AWS CloudFront. Al conectar CloudFront a un bucket S3, los archivos estáticos se distribuyen a través de una red global de servidores, reduciendo la latencia y mejorando la velocidad de carga.
A continuación, presentamos cómo podríamos levantar una infraestructura usando estas características, en terraform:
Paso 1. Configurar el provider:
provider "aws" {
region = "us-east-1"
}
Paso 2. Crear el bucket de s3, usaremos para ello el bucket oficial de S3:
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket = "my-s3-bucket"
acl = "private"
control_object_ownership = true
object_ownership = "ObjectWriter"
}
Paso 3. Creamos el cloudfront distribution.
module "cloudfront" {
source = "terraform-aws-modules/cloudfront/aws"
comment = "My awesome CloudFront"
enabled = true
create_origin_access_control = true
origin_access_control = {
s3_oac = {
description = "CloudFront access to S3"
origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
}
origin = {
s3_oac = { # with origin access control settings (recommended)
domain_name = module.s3_bucket.bucket_regional_domain_name
origin_access_control = "s3_oac" # key in `origin_access_control`
}
}
default_cache_behavior {
cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6" # CachingOptimized
allowed_methods = ["GET", "HEAD", "OPTIONS"]
target_origin_id = "s3_oac" # key in `origin`
}
}
Paso 4. Definimos las políticas de acceso para permitir que el OAC de cloudfront tenga acceso al bucket privado:
data "aws_iam_policy_document" "s3_policy" {
# Origin Access Identities
statement {
actions = ["s3:GetObject"]
resources = ["${module.s3_bucket.s3_bucket_arn}/static/*"]
principals {
type = "AWS"
identifiers = module.cloudfront.cloudfront_origin_access_identity_iam_arns
}
}
# Origin Access Controls
statement {
actions = ["s3:GetObject"]
resources = ["${module.s3_bucket.s3_bucket_arn}/static/*"]
principals {
type = "Service"
identifiers = ["cloudfront.amazonaws.com"]
}
condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = [module.cloudfront.cloudfront_distribution_arn]
}
}
}
resource "aws_s3_bucket_policy" "bucket_policy" {
bucket = module.s3_bucket.s3_bucket_id
policy = data.aws_iam_policy_document.s3_policy.json
}
Conclusión.
En definitiva este es un stack bastante usado y recomendado, que ayudará a reducir la cantidad de trabajo de operacíon y mantenimento de sitios estáticos basados en html, css y javascript, y además, reducirá costos dado que no hay un componente de cómputo detrás, y la utilización está almacenada en caché, por lo que se aceleraría al velocidad del sitio web estático.