Lección 2 de 412 min
Almacenamiento de objetos: Amazon S3
Buckets y objetos, clases de almacenamiento, permisos, URLs prefirmadas, versionado y webs estáticas.
Las fotos de perfil de tus usuarios, los PDF de las facturas, los vídeos de un curso, las copias de seguridad de la base de datos: nada de eso debería vivir en el disco de un servidor, que se llena, se estropea y no se comparte bien entre varias máquinas.
Amazon S3 (Simple Storage Service) es el almacenamiento de objetos de AWS: guardas archivos de cualquier tamaño a través de una API HTTP, pagas por lo que ocupan y te olvidas de los discos. Su API se ha convertido en un estándar de hecho, y servicios como Cloudflare R2 hablan el mismo idioma. En esta lección verás cómo se organiza, cuánto cuesta guardar según cómo leas y cómo compartir archivos sin hacerlos públicos.
Buckets, objetos y clases de almacenamiento
Buckets y objetos
Un espacio plano en el que cada archivo es un objeto identificado por su clave.
- Máximo por objeto:
- 5 TB
- Durabilidad de diseño:
- 99,999999999 %
Un bucket es un contenedor de objetos que vive en una región. Su nombre es único en todo AWS, no solo en tu cuenta, porque forma parte de su dirección: https://mis-fotos.s3.eu-west-1.amazonaws.com. Un objeto es un archivo, de unos pocos bytes a varios terabytes, más sus metadatos, como el tipo de contenido.
Cada objeto se identifica por su clave, su nombre completo: usuarios/42/avatar.png. Aunque la consola muestre carpetas, no existen: S3 es plano, y las «carpetas» son prefijos de la clave que la consola agrupa por el carácter /. Listar «una carpeta» es, en realidad, pedir los objetos cuyas claves empiezan por ese prefijo.
No puedes modificar un trozo de un objeto: lo sustituyes entero. A cambio, S3 ofrece consistencia fuerte: en cuanto termina una escritura, cualquier lectura posterior ve la versión nueva.
Úsalo cuando
Para cualquier archivo que suban tus usuarios o que genere tu aplicación: imágenes, documentos, exportaciones, copias de seguridad, registros o los archivos de una web estática.
Ten en cuenta
S3 no es un disco: no lo uses como sistema de archivos de una base de datos. Diseña las claves pensando en cómo las vas a listar (por usuario, por fecha) y no metas datos personales en ellas, porque aparecen en URLs y registros. Los archivos grandes se suben por partes (multipart upload).
# Crea un bucket en Irlanda y sube un archivo
aws s3 mb s3://mis-fotos-2026 --region eu-west-1
aws s3 cp avatar.png s3://mis-fotos-2026/usuarios/42/avatar.png
# «Listar una carpeta» es filtrar por prefijo
aws s3 ls s3://mis-fotos-2026/usuarios/42/
# Sincroniza una carpeta local (solo sube lo que cambió)
aws s3 sync ./dist s3://mi-web-estaticaClases de almacenamiento
El mismo objeto, más barato de guardar cuanto menos lo leas.
- Por defecto:
- S3 Standard
- La más barata:
- Glacier Deep Archive
Cada objeto tiene una clase de almacenamiento que fija su precio y su velocidad de acceso. S3 Standard es la clase por defecto, para datos que se leen a menudo. Standard-IA (Infrequent Access) cuesta menos por GB guardado, pero cobra cada lectura y factura un mínimo de 30 días por objeto.
La familia Glacier es para archivo: Glacier Instant Retrieval responde en milisegundos, Flexible Retrieval tarda de minutos a horas y Deep Archive, la más barata de todas, puede tardar horas. Intelligent-Tiering mueve cada objeto entre niveles según lo uses, a cambio de una pequeña tarifa de seguimiento por objeto.
Úsalo cuando
Standard para lo que se lee a diario; Standard-IA para copias o documentos que se consultan de vez en cuando; Glacier para archivo legal o copias que esperas no tocar nunca; Intelligent-Tiering cuando no sabes cómo se van a usar.
Ten en cuenta
Lo barato de guardar es caro de leer: pasar a IA o a Glacier datos que se leen mucho encarece la factura. Las permanencias mínimas se cobran enteras aunque borres antes, y en Flexible Retrieval y Deep Archive hay que restaurar el objeto antes de poder descargarlo.
# Sube una copia de seguridad directamente a Standard-IA
aws s3 cp copia-2026-11.sql.gz s3://copias-tienda/db/ \
--storage-class STANDARD_IA
# Un objeto en Deep Archive hay que restaurarlo antes de leerlo
aws s3api restore-object \
--bucket copias-tienda --key db/copia-2024-01.sql.gz \
--restore-request '{"Days": 3, "GlacierJobParameters": {"Tier": "Standard"}}'No solo pagas por el espacio
S3 también cobra por peticiones (cada PUT, GET o LIST) y por los datos que salen hacia Internet. En una web con mucho tráfico, esa transferencia suele pesar más que el almacenamiento. Por eso se pone una CDN delante, como CloudFront o la de Cloudflare, que verás en la próxima lección.
Permisos y URLs prefirmadas
Muchas filtraciones de datos famosas fueron buckets abiertos por error. La buena noticia es que S3 empieza cerrado; la clave está en abrir solo lo justo, a quien lo necesita y durante el tiempo necesario.
Permisos: privado por defecto
Nadie puede leer tus objetos hasta que una política lo permita expresamente.
- Por defecto:
- Privado
- ACL:
- Desactivadas en buckets nuevos
Un bucket nuevo es privado: solo tu cuenta puede acceder a él. Además, Block Public Access viene activado en los buckets nuevos y funciona como un interruptor general: aunque alguien escriba por error una política que abre el bucket a todo el mundo, S3 la bloquea.
Hay dos sitios donde dar permisos. Una política de IAM va pegada a una identidad (un usuario, un rol) y dice a qué buckets puede acceder. Una política de bucket va pegada al bucket y dice quién puede entrar, por eso lleva un campo Principal: sirve para dar acceso a otras cuentas o a un servicio como CloudFront. Las antiguas ACL por objeto siguen existiendo, pero AWS recomienda dejarlas desactivadas, y así vienen en los buckets nuevos.
Úsalo cuando
Políticas de IAM para tus propias aplicaciones y personas (el rol de tu función Lambda puede leer facturas/*); políticas de bucket para dar acceso a otras cuentas o a servicios de AWS, o para imponer reglas a todos, como exigir HTTPS.
Ten en cuenta
No desactives Block Public Access para servir archivos: para eso están CloudFront y las URLs prefirmadas. Y recuerda que una denegación explícita, en cualquiera de las dos políticas, gana siempre.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RechazarSinHTTPS",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::facturas-tienda", "arn:aws:s3:::facturas-tienda/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
}
]
}URLs prefirmadas
Un enlace temporal para subir o descargar un objeto concreto sin credenciales.
- Caducidad:
- La eliges al firmar
- Firma:
- Se calcula sin llamar a S3
Una URL prefirmada es la dirección de un objeto con una firma criptográfica y una caducidad en sus parámetros. La genera tu servidor con sus propias credenciales, sin llamar a S3, y quien la tenga puede hacer exactamente esa operación (descargar facturas/123.pdf, subir avatares/42.png) hasta que caduque.
Es el patrón estándar para subidas directas desde el navegador: el cliente pide una URL a tu API, tu API comprueba que ese usuario puede subir y la firma, y el navegador envía el archivo directamente a S3. Los megas no pasan por tu servidor, que ni se satura ni paga ese ancho de banda.
Úsalo cuando
Para descargar archivos privados (facturas, informes) y para que los usuarios suban archivos grandes sin que pasen por tu backend.
Ten en cuenta
Para subir desde el navegador, el bucket necesita una configuración CORS que admita tu dominio, como viste en el módulo de seguridad. Una URL de subida firmada para PUT apenas limita el tamaño del archivo: si lo necesitas, usa un POST prefirmado con condiciones y valida después lo que llegó. Pon caducidades cortas: cualquiera que tenga el enlace puede usarlo.
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3 = new S3Client({ region: "eu-west-1" });
// En tu API: firma una URL para que este usuario suba su avatar
export async function urlDeSubida(usuarioId: string) {
const comando = new PutObjectCommand({
Bucket: "avatares-tienda",
Key: `usuarios/${usuarioId}/avatar.png`,
ContentType: "image/png",
});
return getSignedUrl(s3, comando, { expiresIn: 300 }); // caduca en 5 minutos
}
// En el navegador:
// await fetch(url, { method: "PUT", body: archivo, headers: { "Content-Type": "image/png" } });Versiones, ciclo de vida y webs estáticas
Versionado y reglas de ciclo de vida
Conserva las versiones anteriores de cada objeto y automatiza cuándo moverlas o borrarlas.
- Versionado:
- Se suspende, no se desactiva
Con el versionado activado, sobrescribir un objeto no destruye el anterior: S3 guarda cada versión con su identificador. Borrar tampoco elimina nada: añade un marcador de borrado que oculta el objeto, y quitar ese marcador lo recupera. Es tu red de seguridad ante un error humano o un programa malicioso que cifra los archivos.
Las reglas de ciclo de vida automatizan la limpieza: mover objetos a Standard-IA a los 30 días y a Glacier a los 90, borrar los registros al cabo de un año, eliminar las versiones antiguas o las subidas por partes que quedaron a medias. Las aplica S3 sin que tengas que ejecutar nada.
Úsalo cuando
Activa el versionado en los buckets con datos que no puedes perder, como documentos de usuarios o copias. Usa reglas de ciclo de vida en cualquier bucket que crezca sin parar, como registros o exportaciones.
Ten en cuenta
Cada versión ocupa espacio y se cobra: sin una regla que caduque las versiones antiguas, un archivo que se sobrescribe a diario multiplica su coste. Y una vez activado, el versionado no se puede desactivar del todo, solo suspender.
{
"Rules": [
{
"ID": "registros",
"Filter": { "Prefix": "logs/" },
"Status": "Enabled",
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER" }
],
"Expiration": { "Days": 365 },
"NoncurrentVersionExpiration": { "NoncurrentDays": 30 },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
}
]
}Webs estáticas con CloudFront
Un bucket privado con tu web y una CDN delante que la sirve con HTTPS.
- CDN:
- Amazon CloudFront
- Acceso al bucket:
- OAC
Una web estática (HTML, CSS, JavaScript e imágenes ya generados, como la salida de vite build) no necesita servidor: basta con dejar los archivos en S3. S3 tiene una opción de «alojamiento de sitio web estático», pero esa dirección solo funciona con HTTP y exige que el bucket sea público.
La arquitectura recomendada es otra: bucket privado y CloudFront, la CDN de AWS, delante. CloudFront sirve los archivos desde ubicaciones cercanas al usuario, con HTTPS y tu dominio. Para que solo CloudFront pueda leer el bucket se usa Origin Access Control (OAC), que sustituye al antiguo OAI: CloudFront firma sus peticiones y la política del bucket solo admite las de tu distribución.
Úsalo cuando
Para landings, documentación, blogs generados y aplicaciones de una sola página (SPA) que hablan con una API.
Ten en cuenta
Tras desplegar, CloudFront sigue sirviendo la copia en caché hasta que caduca o la invalidas: usa nombres de archivo con hash para el JS y el CSS e invalida el index.html. En una SPA, rutas como /perfil no existen como archivo: configura una respuesta de error personalizada que devuelva index.html. Y el certificado de tu dominio debe estar en ACM, en us-east-1.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SoloMiDistribucion",
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mi-web-estatica/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/E1ABCDEF2GHIJ"
}
}
}
]
}Interactivo
Las clases de almacenamiento de S3
Valores orientativos: los precios exactos cambian según la región y con el tiempo, así que consulta la página de precios de S3 antes de decidir.
| Característica | S3 Standard | Intelligent-Tiering | Standard-IA |
|---|---|---|---|
| Pensada para | Datos que se leen a menudo | Uso desconocido o cambiante | Datos que se leen poco, pero se necesitan al instante |
| Coste de guardar | El más alto de las cuatro | Según el nivel de cada objeto, más una tarifa de seguimiento | Más bajo que Standard |
| Coste de leer | Solo peticiones y transferencia | Sin tarifa de recuperación | Cobra por cada GB leído |
| Tiempo hasta el primer byte | Milisegundos | Milisegundos en los niveles automáticos | Milisegundos |
| Permanencia mínima facturada | Ninguna | Ninguna | 30 días |
Ponlo en práctica
Saber qué es cada cosa es la mitad del trabajo. La otra mitad es reconocer cuándo usarla.
Interactivo
¿Qué usarías?
Lee cada situación y elige la opción que mejor la resuelve. Fallar aquí no cuenta: es para practicar.
Los usuarios de tu app suben vídeos de hasta 1 GB y tu servidor se queda sin memoria al recibirlos para reenviarlos a S3.
Para recordar
- S3 guarda objetos en un espacio plano: las «carpetas» son solo prefijos de la clave.
- Elige la clase por cómo se leen los datos: guardar barato significa leer caro, y las reglas de ciclo de vida mueven los objetos solas.
- Los buckets son privados por defecto y así deben quedarse: comparte con políticas, CloudFront o URLs prefirmadas, no abriéndolos.
- Las URLs prefirmadas permiten subir y descargar desde el navegador sin que los archivos pasen por tu servidor.
- El versionado te protege de borrados accidentales, pero necesita una regla que limpie las versiones antiguas.
Comprueba lo aprendido
Cuestionario
Responde las 5 preguntas para completar la lección.
1.En la consola de S3 ves la carpeta
fotos/. ¿Qué es en realidad?2.¿Por qué se usan URLs prefirmadas para que el navegador suba archivos?
3.Pasas a Standard-IA unas imágenes que se muestran miles de veces al día. ¿Qué le pasa a la factura?
4.¿Qué hace Origin Access Control (OAC) en una web estática con CloudFront?
5.Con el versionado activado, borras
contrato.pdf. ¿Qué ocurre?