Storage Accounts: Blobs, Files, Queues & Tables
By the end of this lesson you will be able to create a secure storage account, choose a redundancy option, upload and list blobs using Entra ID sign-in, move data between access tiers, and automate tiering with a lifecycle policy. You will also know when to use Files, Queues and Tables.
What is a storage account?
A storage account is a container for four data services that share one name, one set of security settings and one bill:
| Service | Stores | Everyday example |
|---|---|---|
| Blob Storage | Any file as an object: images, PDFs, videos, backups, logs | Scanned answer sheets of a Pune university |
| Azure Files | File shares you mount over SMB or NFS | A shared folder for an accounts team |
| Queue Storage | Small messages waiting to be processed | Orders waiting for the kitchen in a cloud kitchen |
| Table Storage | Simple NoSQL rows looked up by key | Device readings from water meters |
Each service has its own address based on the account name, for example https://stjaipurnotes01.blob.core.windows.net. That is why account names must be globally unique: 3 to 24 lowercase letters and numbers.
The usual account type is Standard general-purpose v2. Premium account types exist for low-latency block blobs, file shares and page blobs.
Redundancy: how many copies, and where
Azure always keeps several copies of your data. You choose how far apart they are:
| Option | Copies | Protects against |
|---|---|---|
| LRS (locally redundant) | 3 copies in one data centre | Disk and server failure |
| ZRS (zone-redundant) | 3 copies across 3 availability zones | A whole data centre failing |
| GRS (geo-redundant) | LRS locally plus 3 copies in the paired region | A whole region failing |
| GZRS (geo-zone-redundant) | ZRS locally plus 3 copies in the paired region | Zone and region failures |
The RA- versions (RA-GRS, RA-GZRS) also let you read from the secondary region at any time. Think of keeping exam certificates: one photocopy in your cupboard (LRS), copies at three relatives' houses in the same city (ZRS), or one set in another city too (GRS).
Step by step: a secure storage account
Step 1: create the account with safe settings: no anonymous public blobs, TLS 1.2 minimum, and no shared key access, so every request must use Entra ID.
az group create --name rg-storage-demo --location centralindia --output none
az storage account create --resource-group rg-storage-demo --name stjaipurnotes01 \
--location centralindia --kind StorageV2 --sku Standard_ZRS --access-tier Hot \
--allow-blob-public-access false --min-tls-version TLS1_2 --allow-shared-key-access false \
--query "{name:name, sku:sku.name, tier:accessTier}"{
"name": "stjaipurnotes01",
"sku": "Standard_ZRS",
"tier": "Hot"
}Step 2: give yourself a data role. Being Owner is not enough to read blobs through Entra ID.
me=$(az ad signed-in-user show --query id --output tsv)
stId=$(az storage account show --resource-group rg-storage-demo --name stjaipurnotes01 --query id --output tsv)
az role assignment create --assignee-object-id "$me" --assignee-principal-type User \
--role "Storage Blob Data Contributor" --scope "$stId" --output noneStep 3: create a container (a folder-like group of blobs) and upload files. --auth-mode login tells the CLI to use your Entra ID token instead of account keys.
az storage container create --account-name stjaipurnotes01 --name notes --auth-mode login --output none
az storage blob upload --account-name stjaipurnotes01 --container-name notes \
--name notes/physics-unit-1.pdf --file physics-unit-1.pdf --auth-mode login --output noneStep 4: list the blobs.
az storage blob list --account-name stjaipurnotes01 --container-name notes --auth-mode login \
--query "[].{Name:name, Tier:properties.blobTier, Size:properties.contentLength}" --output tableName Tier Size -------------------------- ---- ------ notes/physics-unit-1.pdf Hot 482113 notes/chemistry-unit-1.pdf Hot 390220
These outputs are traced from the documented CLI fields; sizes are in bytes and made up. Blob storage has no real folders: the / in a blob name just looks like one.
Access tiers: pay less for old data
Blob data that nobody opens should not cost the same as data read every minute. Azure offers access tiers for block blobs:
| Tier | Storage cost | Access cost | Minimum days before early-deletion charge | Use for |
|---|---|---|---|---|
| Hot | Highest | Lowest | None | Data in daily use |
| Cool | Lower | Higher | 30 | Data used now and then, such as last month's notes |
| Cold | Lower still | Higher still | 90 | Rarely used data that must still open instantly |
| Archive | Lowest | Highest | 180 | Long-term records; offline |
Hot, Cool and Cold are online: you read the blob immediately. Archive is offline: you must first rehydrate the blob to an online tier, which can take hours. It is like the difference between your bookshelf, your loft and a warehouse outside the city.
If you move or delete a blob before its minimum days, you pay an early-deletion charge for the remaining days. Check the Blob Storage pricing page for current rates.
az storage blob set-tier --account-name stjaipurnotes01 --container-name notes \
--name notes/chemistry-unit-1.pdf --tier Cool --auth-mode loginThe account has a default tier (Hot or Cool) that new blobs inherit; you can override it for each blob.
Lifecycle management: let Azure move data for you
A lifecycle management policy moves or deletes blobs automatically based on age. This policy moves notes to Cool after 30 days, Archive after 180 days, and deletes them after about seven years:
{
"rules": [
{
"enabled": true,
"name": "age-out-notes",
"type": "Lifecycle",
"definition": {
"filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["notes/notes/"] },
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 },
"tierToArchive": { "daysAfterModificationGreaterThan": 180 },
"delete": { "daysAfterModificationGreaterThan": 2555 }
}
}
}
}
]
}The prefixMatch value starts with the container name (notes), followed by the blob name prefix (notes/). Save it as policy.json and apply it:
az storage account management-policy create --account-name stjaipurnotes01 \
--resource-group rg-storage-demo --policy @policy.json --output noneFiles, Queues and Tables in practice
- Azure Files gives SMB and NFS shares that Windows, Linux and macOS can mount like a network drive. It suits lift-and-shift apps that expect a shared folder.
- Queue Storage holds messages up to 64 KB. A web app adds an order message; a Function picks it up and processes it. Queues decouple the two, like a token system at a railway ticket counter.
- Table Storage stores rows with a
PartitionKeyand aRowKey. It is cheap and simple; for global scale, richer queries and more features, use Cosmos DB.
az storage queue create --account-name stjaipurnotes01 --name orders --auth-mode login --output none
az storage message put --account-name stjaipurnotes01 --queue-name orders \
--content "order-1001: 2 veg thali" --auth-mode login --output noneThis needs the Storage Queue Data Contributor role, just as blobs need a blob data role.
Sharing files safely: SAS
A shared access signature (SAS) is a URL with a signed token that gives limited, time-bound access, such as "read this one PDF for one hour". Prefer a user delegation SAS, which is signed with Entra ID credentials rather than the account key. Never share account keys, and treat every SAS URL as a secret until it expires.
Common mistakes
- Making a container public "just for a minute". Public blobs get indexed and copied. Use a SAS or a CDN with proper access instead.
- Archiving data you need quickly. Rehydration can take hours. Use Cold for rarely used data that must open instantly.
- Using account keys in code. Use managed identities and data roles.
- Choosing LRS for important data in production. Prefer ZRS or GZRS.
Key points
- A storage account holds Blob, Files, Queue and Table services under one globally unique name.
- Redundancy options range from LRS (one data centre) to GZRS (zones plus another region).
- Disable public blob access and shared keys; use Entra ID with data roles and
--auth-mode login. - Hot, Cool, Cold and Archive tiers trade storage cost against access cost; Archive is offline.
- Lifecycle policies move and delete blobs automatically by age.
Exercise
Rohan keeps CCTV recordings from his shop in Lucknow in a container cctv. Recordings are watched only in the first week, rarely after that, and must be deleted after one year. Write a lifecycle policy JSON that moves blobs in cctv to the Cold tier after 7 days and deletes them after 365 days. Explain why going to Cool at day 7 and then Cold at day 30 would be a worse plan.
Show solution
{
"rules": [
{
"enabled": true,
"name": "cctv-retention",
"type": "Lifecycle",
"definition": {
"filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["cctv/"] },
"actions": {
"baseBlob": {
"tierToCold": { "daysAfterModificationGreaterThan": 7 },
"delete": { "daysAfterModificationGreaterThan": 365 }
}
}
}
}
]
}Cold keeps recordings instantly readable if the police ask for one, at a lower storage cost than Cool. Moving to Cool at day 7 and on to Cold at day 30 would leave each blob in Cool for only 23 days, so you would pay an early-deletion charge for the rest of Cool's 30-day minimum. Each blob stays in Cold for 358 days, well past Cold's 90-day minimum.
Quick Quiz
1. Which redundancy option keeps three copies across availability zones in one region?
Zone-redundant storage spreads copies across three zones in the same region.
2. Why does a blob in the Archive tier not open immediately?
Archive is an offline tier; rehydration to an online tier can take hours.
3. Which setting makes every request use Entra ID instead of account keys?
Disabling shared key access blocks key-based and account-key SAS requests.
Learn Microsoft Azure with a mentor
Free lessons get you started. Our Cloud & DevOps training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
