Azure Storage — Blobs, Queues, Tables, and Files Demystified
Your application generates 500 GB of log files per month, serves images to millions of users, and needs a message queue to coordinate background jobs. Three different problems, one Azure service. Azure Storage handles all of them — if you know which sub-service to pick.
The Four Pillars of Azure Storage
Every Azure Storage account gives you access to four distinct services under a single endpoint:
| Service | Purpose | Access Protocol | Example Use Case |
|---|---|---|---|
| Blob Storage | Unstructured data (files, images, videos) | REST/HTTP | Media hosting, backups, data lakes |
| Queue Storage | Message queuing | REST/HTTP | Decoupling microservices, job queues |
| Table Storage | NoSQL key-value store | REST/HTTP | IoT telemetry, user profiles |
| File Storage | Managed SMB/NFS file shares | SMB 3.0 / NFS | Lift-and-shift, shared config files |
Creating a Storage Account
# Create a general-purpose v2 storage account
az storage account create \
--name stprodappeastus2025 \
--resource-group rg-prod-webapp-eastus \
--location eastus \
--sku Standard_LRS \
--kind StorageV2 \
--access-tier Hot \
--tags Environment=Production Team=Platform
Storage account names must be globally unique, 3-24 characters, and lowercase alphanumeric only. That is why naming conventions matter.
Blob Storage Deep Dive
Blob storage is what most teams interact with daily. Azure offers three blob types:
- Block Blobs — optimized for uploading large files in blocks (up to 190.7 TB). This is what you use 90% of the time.
- Append Blobs — optimized for append operations. Perfect for log files.
- Page Blobs — optimized for random read/write. Used internally by Azure VM disks.
Uploading and Managing Blobs
# Create a container
az storage container create \
--name app-assets \
--account-name stprodappeastus2025 \
--public-access off
# Upload a single file
az storage blob upload \
--account-name stprodappeastus2025 \
--container-name app-assets \
--file ./deploy-package.tar.gz \
--name releases/v2.1.0/deploy-package.tar.gz
# Upload an entire directory
az storage blob upload-batch \
--account-name stprodappeastus2025 \
--destination app-assets \
--source ./build-output \
--destination-path static/
# List blobs in a container
az storage blob list \
--account-name stprodappeastus2025 \
--container-name app-assets \
--output table
Access Tiers — Stop Overpaying for Cold Data
Not all data is accessed equally. Azure lets you place blobs in different access tiers to optimize cost:
| Tier | Storage Cost | Access Cost | Min Retention | Best For |
|---|---|---|---|---|
| Hot | Highest | Lowest | None | Frequently accessed data |
| Cool | ~40% less | Higher | 30 days | Infrequently accessed, monthly reports |
| Cold | ~55% less | Higher | 90 days | Rarely accessed, quarterly data |
| Archive | ~85% less | Highest | 180 days | Compliance data, long-term backups |
Key detail: Archive tier takes up to 15 hours to rehydrate data. You cannot read it instantly.
Setting and Changing Tiers
# Set blob tier to Cool
az storage blob set-tier \
--account-name stprodappeastus2025 \
--container-name app-assets \
--name releases/v1.0.0/deploy-package.tar.gz \
--tier Cool
# Set account-level default tier
az storage account update \
--name stprodappeastus2025 \
--access-tier Cool
Lifecycle Management — Automate Tier Transitions
Manually moving blobs between tiers does not scale. Lifecycle management policies automate it:
# Create a lifecycle policy JSON file
cat > lifecycle-policy.json << 'EOF'
{
"rules": [
{
"enabled": true,
"name": "move-to-cool-after-30-days",
"type": "Lifecycle",
"definition": {
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 },
"tierToArchive": { "daysAfterModificationGreaterThan": 180 },
"delete": { "daysAfterModificationGreaterThan": 365 }
}
},
"filters": {
"blobTypes": ["blockBlob"],
"prefixMatch": ["releases/", "logs/"]
}
}
}
]
}
EOF
# Apply the lifecycle policy
az storage account management-policy create \
--account-name stprodappeastus2025 \
--resource-group rg-prod-webapp-eastus \
--policy @lifecycle-policy.json
This policy automatically moves blobs to Cool after 30 days, Archive after 180 days, and deletes them after a year. Set it once and forget about it.
SAS Tokens — Secure Temporary Access
Shared Access Signatures (SAS) let you grant limited, time-bound access to storage resources without sharing your account key.
# Generate a SAS token for a specific blob (valid for 24 hours)
az storage blob generate-sas \
--account-name stprodappeastus2025 \
--container-name app-assets \
--name releases/v2.1.0/deploy-package.tar.gz \
--permissions r \
--expiry $(date -u -d '+24 hours' +%Y-%m-%dT%H:%MZ) \
--output tsv
# Generate a container-level SAS with read and list permissions
az storage container generate-sas \
--account-name stprodappeastus2025 \
--name app-assets \
--permissions rl \
--expiry $(date -u -d '+7 days' +%Y-%m-%dT%H:%MZ) \
--output tsv
Security tip: Always use the shortest expiry time that works for your use case. A SAS token valid for a year is a security incident waiting to happen.
Azure Files — SMB Shares in the Cloud
Azure Files provides fully managed file shares accessible via SMB 3.0 protocol. This is perfect for legacy applications that expect a mounted file system.
# Create a file share
az storage share-rm create \
--storage-account stprodappeastus2025 \
--resource-group rg-prod-webapp-eastus \
--name config-share \
--quota 100
# Upload a file to the share
az storage file upload \
--account-name stprodappeastus2025 \
--share-name config-share \
--source ./app-config.json \
--path settings/app-config.json
Mount the share on a Linux VM:
# On your Azure VM
sudo mkdir /mnt/config-share
sudo mount -t cifs \
//stprodappeastus2025.file.core.windows.net/config-share \
/mnt/config-share \
-o vers=3.0,username=stprodappeastus2025,password=<storage-account-key>,dir_mode=0777,file_mode=0777
Redundancy Options
Azure replicates your data automatically, but you choose how many copies and where:
| Option | Copies | Regions | Durability | Use Case |
|---|---|---|---|---|
| LRS | 3 | 1 datacenter | 11 nines | Dev/test, non-critical data |
| ZRS | 3 | 3 zones in 1 region | 12 nines | Production, zone-level resilience |
| GRS | 6 | 2 regions | 16 nines | Disaster recovery, compliance |
| RA-GRS | 6 | 2 regions (read access to secondary) | 16 nines | Read-heavy apps needing DR |
# Update redundancy to Zone-Redundant Storage
az storage account update \
--name stprodappeastus2025 \
--sku Standard_ZRS
Static Website Hosting
Need to host a static site without a web server? Azure Storage does it natively:
# Enable static website hosting
az storage blob service-properties update \
--account-name stprodappeastus2025 \
--static-website true \
--index-document index.html \
--404-document 404.html
# Upload your site files
az storage blob upload-batch \
--account-name stprodappeastus2025 \
--destination '$web' \
--source ./dist/
Your site is now live at https://stprodappeastus2025.z13.web.core.windows.net. Add Azure CDN in front of it for custom domains and global edge caching.
Wrapping Up
Azure Storage is one of those services where the basics are simple but the depth is enormous. Start with Blob storage for most workloads, use lifecycle policies to control costs from day one, and never hand out long-lived SAS tokens. The access tier decision alone can save your team thousands of dollars per month.
Next up: Entra ID (formerly Azure AD) — identity management that actually makes sense, covering tenants, managed identities, and conditional access.
