La lección anterior dejó una regla clara: una aplicación que escala horizontalmente no puede guardar nada en su disco local. Y Contoso Airlines genera un fichero por cada venta: la tarjeta de embarque en PDF. Ese fichero tiene que vivir en algún sitio al que lleguen todas las instancias, que aguante millones de objetos, que sea barato y que permita dar al cliente un enlace de descarga sin abrir el almacén entero a internet.
Ese sitio es Azure Storage. En el módulo 1 ya creaste la cuenta sttarjetascontosodev con su contenedor tarjetas-embarque, HTTPS obligatorio y acceso anónimo desactivado, pero dejaste aplazada una decisión importante: qué redundancia usar en desarrollo y cuál en producción. Esta lección recoge ese cabo suelto y lo cierra.
Aprenderás qué son los cuatro servicios que caben en una cuenta de almacenamiento, cómo funciona Blob Storage en detalle (tipos de blob, niveles de acceso y reglas de ciclo de vida), para qué sirven Azure Files, Queue Storage y Table Storage, cómo se protege el acceso con firmas de acceso compartido e identidades, y qué herramientas usar en cada caso. Al final montarás el flujo real de Contoso: subir una tarjeta de embarque, generar un enlace temporal para el pasajero y programar que el fichero se abarate solo con el tiempo.
Aviso de coste: el almacenamiento se factura por GB al mes, por operaciones y por salida de datos. Los ejemplos de esta lección mueven kilobytes y cuestan céntimos, pero las cuentas de almacenamiento olvidadas se acumulan. Al final tienes la limpieza.
Contenido
- La cuenta de almacenamiento: un recurso, cuatro servicios
- Blob Storage: contenedores y tipos de blob
- Niveles de acceso: Hot, Cool, Cold y Archive
- Reglas de ciclo de vida: las tarjetas de embarque de Contoso
- Azure Files: el recurso compartido de la oficina
- Queue Storage: desacoplar la emisión de tarjetas
- Table Storage y su relación con Cosmos DB
- Redundancia: LRS, ZRS, GRS, GZRS y RA-GRS
- Seguridad de acceso: claves, SAS e identidades
- Cifrado, versionado, instantáneas y eliminación temporal
- Herramientas:
az storage, AzCopy y Storage Explorer - Ejemplo completo: la tarjeta de embarque de principio a fin
- Limpieza
- Errores Comunes y Consejos
- Ejercicios
- Conclusión
- La cuenta de almacenamiento: un recurso, cuatro servicios
Una cuenta de almacenamiento es el contenedor de facturación, seguridad y configuración de hasta cuatro servicios de datos distintos, cada uno con su propio punto de conexión:
| Servicio | Para qué sirve | Punto de conexión |
|---|---|---|
| Blob | Objetos no estructurados: PDF, imágenes, copias, registros | https://<cuenta>.blob.core.windows.net |
| File | Recursos compartidos de red por SMB o NFS | https://<cuenta>.file.core.windows.net |
| Queue | Colas de mensajes sencillas para desacoplar procesos | https://<cuenta>.queue.core.windows.net |
| Table | Almacén NoSQL de clave-valor, muy barato | https://<cuenta>.table.core.windows.net |
Al crear la cuenta eliges dos cosas que condicionan todo lo demás:
| Decisión | Opciones | Qué implica |
|---|---|---|
| Tipo de cuenta | StorageV2 (uso general v2), BlockBlobStorage (premium para blobs), FileStorage (premium para archivos) |
StorageV2 es la opción por defecto y la correcta salvo necesidad específica |
| Rendimiento | Standard (HDD por detrás) o Premium (SSD, latencia baja) | Standard admite los cuatro servicios; Premium se especializa por tipo |
Y una restricción que sorprende a todos: el nombre de la cuenta es globalmente único, entre 3 y 24 caracteres, solo minúsculas y números. Nada de guiones. Por eso las cuentas de Contoso se llaman sttarjetascontosodev y sttarjetascontosopro y no siguen el patrón con guiones del resto de recursos.
Recordatorio de lo creado en el módulo 1, con el comando completo por si necesitas rehacerlo:
az storage account create \
--resource-group rg-contoso-reservas-dev \
--name sttarjetascontosodev \
--location westeurope \
--sku Standard_LRS \
--kind StorageV2 \
--https-only true \
--min-tls-version TLS1_2 \
--allow-blob-public-access false \
--tags entorno=desarrollo proyecto=contoso-reservas \
centro-coste=CC-1042 [email protected] \
--output table--allow-blob-public-access false es la línea que impide que nadie pueda abrir un contenedor al público por error. Con ella activada a nivel de cuenta, ninguna configuración de contenedor puede exponer los ficheros anónimamente.
- Blob Storage: contenedores y tipos de blob
La jerarquía de Blob Storage tiene tres niveles y no más:
Cuenta de almacenamiento (sttarjetascontosopro)
└── Contenedor (tarjetas-embarque)
└── Blob (2026/08/IB3241-20260814-A7K2.pdf)No existen carpetas reales: lo que parece una jerarquía son nombres de blob con barras. Las herramientas la muestran como si fuera un árbol, pero para el servicio es un nombre plano. Esto tiene una consecuencia práctica útil: puedes listar «una carpeta» con un prefijo, y es una operación eficiente.
Los tres tipos de blob
| Tipo | Cómo funciona | Tamaño máximo | Casos de uso |
|---|---|---|---|
| En bloques (block) | Se compone de bloques que se suben en paralelo y se confirman | ~190 TiB | El 95 % de los casos: PDF, imágenes, vídeo, copias, ZIP |
| De anexos (append) | Solo permite añadir al final; optimizado para escritura secuencial | ~195 GiB | Registros de auditoría, ficheros de log |
| De páginas (page) | Acceso aleatorio por páginas de 512 bytes | 8 TiB | Discos de VM (los discos gestionados son blobs de páginas por debajo) |
Para las tarjetas de embarque de Contoso: blobs en bloques, sin duda.
Operaciones básicas con la CLI
CUENTA="sttarjetascontosodev"
CONTENEDOR="tarjetas-embarque"
# Crear el contenedor. --auth-mode login usa tu identidad de Entra ID
# en lugar de la clave de la cuenta: es la forma recomendada.
az storage container create \
--account-name "${CUENTA}" \
--name "${CONTENEDOR}" \
--auth-mode login \
--public-access off \
--output table
# Subir una tarjeta de embarque.
az storage blob upload \
--account-name "${CUENTA}" \
--container-name "${CONTENEDOR}" \
--name "2026/08/IB3241-20260814-A7K2.pdf" \
--file ./tarjeta.pdf \
--content-type "application/pdf" \
--auth-mode login \
--overwrite
# Listar las tarjetas de agosto de 2026 usando el prefijo.
az storage blob list \
--account-name "${CUENTA}" \
--container-name "${CONTENEDOR}" \
--prefix "2026/08/" \
--auth-mode login \
--query "[].{Nombre:name, Bytes:properties.contentLength, Nivel:properties.blobTier}" \
--output tableFíjate en --content-type "application/pdf": sin él, el navegador puede descargar el fichero en lugar de mostrarlo. Es un detalle pequeño que genera muchas incidencias de soporte.
Consejo de diseño del nombre: 2026/08/IB3241-20260814-A7K2.pdf incluye año, mes, vuelo, fecha y localizador. Ese esquema permite listar por periodo con prefijos y aplicar reglas de ciclo de vida por carpeta. Un nombre plano tipo tarjeta12345.pdf funciona igual de bien para leer, pero te deja sin herramientas para gestionar el ciclo de vida.
- Niveles de acceso: Hot, Cool, Cold y Archive
Aquí está el mecanismo con el que Azure Storage se abarata de verdad. Cada blob tiene un nivel de acceso que intercambia coste de almacenamiento por coste y tiempo de recuperación.
| Nivel | Coste de almacenamiento | Coste de acceso | Permanencia mínima | Disponibilidad | Uso previsto |
|---|---|---|---|---|---|
| Hot | El más alto | El más bajo | Ninguna | Inmediata | Datos en uso activo |
| Cool | ~50 % menos que Hot | Mayor por operación y por GB leído | 30 días | Inmediata | Datos de los últimos meses, acceso ocasional |
| Cold | Menor que Cool | Mayor que Cool | 90 días | Inmediata | Datos que casi no se tocan pero deben estar disponibles ya |
| Archive | El más bajo, con diferencia | El más alto, y con espera | 180 días | Requiere rehidratación: de 1 a 15 horas | Retención legal, copias históricas |
Cuatro reglas que evitan sustos:
- La permanencia mínima se factura aunque borres antes. Si subes un blob a Cool y lo borras a los 3 días, pagas los 30. Cambiar de nivel demasiado pronto también cuenta como borrado anticipado.
- Archive no se lee. Un blob en Archive está fuera de línea: hay que rehidratarlo (
az storage blob set-tier --rehydrate-priority High) y esperar horas. No sirve para nada que un cliente pueda pedir en caliente. - El nivel se aplica por blob, aunque la cuenta tenga un nivel predeterminado para los blobs nuevos.
- Bajar de nivel ahorra en almacenamiento pero encarece cada lectura. Si un fichero se lee cada semana, Cool puede salir más caro que Hot.
El patrón de uso de las tarjetas de embarque de Contoso, medido por Diego Salas:
| Antigüedad de la tarjeta | Descargas | Nivel adecuado |
|---|---|---|
| 0–7 días (antes y durante el vuelo) | Muy alto: el pasajero la abre varias veces | Hot |
| 8–90 días (reclamaciones, justificantes de gasto) | Bajo pero real | Cool |
| 91 días – 5 años (retención legal y fiscal) | Casi nulo | Archive |
| Más de 5 años | Ninguna | Borrar |
Ese patrón se traduce directamente en una regla de ciclo de vida.
- Reglas de ciclo de vida: las tarjetas de embarque de Contoso
Una regla de ciclo de vida (lifecycle management) es una política que Azure ejecuta a diario sobre los blobs de la cuenta, moviéndolos de nivel o borrándolos según su antigüedad. Es automática y gratuita: solo pagas las operaciones que genera.
{
"rules": [
{
"enabled": true,
"name": "ciclo-tarjetas-embarque",
"type": "Lifecycle",
"definition": {
"filters": {
"blobTypes": [ "blockBlob" ],
"prefixMatch": [ "tarjetas-embarque/" ]
},
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 },
"tierToArchive": { "daysAfterModificationGreaterThan": 90 },
"delete": { "daysAfterModificationGreaterThan": 1825 }
},
"snapshot": {
"delete": { "daysAfterCreationGreaterThan": 90 }
}
}
}
}
]
}Lectura del documento, apartado por apartado:
filters.blobTypes: solo afecta a blobs en bloques (los de páginas de un disco no deben moverse jamás a Cool).filters.prefixMatch: el prefijo empieza por el nombre del contenedor, no por el nombre del blob. Es el error de sintaxis más frecuente de estas reglas.tierToCoola los 30 días,tierToArchivea los 90,deletea los 1825 (5 años): exactamente la política de retención de Contoso.snapshot.delete: las instantáneas antiguas también ocupan y se facturan.
Aplicación de la regla:
# Guarda el JSON anterior como ciclo-tarjetas.json y aplícalo a la cuenta.
az storage account management-policy create \
--account-name sttarjetascontosopro \
--resource-group rg-contoso-reservas-pro \
--policy @ciclo-tarjetas.json \
--output none
# Comprobar la política activa.
az storage account management-policy show \
--account-name sttarjetascontosopro \
--resource-group rg-contoso-reservas-pro \
--output jsonDos advertencias operativas: la política tarda hasta 24 horas en ejecutarse por primera vez (no esperes ver el cambio en cinco minutos), y daysAfterModificationGreaterThan cuenta desde la última modificación, no desde la creación. Si un proceso reescribe los ficheros, el reloj se reinicia y nada baja de nivel nunca.
- Azure Files: el recurso compartido de la oficina
Azure Files ofrece recursos compartidos de red accesibles por SMB (el protocolo de Windows, también soportado en Linux y macOS) y por NFS (solo en cuentas premium). A diferencia de los blobs, aquí sí hay un sistema de ficheros real con carpetas, permisos y bloqueo de ficheros.
Contoso tiene un caso claro: en las oficinas de Barcelona y Palma hay un recurso compartido \\servidor-oficina\operaciones con partes de incidencias, plantillas y hojas de cálculo que el personal de tierra abre a diario desde Windows. Ese recurso puede moverse tal cual a Azure Files sin cambiar la forma de trabajar de nadie.
| Cuándo usar | Blob Storage | Azure Files |
|---|---|---|
| Aplicación que sube y descarga objetos por HTTPS | Sí | Se puede, pero no es lo natural |
| Recurso compartido montado como unidad de red | No | Sí |
| Software heredado que exige una ruta de sistema de ficheros | No | Sí |
| Millones de objetos con acceso por URL | Sí | No |
| Coste por GB | Menor | Mayor |
# 1. Crear el recurso compartido con cuota de 100 GiB.
az storage share-rm create \
--resource-group rg-contoso-reservas-pro \
--storage-account stoperacionescontosopro \
--name compartido-operaciones \
--quota 100 \
--output table
# 2. Montarlo en Linux (el paquete cifs-utils debe estar instalado).
sudo mkdir -p /mnt/operaciones
sudo mount -t cifs \
//stoperacionescontosopro.file.core.windows.net/compartido-operaciones \
/mnt/operaciones \
-o vers=3.1.1,username=stoperacionescontosopro,password="${CLAVE_CUENTA}",serverinoEn Windows sería un net use Z: \\stoperacionescontosopro.file.core.windows.net\compartido-operaciones. Dos consideraciones importantes:
- El puerto 445 (SMB) está bloqueado por muchos proveedores de internet domésticos y corporativos. Por eso el montaje desde una oficina exige, en la práctica, conectividad privada: VPN o ExpressRoute. Es justo lo que veremos en la lección 02-06.
- Existe Azure File Sync, que mantiene sincronizado un servidor de ficheros local con el recurso de Azure y deja en local solo los ficheros usados recientemente. Es la vía habitual para migrar un servidor de ficheros de oficina sin cambiar nada para el usuario.
- Queue Storage: desacoplar la emisión de tarjetas
Queue Storage es un servicio de colas de mensajes sencillo: un productor deja un mensaje, un consumidor lo recoge y lo procesa. Mensajes de hasta 64 KB, hasta millones en una cola, con una semántica de «al menos una vez».
El caso de Contoso: cuando un pasajero compra un billete, generar el PDF de la tarjeta de embarque tarda un par de segundos. Hacerlo dentro de la petición web significa que el cliente espera; si el generador falla, la compra falla. Con una cola, la web deja un mensaje y responde de inmediato; un proceso aparte genera el PDF y lo sube al contenedor.
# Crear la cola y encolar una solicitud de emisión.
az storage queue create \
--account-name sttarjetascontosopro \
--name cola-emision-tarjetas \
--auth-mode login --output none
az storage message put \
--account-name sttarjetascontosopro \
--queue-name cola-emision-tarjetas \
--content '{"localizador":"A7K2","vuelo":"IB3241","fecha":"2026-08-14"}' \
--auth-mode login --output noneQueue Storage es la opción básica y barata. Cuando hacen falta temas de publicación y suscripción, sesiones, transacciones, orden garantizado o mensajes de más de 64 KB, la respuesta es Azure Service Bus; y para eventos a gran escala, Event Grid y Event Hubs. Los tres se comparan en la lección 06-05; aquí basta con que sepas que la cola existe dentro de la cuenta de almacenamiento y para qué sirve.
- Table Storage y su relación con Cosmos DB
Table Storage es un almacén NoSQL de clave-valor con esquema flexible. Cada entidad tiene:
- PartitionKey: agrupa entidades; determina el reparto y el rendimiento.
- RowKey: identifica la entidad dentro de la partición.
- Hasta 252 propiedades más, sin esquema fijo.
Su virtud es el precio: almacenar millones de filas simples cuesta una fracción de lo que costaría una base relacional. Su límite es la consulta: solo es rápida buscando por PartitionKey + RowKey. Cualquier otra consulta recorre la tabla.
az storage table create --account-name sttarjetascontosopro \
--name registroembarques --auth-mode login --output none
# Una entidad de auditoría: partición por vuelo, fila por localizador.
az storage entity insert \
--account-name sttarjetascontosopro \
--table-name registroembarques \
--entity PartitionKey=IB3241 RowKey=A7K2 \
emitida=2026-08-14T09:12:00Z puerta=B14 \
--auth-mode login --output noneRelación con Cosmos DB: Azure Cosmos DB for Table ofrece la misma API con distribución global, latencia garantizada por SLA, índices sobre todas las propiedades y rendimiento aprovisionado. Es la evolución natural cuando Table Storage se queda corto. La comparación completa y cuándo dar el salto están en la lección 03-03.
Criterio rápido: si tu dato es una tabla de auditoría barata con acceso por clave, Table Storage. Si necesitas consultas variadas, latencia garantizada o presencia global, Cosmos DB.
- Redundancia: LRS, ZRS, GRS, GZRS y RA-GRS
Este es el cabo suelto que dejó el módulo 1. Azure Storage siempre guarda varias copias de tus datos; lo que eliges es dónde están esas copias, y eso determina de qué fallo te protege.
| Opción | Copias y ubicación | Protege de | Lectura en la región secundaria | Coste relativo |
|---|---|---|---|---|
| LRS (local) | 3 copias en un mismo centro de datos | Fallo de disco, bastidor o servidor | — | € |
| ZRS (zona) | 3 copias en tres zonas de la región | Caída de un centro de datos completo | — | €€ |
| GRS (geográfica) | 3 copias locales + 3 en la región pareja | Desastre regional | No (la secundaria solo se lee tras conmutación) | €€ |
| GZRS (zona + geográfica) | 3 zonas en la principal + 3 locales en la pareja | Caída de zona y desastre regional | No | €€€ |
| RA-GRS / RA-GZRS | Como GRS/GZRS, con acceso de lectura a la secundaria | Lo mismo, y además permite leer en la secundaria | Sí, por un punto de conexión -secondary |
€€€€ |
Detalles que hay que conocer antes de decidir:
- La región pareja de West Europe es North Europe (fijado en la lección 01-02). La replicación geográfica es asíncrona: en un desastre puedes perder los últimos minutos de escrituras (el llamado punto de recuperación, RPO, de unos 15 minutos).
- La conmutación por error a la región pareja es una operación que se inicia (
az storage account failover), no algo instantáneo y automático. - Con RA-GRS puedes leer siempre de la secundaria en
https://<cuenta>-secondary.blob.core.windows.net, pero esos datos pueden ir retrasados. Sirve para informes o lecturas tolerantes, no para dar una tarjeta de embarque recién emitida. - La redundancia se puede cambiar después (
az storage account update --sku), aunque algunos saltos (por ejemplo, a ZRS) pueden requerir una migración solicitada.
La decisión de Contoso Airlines
| Cuenta | Entorno | Redundancia | Justificación |
|---|---|---|---|
sttarjetascontosodev |
Desarrollo | LRS (Standard_LRS) |
Los datos son desechables y regenerables. Pagar redundancia geográfica por ficheros de prueba es tirar dinero |
sttarjetascontosopro |
Producción | GZRS (Standard_GZRS) |
Las tarjetas de embarque son un documento del pasajero con obligación de retención. GZRS cubre la caída de una zona (política de Contoso) y el desastre regional |
stoperacionescontosopro |
Producción, ficheros de oficina | ZRS (Standard_ZRS) |
Contenido operativo importante pero reconstruible desde los sistemas de origen; basta la protección zonal |
# Aplicar la decisión en producción.
az storage account update \
--resource-group rg-contoso-reservas-pro \
--name sttarjetascontosopro \
--sku Standard_GZRS \
--output table
# Comprobar la redundancia de todas las cuentas de la suscripción.
az storage account list \
--query "[].{Cuenta:name, Redundancia:sku.name, Region:location, Grupo:resourceGroup}" \
--output tableY una advertencia que hay que decir en voz alta: la redundancia no es una copia de seguridad. GZRS replica fielmente los borrados y las sobrescrituras. Si un proceso borra las tarjetas de agosto, se borran en las seis copias a la vez. Contra eso protegen el versionado y la eliminación temporal del apartado 10, y Azure Backup en la lección 07-05.
- Seguridad de acceso: claves, SAS e identidades
Hay tres formas de autorizar el acceso a los datos, y están ordenadas de peor a mejor.
Claves de la cuenta
Cada cuenta tiene dos claves de 512 bits que dan control total sobre todo el contenido, sin caducidad y sin identidad asociada.
# Ver las claves (y por qué esto debería incomodarte).
az storage account keys list \
--resource-group rg-contoso-reservas-dev \
--account-name sttarjetascontosodev \
--output table
# Rotar la clave primaria.
az storage account keys renew \
--resource-group rg-contoso-reservas-dev \
--account-name sttarjetascontosodev \
--key primary --output noneQue haya dos claves es precisamente para poder rotar sin cortes: configuras las aplicaciones con la secundaria, renuevas la primaria, cambias las aplicaciones y renuevas la secundaria. Aun así, la recomendación es no usarlas: si una clave se filtra en un repositorio, cualquiera lee y borra todo. Puedes deshabilitarlas por completo:
az storage account update \
--resource-group rg-contoso-reservas-pro \
--name sttarjetascontosopro \
--allow-shared-key-access false --output noneFirmas de acceso compartido (SAS)
Una SAS es una URL con permisos limitados y caducidad. Es la forma de dar a un pasajero acceso a su tarjeta de embarque y a nada más.
| Tipo de SAS | Cómo se firma | Alcance | Revocación |
|---|---|---|---|
| De servicio | Con la clave de la cuenta | Un recurso concreto (un blob, un contenedor) | Rotando la clave o con una directiva almacenada |
| De cuenta | Con la clave de la cuenta | Varios servicios y operaciones de gestión | Rotando la clave |
| De delegación de usuario | Con una clave de Entra ID, no con la clave de la cuenta | Blobs | Revocando la clave de delegación, sin tocar la cuenta |
La de delegación de usuario es la recomendada: no requiere que la aplicación conozca la clave de la cuenta, queda asociada a una identidad y se puede revocar sin romper todo lo demás.
# SAS de delegación de usuario: lectura de un blob concreto, válida 15 minutos.
CADUCIDAD=$(date -u -d "15 minutes" '+%Y-%m-%dT%H:%MZ')
SAS=$(az storage blob generate-sas \
--account-name sttarjetascontosopro \
--container-name tarjetas-embarque \
--name "2026/08/IB3241-20260814-A7K2.pdf" \
--permissions r \
--expiry "${CADUCIDAD}" \
--https-only \
--as-user --auth-mode login \
--full-uri --output tsv)
echo "Enlace temporal: ${SAS}"Desglose de las opciones, porque cada una es una decisión de seguridad:
| Opción | Efecto |
|---|---|
--permissions r |
Solo lectura. Los permisos se componen con letras: r leer, w escribir, d borrar, l listar, a añadir, c crear |
--expiry |
Caducidad. Corta siempre: minutos u horas, nunca meses |
--https-only |
La URL no funciona por HTTP |
--as-user --auth-mode login |
SAS de delegación de usuario, firmada con Entra ID y no con la clave |
--full-uri |
Devuelve la URL completa lista para entregar |
Buenas prácticas de SAS que Contoso aplica: caducidad de 15 minutos para descargas de pasajero, permisos mínimos, generación en el servidor (nunca en el navegador), y directivas de acceso almacenadas a nivel de contenedor cuando se necesita poder revocar en masa.
Acceso por identidad de Microsoft Entra ID
La opción correcta para que una aplicación acceda a los datos: sin claves, sin SAS, con permisos RBAC concretos y auditoría.
# Dar a la web de reservas permiso para escribir tarjetas, usando su identidad administrada.
ID_APP=$(az webapp identity assign \
--resource-group rg-contoso-reservas-pro \
--name app-contoso-reservas-pro \
--query principalId --output tsv)
ID_CUENTA=$(az storage account show \
--resource-group rg-contoso-reservas-pro \
--name sttarjetascontosopro --query id --output tsv)
az role assignment create \
--assignee "${ID_APP}" \
--role "Storage Blob Data Contributor" \
--scope "${ID_CUENTA}" --output noneLos roles de datos más usados: Storage Blob Data Reader (leer), Storage Blob Data Contributor (leer y escribir) y Storage Blob Data Owner (además, gestionar permisos POSIX). Ojo con una confusión clásica: el rol Colaborador de Azure permite gestionar la cuenta, pero no da acceso a los datos salvo a través de las claves. Identidades administradas y RBAC se desarrollan en la lección 04-02.
- Cifrado, versionado, instantáneas y eliminación temporal
Cifrado en reposo: todo lo que hay en Azure Storage se cifra con AES de 256 bits, siempre y sin coste. Puedes usar claves gestionadas por Microsoft (por defecto) o claves propias en Key Vault (04-03) cuando el cumplimiento normativo lo exija.
Cifrado en tránsito: --https-only true y --min-tls-version TLS1_2, ya aplicados en la cuenta de Contoso desde el módulo 1.
Protección contra el borrado, que es lo que la redundancia no cubre:
CUENTA="sttarjetascontosopro"
GRUPO="rg-contoso-reservas-pro"
# 1. Eliminación temporal de blobs: 30 días para recuperar lo borrado.
az storage account blob-service-properties update \
--account-name "${CUENTA}" --resource-group "${GRUPO}" \
--enable-delete-retention true --delete-retention-days 30 --output none
# 2. Eliminación temporal de contenedores enteros.
az storage account blob-service-properties update \
--account-name "${CUENTA}" --resource-group "${GRUPO}" \
--enable-container-delete-retention true --container-delete-retention-days 30 --output none
# 3. Versionado: cada sobrescritura conserva la versión anterior.
az storage account blob-service-properties update \
--account-name "${CUENTA}" --resource-group "${GRUPO}" \
--enable-versioning true --output none| Mecanismo | De qué protege | Coste |
|---|---|---|
| Eliminación temporal | Borrado accidental de blobs o contenedores | Se factura el espacio de lo borrado durante la retención |
| Versionado | Sobrescritura accidental o cifrado por ransomware | Cada versión ocupa y se factura: combínalo con ciclo de vida |
| Instantáneas | Punto de retorno manual antes de un cambio | Solo los bloques modificados |
| Bloqueo inmutable (WORM) | Manipulación deliberada; cumplimiento legal | El blob no se puede borrar ni modificar durante el periodo fijado |
Contoso activa eliminación temporal de 30 días y versionado en producción, y añade a la regla de ciclo de vida el borrado de versiones antiguas para que el versionado no dispare la factura.
- Herramientas:
az storage, AzCopy y Storage Explorer
az storage, AzCopy y Storage Explorer| Herramienta | Cuándo usarla | Fortaleza |
|---|---|---|
az storage (Azure CLI) |
Automatización, scripts, tuberías | Ya la tienes instalada; se integra con el resto de comandos |
| AzCopy | Transferencias masivas y sincronización | Mucho más rápido: paraleliza, reanuda transferencias y sincroniza |
| Azure Storage Explorer | Exploración visual y depuración | Interfaz gráfica multiplataforma, muy útil para ver qué hay realmente |
| SDK (Java, .NET, Python, JS) | Desde el código de la aplicación | Reintentos, flujos y autenticación por identidad integrados |
# AzCopy con inicio de sesión de Entra ID (sin claves).
azcopy login
# Copiar un directorio completo de tarjetas históricas, recursivo.
azcopy copy "./tarjetas-2025/" \
"https://sttarjetascontosopro.blob.core.windows.net/tarjetas-embarque/2025/" \
--recursive=true
# Sincronizar: solo sube lo que ha cambiado. Ideal para migraciones repetidas.
azcopy sync "./tarjetas-2025/" \
"https://sttarjetascontosopro.blob.core.windows.net/tarjetas-embarque/2025/" \
--recursive=true --delete-destination=falseRegla práctica: para mover más de unos cientos de megabytes o más de unos cientos de ficheros, AzCopy. az storage blob upload-batch funciona, pero es notablemente más lento.
- Ejemplo completo: la tarjeta de embarque de principio a fin
Este script reúne todo lo anterior en el flujo real de Contoso: preparar la cuenta con la redundancia decidida, subir la tarjeta, entregar un enlace temporal al pasajero y programar el abaratamiento automático.
#!/usr/bin/env bash
set -euo pipefail
# ---------- Parámetros ----------
GRUPO="rg-contoso-reservas-dev"
CUENTA="sttarjetascontosodev"
CONTENEDOR="tarjetas-embarque"
LOCALIZADOR="A7K2"
VUELO="IB3241"
FECHA="2026-08-14"
BLOB="$(date -d "${FECHA}" '+%Y/%m')/${VUELO}-$(date -d "${FECHA}" '+%Y%m%d')-${LOCALIZADOR}.pdf"
# ---------- 1. Contenedor privado (idempotente) ----------
az storage container create \
--account-name "${CUENTA}" --name "${CONTENEDOR}" \
--public-access off --auth-mode login --output none
# ---------- 2. Subir la tarjeta con su tipo de contenido ----------
az storage blob upload \
--account-name "${CUENTA}" --container-name "${CONTENEDOR}" \
--name "${BLOB}" --file "./tarjeta-${LOCALIZADOR}.pdf" \
--content-type "application/pdf" \
--content-disposition "inline; filename=\"tarjeta-${VUELO}.pdf\"" \
--tier Hot \
--auth-mode login --overwrite --output none
echo "Tarjeta subida como ${BLOB}"
# ---------- 3. Enlace temporal para el pasajero (15 minutos, solo lectura) ----------
CADUCIDAD=$(date -u -d "15 minutes" '+%Y-%m-%dT%H:%MZ')
ENLACE=$(az storage blob generate-sas \
--account-name "${CUENTA}" --container-name "${CONTENEDOR}" --name "${BLOB}" \
--permissions r --expiry "${CADUCIDAD}" --https-only \
--as-user --auth-mode login --full-uri --output tsv)
echo "Enlace para el pasajero (caduca ${CADUCIDAD}): ${ENLACE}"
# ---------- 4. Regla de ciclo de vida: Cool a los 30 días ----------
cat > ciclo-tarjetas.json <<'EOF'
{
"rules": [
{
"enabled": true,
"name": "ciclo-tarjetas-embarque",
"type": "Lifecycle",
"definition": {
"filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["tarjetas-embarque/"] },
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 },
"tierToArchive": { "daysAfterModificationGreaterThan": 90 },
"delete": { "daysAfterModificationGreaterThan": 1825 }
}
}
}
}
]
}
EOF
az storage account management-policy create \
--account-name "${CUENTA}" --resource-group "${GRUPO}" \
--policy @ciclo-tarjetas.json --output none
echo "Politica de ciclo de vida aplicada."
# ---------- 5. Verificación ----------
az storage blob show \
--account-name "${CUENTA}" --container-name "${CONTENEDOR}" --name "${BLOB}" \
--auth-mode login \
--query "{Nombre:name, Nivel:properties.blobTier, Bytes:properties.contentLength, Tipo:properties.contentSettings.contentType}" \
--output tablePrueba el enlace con curl -I "${ENLACE}": debe devolver HTTP/1.1 200 OK. Espera a que caduque y repítelo: obtendrás un 403 con el código AuthenticationFailed. Esa es exactamente la protección que buscamos: el enlace sirve para descargar la tarjeta ahora, no para siempre.
- Limpieza
# Borrar los blobs de prueba de un prefijo.
az storage blob delete-batch \
--account-name sttarjetascontosodev \
--source tarjetas-embarque \
--pattern "2026/08/*" \
--auth-mode login
# Quitar la política de ciclo de vida si era solo una prueba.
az storage account management-policy delete \
--account-name sttarjetascontosodev \
--resource-group rg-contoso-reservas-dev
# Borrar la cuenta entera (solo en laboratorio).
# az storage account delete --name sttarjetascontosodev \
# --resource-group rg-contoso-reservas-dev --yesRecuerda: con la eliminación temporal activada, los blobs borrados siguen ocupando y facturando durante los días de retención. Es lo correcto para producción, pero tenlo en cuenta al limpiar un laboratorio.
Errores Comunes y Consejos
- Repartir la clave de la cuenta para dar acceso a un fichero. Da control total sobre todo. Usa SAS de delegación de usuario con caducidad corta, o identidades administradas.
- Generar SAS con caducidad de meses o años. Una URL con un año de vida acaba en un correo, en un ticket y en un buscador. Minutos, no meses.
- Subir a Archive lo que un cliente puede pedir hoy. Archive está fuera de línea: rehidratar tarda horas. Nunca para tarjetas del vuelo de mañana.
- Olvidar la permanencia mínima. Mover a Cool y borrar a los tres días cuesta los 30 días completos. Ajusta la política a la realidad de tus datos.
- Confundir redundancia con copia de seguridad. GZRS replica los borrados fielmente. Activa eliminación temporal y versionado.
- Poner mal el
prefixMatchde la regla de ciclo de vida. Empieza por el nombre del contenedor, no por el del blob. Es el fallo más habitual y silencioso: la regla no falla, simplemente no hace nada. - Esperar que la regla actúe al instante. Se ejecuta a diario y la primera vez puede tardar 24 horas.
- No poner el
content-typeal subir. El PDF se descarga en vez de verse; luego llegan las incidencias de soporte. - Usar Azure Files donde bastan blobs. Files cuesta más por GB y añade dependencia del puerto 445.
- Activar versionado sin ciclo de vida. Cada sobrescritura crea una versión que se factura para siempre. Combina siempre ambas cosas.
- Consejo: activa
--allow-shared-key-access falseen producción. Fuerza a que todo el acceso sea por Entra ID y elimina de golpe la clase entera de incidentes por clave filtrada. - Consejo: diseña el nombre del blob con jerarquía por fecha (
aaaa/mm/). Te da listados por prefijo y políticas de ciclo de vida por periodo prácticamente gratis.
Ejercicios
Ejercicio 1: elegir servicio, nivel y redundancia
Para cada dato de Contoso Airlines, indica qué servicio de la cuenta de almacenamiento usarías, qué nivel de acceso y qué redundancia, con su justificación:
- Tarjetas de embarque en PDF de producción, retención legal de 5 años.
- Plantillas y hojas de cálculo que el personal de tierra de Palma abre desde el explorador de Windows.
- Solicitudes de emisión de tarjeta pendientes de procesar por el generador de PDF.
- Registro de auditoría de cada emisión: qué vuelo, qué localizador, a qué hora, para consulta por vuelo.
- Copias de los ficheros de prueba que Diego regenera cada semana.
Ejercicio 2: enlace temporal y ciclo de vida
- Sube un fichero de prueba a
tarjetas-embarqueen la cuenta de desarrollo con el tipo de contenido correcto. - Genera una SAS de delegación de usuario, de solo lectura, válida 10 minutos y solo por HTTPS.
- Verifica con
curlque funciona, y explica qué respuesta esperas cuando caduque. - Escribe la política de ciclo de vida que mueva a Cool a los 30 días, a Archive a los 90 y borre a los 5 años.
Ejercicio 3: auditoría de almacenamiento
Escribe los comandos de Azure CLI que respondan a estas preguntas sobre la suscripción:
- ¿Qué cuentas de almacenamiento hay y con qué redundancia?
- ¿Alguna permite acceso público a blobs o admite claves compartidas?
- ¿Alguna acepta TLS por debajo de 1.2?
- ¿Qué cuentas de producción no tienen política de ciclo de vida?
Soluciones
Solución 1:
| Dato | Servicio | Nivel | Redundancia | Justificación |
|---|---|---|---|---|
| 1. Tarjetas de producción | Blob (en bloques) | Hot → Cool (30 d) → Archive (90 d) | GZRS | Documento del pasajero con retención legal: protección zonal y geográfica; el ciclo de vida abarata la retención larga |
| 2. Plantillas de la oficina | File (SMB) | — | ZRS | Necesita montarse como unidad de red desde Windows; contenido reconstruible, basta protección zonal |
| 3. Solicitudes pendientes | Queue | — | La de la cuenta (ZRS/GZRS) | Mensajes efímeros que desacoplan la web del generador de PDF |
| 4. Registro de auditoría por vuelo | Table | — | La de la cuenta | Clave-valor barato: PartitionKey = vuelo, RowKey = localizador, que es justo el patrón de consulta |
| 5. Ficheros de prueba de Diego | Blob | Hot | LRS | Datos desechables y regenerables: la redundancia geográfica sería gasto puro |
Solución 2:
#!/usr/bin/env bash
set -euo pipefail
CUENTA="sttarjetascontosodev"
CONTENEDOR="tarjetas-embarque"
BLOB="2026/08/PRUEBA-20260814-TEST.pdf"
# 1. Subida con tipo de contenido correcto.
az storage blob upload \
--account-name "${CUENTA}" --container-name "${CONTENEDOR}" \
--name "${BLOB}" --file ./prueba.pdf \
--content-type "application/pdf" \
--auth-mode login --overwrite --output none
# 2. SAS de delegación de usuario, lectura, 10 minutos, solo HTTPS.
CADUCIDAD=$(date -u -d "10 minutes" '+%Y-%m-%dT%H:%MZ')
ENLACE=$(az storage blob generate-sas \
--account-name "${CUENTA}" --container-name "${CONTENEDOR}" --name "${BLOB}" \
--permissions r --expiry "${CADUCIDAD}" --https-only \
--as-user --auth-mode login --full-uri --output tsv)
# 3. Verificación.
curl -I "${ENLACE}" # Esperado ahora: HTTP/1.1 200 OK-
Una vez pasados los 10 minutos, la misma URL devuelve
HTTP/1.1 403 Forbiddencon el código de errorAuthenticationFailed: la firma incluye la caducidad y el servicio la valida en cada petición. No hace falta borrar ni revocar nada. -
Política:
{
"rules": [{
"enabled": true,
"name": "ciclo-tarjetas-embarque",
"type": "Lifecycle",
"definition": {
"filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["tarjetas-embarque/"] },
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 },
"tierToArchive": { "daysAfterModificationGreaterThan": 90 },
"delete": { "daysAfterModificationGreaterThan": 1825 }
}
}
}
}]
}Solución 3:
# 1. Cuentas y redundancia.
az storage account list \
--query "[].{Cuenta:name, Redundancia:sku.name, Region:location, Grupo:resourceGroup}" \
--output table
# 2. Acceso público a blobs o claves compartidas permitidas.
az storage account list \
--query "[?allowBlobPublicAccess==\`true\` || allowSharedKeyAccess==\`true\`].{Cuenta:name, Publico:allowBlobPublicAccess, ClaveCompartida:allowSharedKeyAccess}" \
--output table
# 3. TLS por debajo de 1.2.
az storage account list \
--query "[?minimumTlsVersion!='TLS1_2'].{Cuenta:name, TLS:minimumTlsVersion}" \
--output table
# 4. Cuentas de producción sin política de ciclo de vida (bucle, porque
# la política es un subrecurso y no aparece en la lista de cuentas).
for CUENTA in $(az storage account list \
--query "[?tags.entorno=='produccion'].name" -o tsv); do
GRUPO=$(az storage account show -n "${CUENTA}" --query resourceGroup -o tsv)
if ! az storage account management-policy show \
--account-name "${CUENTA}" --resource-group "${GRUPO}" \
--output none 2>/dev/null; then
echo "SIN POLITICA DE CICLO DE VIDA: ${CUENTA} (${GRUPO})"
fi
doneEn el módulo 4 verás cómo convertir estas comprobaciones en Azure Policy para que no dependan de que alguien se acuerde de ejecutarlas.
Conclusión
Has cerrado el cabo suelto que dejó el módulo 1 y, de paso, has aprendido el servicio de datos más transversal de Azure. Sabes que una cuenta de almacenamiento aloja cuatro servicios —Blob, File, Queue y Table— con su propio punto de conexión y su nombre globalmente único en minúsculas. Conoces Blob Storage en detalle: contenedores, la jerarquía plana con prefijos, los tres tipos de blob y los niveles de acceso Hot, Cool, Cold y Archive con su compromiso entre coste de almacenamiento y de recuperación, las permanencias mínimas y la rehidratación de Archive. Has traducido el patrón real de uso de las tarjetas de embarque de Contoso —mucho la primera semana, casi nada después— en una regla de ciclo de vida que las abarata sola. Sabes cuándo tiene sentido Azure Files para el recurso compartido de la oficina, para qué sirve Queue Storage como desacoplador y qué relación tiene Table Storage con Cosmos DB. Y has fijado la decisión de redundancia de Contoso: LRS en desarrollo, GZRS para las tarjetas de producción y ZRS para los ficheros de operaciones, con la advertencia esencial de que la redundancia no es una copia de seguridad, para lo cual has activado eliminación temporal y versionado. En seguridad de acceso, has bajado por la escalera de lo malo a lo bueno: claves de cuenta (evitar y deshabilitar), SAS de servicio, de cuenta y de delegación de usuario con caducidad corta, y acceso por identidad de Microsoft Entra ID, que es el destino final.
Fíjate en lo que tienes ya montado: cómputo elástico, aplicaciones publicadas y almacenamiento con su política de ciclo de vida. Pero todo eso, tal como está, habla por internet. La web llega a la API por su nombre público, la aplicación llega al almacenamiento por su punto de conexión público, y la base de datos que viene en el módulo 3 estaría igual de expuesta. Ninguna arquitectura seria se queda así.
En la siguiente lección, Redes en Azure: redes virtuales, subredes y NSG, damos ese paso: planificarás el espacio de direcciones de vnet-contoso-pro con la aritmética CIDR explicada desde cero, diseñarás las subredes snet-web, snet-app, snet-datos y snet-gestion, escribirás reglas de grupos de seguridad de red que abran solo lo imprescindible, entenderás el emparejamiento de redes y el patrón hub-and-spoke, y verás la diferencia decisiva entre puntos de conexión de servicio y Azure Private Link —que es exactamente lo que hará que la cuenta sttarjetascontosopro y la base de datos de reservas dejen de ser accesibles desde internet.
Curso de Azure
Módulo 1: Introducción a Azure
- ¿Qué es Azure?
- Modelos de servicio, regiones y zonas de disponibilidad
- Crear y configurar tu cuenta de Azure
- Recorrido por el portal de Azure
- Azure Resource Manager: suscripciones, grupos de recursos y etiquetas
- Azure CLI, PowerShell y Cloud Shell
Módulo 2: Servicios principales de Azure
- Máquinas virtuales de Azure
- Escalado y alta disponibilidad del cómputo
- Azure App Service
- Azure Storage: blobs, archivos, colas y tablas
- Redes en Azure: redes virtuales, subredes y NSG
- Conectividad híbrida y entrega global
Módulo 3: Bases de datos de Azure
- Elegir el servicio de datos adecuado
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Analítica de datos: Data Lake, Data Factory y Synapse
Módulo 4: Seguridad en Azure
- Microsoft Entra ID y gestión de identidades
- RBAC e identidades administradas
- Azure Key Vault
- Protección DDoS y firewall de aplicaciones web
- Microsoft Defender for Cloud
- Gobernanza y cumplimiento con Azure Policy
Módulo 5: Azure DevOps
- Introducción a Azure DevOps
- Azure Repos
- Azure Pipelines: integración continua
- Despliegue continuo con entornos y aprobaciones
- Azure Artifacts
- Infraestructura como código con Bicep
Módulo 6: Servicios avanzados de Azure
- Contenedores en Azure: Container Registry y Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Mensajería y eventos: Service Bus, Event Grid y Event Hubs
- Servicios de IA de Azure
Módulo 7: Monitoreo y gestión
- Azure Monitor: métricas, alertas y paneles
- Log Analytics y consultas KQL
- Application Insights
- Azure Automation y runbooks
- Copias de seguridad y recuperación ante desastres
Módulo 8: Gestión y optimización de costos
- Calculadora de precios y estimación de costes
- Azure Cost Management: análisis, presupuestos y alertas
- Reservas, planes de ahorro y Azure Hybrid Benefit
- Azure Advisor
- Estrategias de optimización y cultura FinOps
