Crear un bucket S3 público con CloudFormation

Resumen

Crear un bucket S3 con CloudFormation dentro de Serverless Framework te permite almacenar imágenes y firmar URLs sin salir de tu archivo serverless.yaml. Aprenderás a declarar el recurso, asignarle una política pública de lectura y desplegarlo junto al resto de tu infraestructura, ideal para desarrolladores backend que trabajan con AWS.

La idea central: aunque ninguna Lambda hable directamente con el bucket, puedes provisionarlo como un recurso extra usando la sintaxis nativa de CloudFormation dentro del bloque resources. Y aquí viene lo interesante: Serverless Framework no te limita a servicios serverless, te da todo el poder de CloudFormation.

¿Cómo declarar un bucket S3 dentro de serverless.yaml?

El primer paso es agregar el recurso al archivo serverless.yaml usando la sintaxis de CloudFormation. Esta sintaxis no es tan amigable como la propia de Serverless, así que el flujo común es buscar un ejemplo oficial y adaptarlo [01:30].

En la documentación de AWS encuentras plantillas tanto en JSON como en YAML. Para este caso usamos YAML porque es más legible. El fragmento mínimo que necesitas incluye:

  • El tipo de recurso: AWS::S3::Bucket.
  • La propiedad AccessControl con valor PublicRead para permitir lectura pública.
  • Un BucketName único a nivel global.

¿Por qué el nombre del bucket debe ser único globalmente? Porque S3 funciona como los nombres de dominio: el namespace es compartido por todas las cuentas del mundo. Si alguien ya registró ese nombre, no podrás usarlo.

Un ejemplo de nombre razonable es bucket-serverless-course seguido de números aleatorios para evitar colisiones [04:20].

¿Dónde va el recurso dentro del archivo?

El bucket se declara al mismo nivel que otros recursos como una tabla de DynamoDB, dentro del bloque resources. La indentación es crítica en YAML: si lo tabulas mal, el deploy fallará. Revisa que el bucket quede alineado con los demás recursos hermanos.

¿Qué es un bucket policy y por qué lo necesito?

Declarar el bucket no basta. Para que los objetos sean realmente legibles desde internet, necesitas un bucket policy que defina los permisos sobre el recurso. El policy le dice a S3 quién puede hacer qué sobre los objetos almacenados [05:40].

En este caso el objetivo es permitir lectura pública, así que buscamos en la documentación un ejemplo de AWS::S3::BucketPolicy. El policy se compone de:

  1. Una referencia al bucket al que aplica.
  2. Un Statement con la acción s3:GetObject.
  3. Un Resource que apunta al ARN del bucket y sus objetos.
  4. Un Principal que define quién recibe el permiso, en este caso * para acceso público.

¿Qué hace exactamente s3:GetObject? Es la acción que autoriza descargar o leer un objeto del bucket. Sin ese permiso, aunque el bucket sea público, nadie podría visualizar las imágenes desde una URL.

El policy debe referenciar el mismo bucket que CloudFormation va a crear. Para conectarlos usas el identificador lógico que diste al recurso (por ejemplo S3Bucket) y lo enlazas tanto en la propiedad Bucket como en el Resource del statement [07:15].

¿Cómo desplegar y verificar que el bucket quedó público?

Una vez declarados ambos recursos, ejecutas sls deploy y Serverless Framework hace el trabajo: compara el stack actual contra tu archivo, detecta los recursos nuevos y los crea vía CloudFormation. El bucket y el policy aparecen como elementos adicionales dentro del stack.

Un truco útil de troubleshooting: si un deploy tarda demasiado, probablemente hay un error y CloudFormation está haciendo rollback. Tu aplicación en producción no se ve afectada durante un rollback, pero conviene revisar los logs [09:50].

En este flujo apareció un error típico: olvidar las comillas en la versión, que debe ir como string. Al corregirlo y redesplegar, el stack se actualizó en segundos.

¿Cómo confirmo que el bucket es accesible públicamente?

Una vez creado, ve a la consola de AWS, abre el servicio S3 y busca el bucket por el nombre que definiste. Sube una imagen de prueba con el botón upload, entra al objeto y copia la URL pública que provee Amazon. Si abres esa URL en una pestaña nueva y ves la imagen, la configuración funciona [12:30].

Lo poderoso de este enfoque es que demuestra el alcance real del framework: puedes provisionar incluso una EC2 desde aquí, aunque no sea un servicio serverless. Tienes todo el potencial de CloudFormation más las funcionalidades extra de Serverless Framework.

Lo siguiente en este flujo es construir la Lambda que firme las URLs y se las devuelva al usuario, para que la subida de objetos no dependa de credenciales expuestas. ¿Has tenido problemas con nombres duplicados de buckets o con errores silenciosos en CloudFormation? Cuéntalo en los comentarios.