Chapter 7
Storage: accounts, access, networking, Blob and Files
Storage is one of the five exam areas on its own, and it has many small settings that each get a question. Take this chapter in two sittings if you like: accounts, redundancy and access first, then networking, Blob and Files. In the lab, your storage account becomes reachable from the web VMs through a service endpoint and a private endpoint.
Theory
Storage accounts
A storage account is the container for four data services, each with its own endpoint:
- Blob (
https://<account>.blob.core.windows.net): objects such as files, images, backups, logs. With hierarchical namespace enabled it becomes Data Lake Storage Gen2 (endpointdfs). - Files (
file): SMB and NFS file shares. - Queues (
queue): simple message queues. - Tables (
table): a NoSQL key-value store.
The account name becomes part of a public DNS name, so it must be globally unique, 3 to 24 characters, lowercase letters and numbers only.
Account types
| Type | Performance | Services | Redundancy |
|---|---|---|---|
| Standard general-purpose v2 | Standard (HDD-based) | Blob, Files, Queues, Tables | LRS, ZRS, GRS, RA-GRS, GZRS, RA-GZRS |
| Premium block blobs | Premium (SSD) | Block and append blobs | LRS, ZRS |
| Premium file shares | Premium (SSD) | Files (SMB and NFS) | LRS, ZRS |
| Premium page blobs | Premium (SSD) | Page blobs only | LRS, ZRS |
Standard GPv2 is the default answer unless the question asks for low latency (Premium) or NFS file shares (Premium file shares). The performance tier can't be changed after creation; you'd create a new account and copy the data.
Settings worth knowing
- Secure transfer required (HTTPS only, SMB 3 with encryption): on by default.
- Minimum TLS version: set TLS 1.2.
- Allow blob anonymous access: off by default for new accounts. Must be on before any container can be made public.
- Allow storage account key access: turn off to force Entra ID (and user delegation SAS) everywhere.
- Default access tier for blobs: Hot or Cool.
- Hierarchical namespace: for big-data analytics. Can be enabled later (one-way upgrade), never disabled.
Redundancy
Azure Storage always keeps at least three copies of your data. The redundancy option decides where those copies are:
How to choose:
- LRS: cheapest. Fine for data you can recreate, or when data must stay in one location for compliance.
- ZRS: high availability within a region. Your app keeps working if a zone goes down.
- GRS / GZRS: protection against a regional disaster. The secondary is only readable after a failoverβ¦
- RA-GRS / RA-GZRS: β¦unless you choose read-access, then apps can read from the secondary endpoint at any time.
Failover to the secondary region is customer-initiated (you start it). Because replication is asynchronous, the most recent writes may be lost; the Last Sync Time property tells you up to when data is safe. After an unplanned failover the account is LRS in the new primary region until you re-enable geo-redundancy.
You can change redundancy later. Moving between LRS, GRS and RA-GRS is a simple setting. Adding zone redundancy (LRS β ZRS) is a conversion that runs in the background, or a manual migration.
"Data must be readable even if the primary region is down, without waiting for a failover." Only RA-GRS or RA-GZRS qualify. Also: Premium accounts support only LRS and ZRS.
Authorising access to data
There are four ways to get at data in a storage account. Know when to use which:
| Method | How it works | Use it for |
|---|---|---|
| Microsoft Entra ID (recommended) | Users, groups, managed identities with data roles like Storage Blob Data Reader | Apps with managed identity, admins, people |
| Shared Key (account keys) | Two 512-bit keys that give full access to everything in the account | Legacy tools; avoid where possible |
| Shared access signature (SAS) | A signed URL token with limited permissions and an expiry | Giving temporary, limited access to a client or partner |
| Anonymous public read | No authentication at all, per container | Public website assets only |
Access keys
Every account has two keys (key1 and key2) so you can rotate without downtime:
- Switch all apps to key2.
- Regenerate key1.
- Switch apps back to key1, then regenerate key2 (next rotation).
Better still: store keys in Key Vault, set a key expiration policy with reminders, or disable Shared Key altogether and use Entra ID. Remember: regenerating a key invalidates every SAS signed with it.
Shared access signatures
A SAS is a query string you append to a URL. It has three flavours:
- User delegation SAS: signed with Entra ID credentials instead of an account key. Most secure, but Blob (and Data Lake) only, and valid for at most 7 days.
- Service SAS: signed with an account key, for one service (a container, blob, share, queue or table).
- Account SAS: signed with an account key, can cover several services and service-level operations.
The parameters in a SAS token you should be able to read:
?sv=2022-11-02 signed version
&ss=bf &srt=co services (blob, file) and resource types (container, object) β account SAS
&sp=rl permissions: read, list (also a, c, w, d β¦)
&st=2026-11-13T09:00Z start
&se=2026-11-14T09:00Z expiry
&sip=198.51.100.10 allowed client IP(s)
&spr=https allowed protocol
&si=read-1day stored access policy (if used)
&sig=β¦ the signature
Stored access policies
The problem with an ad-hoc SAS is that you can't revoke it, except by rotating the key that signed it (which breaks every other SAS too). A stored access policy fixes that:
- You define it on a container (or a file share, queue or table), with a start time, expiry and permissions.
- A service SAS refers to it by name (
si=) and inherits those values. - To revoke all SASs based on it, you delete or change the policy. To extend them, you change its expiry.
- Up to five policies per container. Changes can take up to 30 seconds to apply.
"Partners use SAS tokens. You must be able to revoke a partner's access without affecting others." Give each partner a SAS based on their own stored access policy. Rotating the account key would revoke everyone. (User delegation SAS can't use stored access policies.)
Networking: firewall, service endpoints and private endpoints
By default a storage account accepts connections from any network (they still need authorisation). The Networking blade lets you restrict that. Public network access has three settings:
- Enabled from all networks.
- Enabled from selected virtual networks and IP addresses: only allowed public IP ranges, allowed subnets (via service endpoints) and allowed Azure resource instances get in.
- Disabled: only private endpoints work.
Some details that come up in questions:
- IP rules accept only public IP ranges, not private ones like
10.x. - Exceptions: "Allow Azure services on the trusted services list" lets services like Azure Backup, Event Grid and Azure Monitor in.
- Resource instance rules allow one specific resource (by its managed identity), like a particular Synapse workspace.
- The firewall applies to the data plane only. You can still manage the account in the portal (control plane), but the portal's storage browser fails unless your own IP is allowed.
Service endpoints
You enable a service endpoint (e.g. Microsoft.Storage) on a subnet. Traffic from that subnet to Azure Storage then travels over the Azure backbone and arrives with the subnet's identity, so the storage firewall can say "allow snet-web". The storage account keeps its public IP. Service endpoints are free, but don't help on-premises clients. Service endpoint policies can restrict a subnet to specific storage accounts (prevents data exfiltration to other accounts).
Private endpoints
A private endpoint is a NIC in your subnet with a private IP that maps to one sub-resource (blob, file, queue, table, dfs, web) of one storage account. It's part of Azure Private Link, which works the same for SQL, Key Vault, App Service and many others.
DNS is the part people get wrong. The public name staz104xx01.file.core.windows.net becomes a CNAME to staz104xx01.privatelink.file.core.windows.net. For clients to get the private IP, a private DNS zone privatelink.file.core.windows.net with an A record must be linked to their VNet (or on-premises DNS must forward to Azure DNS, e.g. via the DNS Private Resolver). Without it, clients resolve the public IP and get blocked by the firewall.
"On-premises servers connected via VPN must reach a storage account privately." Service endpoints don't work from on-premises. Use a private endpoint plus DNS forwarding.
Encryption
All data in Azure Storage is encrypted at rest with 256-bit AES (Storage Service Encryption). You can't turn it off. What you choose is who manages the key:
- Microsoft-managed keys: the default, nothing to do.
- Customer-managed keys (CMK): your key in Key Vault or Managed HSM. The storage account uses a managed identity to reach the key, and the vault needs soft delete and purge protection. You can rotate the key, or revoke access to make the data unreadable.
- Customer-provided keys: the client sends the key with each Blob request.
Two more options: encryption scopes let different containers or blobs use different keys in one account, and infrastructure encryption adds a second layer of encryption (must be enabled at account creation).
Blob storage
Blobs live in containers inside the account. There are three blob types: block blobs (files, most data), append blobs (logs that only grow) and page blobs (random-access disks, like old unmanaged VHDs).
Access tiers
Block blobs have an access tier that trades storage cost against access cost:
- The account default tier can be Hot or Cool. Cold and Archive are set per blob.
- Archive blobs are offline. To read one, you rehydrate it to Hot, Cool or Cold: standard priority takes up to 15 hours, high priority usually under 1 hour for small blobs. Or copy it to a new blob in an online tier.
- Archive isn't available for ZRS/GZRS accounts or premium accounts.
Lifecycle management
A lifecycle management policy moves or deletes blobs automatically. It's a JSON list of rules, each with filters (blob type, prefix like logs/, blob index tags) and actions on the base blob, snapshots and versions:
{ "rules": [ { "name": "logs-tiering", "enabled": true, "type": "Lifecycle",
"definition": {
"filters": { "blobTypes": [ "blockBlob" ], "prefixMatch": [ "images/logs/" ] },
"actions": {
"baseBlob": {
"tierToCool": { "daysAfterModificationGreaterThan": 30 },
"tierToArchive": { "daysAfterModificationGreaterThan": 90 },
"delete": { "daysAfterModificationGreaterThan": 365 } },
"version": { "delete": { "daysAfterCreationGreaterThan": 30 } } } } } ] }
Note that prefixMatch starts with the container name. Rules can also use daysAfterLastAccessTimeGreaterThan if you enable last access time tracking. The policy runs once a day, so changes can take up to 24β48 hours to show.
Data protection for blobs
- Blob soft delete (1β365 days): deleted or overwritten blobs can be restored with Undelete.
- Container soft delete (1β365 days): the same for whole containers.
- Versioning: every write keeps the previous version automatically. You can promote an old version to current.
- Snapshots: a manual read-only point-in-time copy of a blob.
- Point-in-time restore: restore block blobs to an earlier time. Requires versioning, change feed and soft delete.
- Change feed: a log of all changes to blobs.
- Immutable storage (WORM): time-based retention or legal hold. Data can't be changed or deleted, not even by an admin, once a policy is locked. For compliance (e.g. SEC 17a-4).
Object replication
Object replication copies block blobs asynchronously from a container in one account to a container in another account (any region). Uses: lower read latency in another region, or a copy for analytics. Requirements: versioning on both accounts and change feed on the source. Hierarchical namespace isn't supported. You create a replication policy with rules (source container β destination container, optional prefix filter, and whether to copy existing blobs).
Azure Files
Azure Files offers fully managed file shares over SMB 3.x (Windows, Linux, macOS; port 445) and NFS 4.1 (Linux; Premium only, private network only). Use it to replace file servers, share config between VMs, or "lift and shift" apps that expect a share.
- Tiers: Premium (SSD, provisioned capacity), and for Standard: Transaction optimized, Hot and Cool.
- A quota limits the size of a share (up to 100 TiB with large file shares enabled).
- Share snapshots: read-only copies of the whole share (up to 200). Windows users see them as Previous Versions. Azure Backup uses them too.
- Soft delete for shares (1β365 days): a deleted share can be undeleted. It's on by default (7 days) for new accounts.
Port 445 is often blocked by ISPs, so on-premises access usually goes over VPN/ExpressRoute with a private endpoint, or through Azure File Sync, which caches the share on a Windows Server and can tier cold files to the cloud.
Identity-based access for Azure Files
With SMB you can mount a share with the storage account key (full access, like being root) or with user identities. Identity-based access has two layers, like a Windows file server:
- Enable an identity source on the storage account (one at a time):
- On-premises AD DS: the storage account is joined to your domain (with the AzFilesHybrid PowerShell module). Users must be synced to Entra ID.
- Microsoft Entra Domain Services: managed domain in Azure.
- Microsoft Entra Kerberos: for hybrid users on Entra-joined or hybrid-joined clients, without line of sight to a domain controller.
- Share-level permissions with Azure RBAC roles: Storage File Data SMB Share Reader, Contributor, Elevated Contributor (can also change NTFS permissions). You can also set a default share-level permission for all authenticated users.
- Directory and file-level permissions: normal Windows ACLs (NTFS), set with File Explorer or
icacls.
Effective access is the most restrictive combination of share-level and file-level permissions.
"Users get access denied on the share even though NTFS permissions allow them." Check the share-level RBAC role first: without one (and without a default share-level permission), nobody gets in with their identity.
Tools for moving data
- Azure Storage Explorer: a free desktop app to browse and manage blobs, files, queues and tables. Signs in with Entra ID, a key, a SAS or a connection string.
- AzCopy: a command-line tool for fast bulk copies:
azcopy copy(local β Azure, and account to account directly between servers) andazcopy sync. Authenticates with Entra ID (azcopy login) or a SAS. - The portal's Storage browser for quick work.
- Azure Data Box: physical devices for offline transfer of tens to hundreds of TB when the network is too slow. Azure Import/Export uses your own disks.
AZ-305 "design data storage" questions combine everything in this chapter: which redundancy for a given RPO/availability need, which tier and lifecycle for cost, which access method (managed identity + RBAC over keys), and private endpoints + DNS for network isolation. Learn the redundancy figure by heart.
- Storage account overview
- Azure Storage redundancy
- Shared access signatures (SAS)
- Stored access policies
- Storage network security (firewall)
- Private endpoints for Azure Storage
- Storage encryption for data at rest
- Blob access tiers
- Blob lifecycle management
- Blob data protection overview
- Object replication
- What is Azure Files?
- Identity-based access for Azure Files
- Get started with AzCopy
Self-check
1. A storage account must survive a zone outage and a regional disaster, and apps must read from the secondary region at any time. What do you choose?
C. Zones + secondary region + read access.
2. You gave a partner a service SAS based on stored access policy "partner-a". How do you revoke it immediately without affecting other partners?
A. Regenerating keys would revoke every SAS signed with them.
3. VMs in a VNet reach a storage account through a private endpoint, but nslookup returns a public IP. What's missing?
D. Without the private DNS zone link, the CNAME chain resolves to the public endpoint.
4. Which tier makes a blob unreadable until it is rehydrated?
B. Archive is offline; Cold is online but expensive to read.
5. What must be enabled to configure object replication?
C. HNS isn't supported for object replication.
6. Users with Entra Kerberos authentication can mount a share but can't open any folder. NTFS ACLs grant them Modify. What's the likely cause?
A. Both layers must allow access. (Strictly, without a share-level role they usually can't mount either, which is exactly why this is the first thing to check.)
Lab: a protected, private storage account
You create staz104xx01, protect its data, share it with a SAS, automate tiering, and finally close it to the internet so that only snet-web (service endpoint), a private endpoint in snet-data and your browser can reach it. The order matters: the firewall comes last so that your Linux VM can still upload data in the earlier steps. Paste the variables first:
RG=rg-az104-lab; LOC=westeurope; LOC2=northeurope; INIT=xx
ST=staz104${INIT}01; MYIP=$(curl -s https://api.ipify.org)
mkdir -p ~/az104 && cd ~/az104
-
Task
Create the storage account
Create
staz104xx01inrg-az104-lab: Standard general-purpose v2, LRS, default tier Hot, TLS 1.2 minimum, no anonymous blob access, public network access from all networks (for now).Done when- The account exists. On its Overview, find the endpoints for blob and file.
Solution Β· Portal
Create a resource β Storage account. Basics: name, region, primary service Azure Blob Storage or Azure Data Lake Storage Gen 2 (or leave empty), performance Standard, redundancy LRS. Advanced: untick Allow enabling anonymous access on individual containers, minimum TLS 1.2, access tier Hot. Review + create.
Solution Β· Azure CLI
az storage account create -g $RG -n $ST -l $LOC --sku Standard_LRS --kind StorageV2 \ --access-tier Hot --min-tls-version TLS1_2 --allow-blob-public-access false STID=$(az storage account show -g $RG -n $ST --query id -o tsv) az storage account show -g $RG -n $ST --query primaryEndpoints -
Task
Survive a regional disaster
Change the redundancy so the data survives the loss of the whole region and can be read from the other region at any time, without a failover.
Done when- The account shows the new redundancy, a secondary location, and a secondary blob endpoint ending in
-secondary.blob.core.windows.net.
Solution Β· Portal
Storage account β Data management β Redundancy β Read-access geo-redundant storage (RA-GRS) β Save. The page shows the primary and secondary regions.
Solution Β· Azure CLI
az storage account update -g $RG -n $ST --sku Standard_RAGRS az storage account show -g $RG -n $ST --query "{sku:sku.name, secondary:secondaryLocation, ep:secondaryEndpoints.blob}" - The account shows the new redundancy, a secondary location, and a secondary blob endpoint ending in
-
Task
Give yourself data access, then protect the blobs
You're Owner of the subscription. Make sure you can upload blobs with your Entra identity (not a key). Then turn on versioning, blob soft delete (7 days) and container soft delete (7 days), and create a private container
images.Upload a small text file
hello.txt, change it and upload it again, then delete it and get it back.Done whenhello.txtexists again and has two versions.- You can explain why Owner alone wasn't enough.
Hint
The role you need is a data role on the storage account: Storage Blob Data Contributor. Role assignments can take a few minutes.
Solution Β· Portal
- Storage account β Access control (IAM) β Add role assignment β Storage Blob Data Contributor β yourself.
- Data management β Data protection: tick Enable versioning for blobs, Enable soft delete for blobs (7), Enable soft delete for containers (7). Save.
- Data storage β Containers β + Container:
images, private. - Open
imagesβ Uploadhello.txt; change it locally and upload again with Overwrite. The blob's Versions tab shows two. - Delete it, turn on Show deleted blobs, right-click β Undelete.
Owner is a control-plane role. Reading/writing blob data with Entra ID needs a data-plane role (chapter 2).
Solution Β· Azure CLI
ME=$(az ad signed-in-user show --query id -o tsv) az role assignment create --assignee-object-id $ME --assignee-principal-type User \ --role "Storage Blob Data Contributor" --scope $STID az storage account blob-service-properties update -g $RG -n $ST --enable-versioning true \ --enable-delete-retention true --delete-retention-days 7 \ --enable-container-delete-retention true --container-delete-retention-days 7 az storage container create --account-name $ST -n images --auth-mode login echo "version 1" > hello.txt; az storage blob upload --account-name $ST -c images -n hello.txt -f hello.txt --auth-mode login --overwrite echo "version 2" > hello.txt; az storage blob upload --account-name $ST -c images -n hello.txt -f hello.txt --auth-mode login --overwrite az storage blob delete --account-name $ST -c images -n hello.txt --auth-mode login az storage blob undelete --account-name $ST -c images -n hello.txt --auth-mode login az storage blob list --account-name $ST -c images --include v --auth-mode login \ --query "[].{name:name, version:versionId, current:isCurrentVersion}" -o table -
Task
Share with a SAS you can revoke
Create a stored access policy
read-1dayonimagesthat allows read and list for one day. Create a SAS based on it, downloadhello.txtwithcurlusing only that URL, then revoke the SAS without touching the account keys.Done when- The first
curlreturns the file content. - After revoking, the same URL returns 403 (allow up to 30 seconds).
Solution Β· Portal
- Container
imagesβ Settings β Access policy β Add policy: identifierread-1day, permissions Read, List, expiry tomorrow. Save. - Open
hello.txtβ Generate SAS β signing method Account key, Stored access policyread-1dayβ Generate. Copy the Blob SAS URL andcurlit on your Linux VM. - Back to Access policy, delete
read-1day, Save, andcurlagain.
Solution Β· Azure CLI
EXP=$(date -u -d '+1 day' +%Y-%m-%dT%H:%MZ) az storage container policy create --account-name $ST -c images -n read-1day --permissions rl --expiry $EXP SAS=$(az storage blob generate-sas --account-name $ST -c images -n hello.txt --policy-name read-1day -o tsv) curl -s "https://$ST.blob.core.windows.net/images/hello.txt?$SAS" az storage container policy delete --account-name $ST -c images -n read-1day sleep 30; curl -s -o /dev/null -w "%{http_code}\n" "https://$ST.blob.core.windows.net/images/hello.txt?$SAS" - The first
-
Task
Bulk upload with AzCopy and automate tiering
Create five small log files and upload them with AzCopy (using your Entra identity, no SAS) to
images/logs/. Then add a lifecycle management rule for blobs under that prefix: Cool after 30 days, Archive after 90, delete after 365 since last modification, and delete previous versions after 30 days.Done when- The five files are in
images/logs/. - The Lifecycle management blade shows your rule (its effect only shows after a day, of course).
Hint
AzCopy can reuse your
azlogin:export AZCOPY_AUTO_LOGIN_TYPE=AZCLI. The lifecycle prefix includes the container name.Solution Β· Portal (lifecycle)
Storage account β Data management β Lifecycle management β Add a rule: name
logs-tiering, scope Limit blobs with filters, blob type Block, subtypes Base blobs and Versions. Base blobs: Last modified more than 30 days β Move to cool; + 90 β Move to archive; + 365 β Delete. Versions: more than 30 days β Delete. Filter set: prefiximages/logs/.Solution Β· Azure CLI
mkdir -p logs; for i in 1 2 3 4 5; do echo "log line $i $(date)" > logs/app$i.log; done export AZCOPY_AUTO_LOGIN_TYPE=AZCLI azcopy copy "logs" "https://$ST.blob.core.windows.net/images/" --recursive cat > policy.json <<'EOF' { "rules": [ { "name": "logs-tiering", "enabled": true, "type": "Lifecycle", "definition": { "filters": { "blobTypes": [ "blockBlob" ], "prefixMatch": [ "images/logs/" ] }, "actions": { "baseBlob": { "tierToCool": { "daysAfterModificationGreaterThan": 30 }, "tierToArchive": { "daysAfterModificationGreaterThan": 90 }, "delete": { "daysAfterModificationGreaterThan": 365 } }, "version": { "delete": { "daysAfterCreationGreaterThan": 30 } } } } } ] } EOF az storage account management-policy create -g $RG --account-name $ST --policy @policy.json - The five files are in
-
Task
Create a file share with a snapshot
Create an SMB file share
share1with a 10 GiB quota in the Hot tier. Make sure a deleted share can be recovered for 7 days, and take a snapshot of the share.Done whenshare1has one snapshot.- File share soft delete is on with 7 days.
Solution Β· Portal
- Data storage β File shares β + File share:
share1, tier Hot, then set quota 10 GiB (share β Edit quota). - File shares page β Soft delete setting β enabled, 7 days.
share1β Operations β Snapshots β + Add snapshot.
Solution Β· Azure CLI
az storage share-rm create -g $RG --storage-account $ST -n share1 --quota 10 --access-tier Hot az storage account file-service-properties update -g $RG -n $ST --enable-delete-retention true --delete-retention-days 7 az storage share-rm snapshot -g $RG --storage-account $ST -n share1 az storage share-rm list -g $RG --storage-account $ST --include-snapshot -o table -
Task
Close the account to the internet
Change the storage firewall so that the account is reachable only from:
snet-web, through a service endpoint;- your browser's public IP (so the portal's storage browser keeps working), not the Linux VM's;
- trusted Azure services (chapter 10's Backup needs this).
Then add a private endpoint
pe-st-fileinsnet-datafor the file service, with private DNS so that both VNets resolve the share to its private IP.Done when- Networking shows Enabled from selected virtual networks and IP addresses with
snet-weband your IP. - Private DNS zone
privatelink.file.core.windows.nethas an A record pointing to a10.20.2.xaddress and is linked to both VNets. - From your Linux VM,
az storage blob list --auth-mode loginonimagesnow fails, even though you are Owner. Why?
Hint
The portal's private endpoint wizard can create and link the
privatelinkDNS zone for you, but only to the endpoint's own VNet. Add the hub link yourself.Solution Β· Portal
- Storage account β Security + networking β Networking β Firewalls and virtual networks: Enabled from selected virtual networks and IP addresses. + Add existing virtual network β
vnet-spoke/snet-web(the portal enables theMicrosoft.Storageservice endpoint). Tick Add your client IP address. Under Exceptions keep Allow Azure services on the trusted services list. Save. - Private endpoint connections β + Private endpoint: name
pe-st-file, target sub-resource file, VNetvnet-spoke, subnetsnet-data, Integrate with private DNS zone: Yes. - Open Private DNS zones β privatelink.file.core.windows.net β Virtual Network Links β Add β
vnet-hub, no auto-registration.
The VM's requests come from its AWS address (
$MYIP), which isn't in the allow list, so the data plane rejects them withAuthorizationFailure(a 403). The firewall is checked before RBAC: being Owner doesn't help. Managing the account (control plane) from the VM still works.Solution Β· Azure CLI
# service endpoint + firewall az network vnet subnet update -g $RG --vnet-name vnet-spoke -n snet-web --service-endpoints Microsoft.Storage az storage account network-rule add -g $RG --account-name $ST --vnet-name vnet-spoke --subnet snet-web az storage account network-rule add -g $RG --account-name $ST --ip-address <your-browser-ip> az storage account update -g $RG -n $ST --default-action Deny --bypass AzureServices # test from the Linux VM (allow up to a minute for the rules to apply) az storage blob list --account-name $ST -c images --auth-mode login -o table # AuthorizationFailure az storage account show -g $RG -n $ST --query networkRuleSet.defaultAction # control plane still works # private endpoint for the file service az network private-endpoint create -g $RG -n pe-st-file -l $LOC --vnet-name vnet-spoke --subnet snet-data \ --private-connection-resource-id $STID --group-id file --connection-name pe-st-file-conn az network private-dns zone create -g $RG -n privatelink.file.core.windows.net az network private-dns link vnet create -g $RG -z privatelink.file.core.windows.net -n link-spoke -v vnet-spoke -e false az network private-dns link vnet create -g $RG -z privatelink.file.core.windows.net -n link-hub -v vnet-hub -e false az network private-endpoint dns-zone-group create -g $RG --endpoint-name pe-st-file -n default \ --private-dns-zone privatelink.file.core.windows.net --zone-name file az network private-dns record-set a list -g $RG -z privatelink.file.core.windows.net -o tableFind your browser's public IP by searching "what is my IP" in it. It differs from
$MYIP, the AWS VM's address. -
Task
Use the storage account from
vm-web1From
vm-web1(Bastion or Run command):- Look up the blob and the file host names of your account. One resolves to a public IP, one to a private IP. Explain why.
- Mount
share1at/mnt/share1over SMB 3.1.1 and write a filefrom-vm.txtto it.
Done when- Blob β public IP (service endpoint), file β
10.20.2.x(private endpoint). from-vm.txtis visible in the portal undershare1.
Hint
The file share's Connect button in the portal generates a Linux mount script. The VM needs the
cifs-utilspackage; it can download it through the load balancer's outbound rule from chapter 6.Solution Β· Portal + Bastion
- Bastion SSH to
vm-web1:nslookup staz104xx01.blob.core.windows.netandnslookup staz104xx01.file.core.windows.net. The file name goes throughprivatelinkto10.20.2.4. sudo apt-get install -y cifs-utils- Portal:
share1β Connect β Linux β Show script, copy it into the Bastion session (change the mount point to/mnt/share1if you like). echo hello | sudo tee /mnt/share1/from-vm.txt, then check share1 in the portal.
Solution Β· Azure CLI
KEY=$(az storage account keys list -g $RG -n $ST --query "[0].value" -o tsv) az vm run-command invoke -g $RG -n vm-web1 --command-id RunShellScript --scripts " nslookup $ST.blob.core.windows.net | tail -3 nslookup $ST.file.core.windows.net | tail -3 apt-get install -y -q cifs-utils >/dev/null mkdir -p /mnt/share1 mount -t cifs //$ST.file.core.windows.net/share1 /mnt/share1 \ -o vers=3.1.1,username=$ST,password=$KEY,serverino,dir_mode=0777,file_mode=0777 echo hello-from-\$(hostname) > /mnt/share1/from-vm.txt df -h /mnt/share1" --query "value[0].message" -o tsvMounting with the account key gives full access. In production you'd use identity-based access (AD DS or Entra Kerberos) and RBAC share-level roles.
A few MB in RA-GRS cost practically nothing. The private endpoint costs about β¬0.01/hour. Nothing here needs stopping between sessions.
staz104xx01(RA-GRS) with containerimages(versioning, soft delete, lifecycle rule) and shareshare1(snapshot, soft delete).- Firewall: only
snet-web, your IP and trusted services. Private endpointpe-st-fileinsnet-datawith private DNS. share1is mounted onvm-web1(until the next reboot; it isn't in/etc/fstab).