In our previous posts, we built a secure bridge (VPN) and taught our servers to speak to each other by name (Private DNS). Today, we tackle the final challenge: How do we access a Storage Account without ever touching the public internet?
Enter Azure Private Link.
The Architecture: Total Isolation
By default, Azure Storage is a public service with a public endpoint. Even with a VPN, your traffic usually "hairpins" out to the internet to reach your blobs.
In Level 3, we create a Private Endpoint. This gives our Storage Account a local IP address inside our VNet.
๐ ๏ธ The Implementation
We will disable all public access to our Storage Account and create a "Private Link" into our branch network.
# 1. Create Storage (Public Access: Disabled)
$storage = New-AzStorageAccount -ResourceGroupName $rgName -Name $storageName `
-Location $location -SkuName Standard_LRS -Kind StorageV2 `
-PublicNetworkAccess Disabled
# 2. Deploy Private Endpoint into VNet-B
$vnet2 = Get-AzVirtualNetwork -Name "branch-vnet" -ResourceGroupName $rgName
$subB = Get-AzVirtualNetworkSubnetConfig -Name "workload-subnet" -VirtualNetwork $vnet2
$privateEndpoint = New-AzPrivateEndpoint -ResourceGroupName $rgName -Name "StoragePE" `
-Location $location -Subnet $subB `
-PrivateLinkServiceConnection (New-AzPrivateLinkServiceConnection -Name "StorageConn" `
-PrivateLinkServiceId $storage.Id -GroupId "blob")
# 3. Configure Private DNS (The Glue)
$dnsZone = New-AzPrivateDnsZone -ResourceGroupName $rgName -Name "privatelink.blob.core.windows.net"
# Link to both VNets... (See full script for details)
๐งช The Moment of Truth: Writing Data Privately
To prove this works, we log into VM-Alpha and attempt to upload a file. Since the Storage Account is blocked from the internet, this only works because of the VPN tunnel and Private Link.
The Test Command
# Inside VM-Alpha
nslookup securestorage.blob.core.windows.net
Expected Result: You should see a private IP (e.g., 10.1.1.5) instead of a public one.
๐ ๏ธ The Advanced Test Implementation
Here is advanced test script to showcase.
# Get Storage Access Key for authentication
$storageKey = (Get-AzStorageAccountKey -ResourceGroupName $rgName -Name $storageName)[0].Value
# Define the Test Commands to be run inside VM-Alpha
$testScript = @"
# 1. Install Azure CLI
if ! command -v az &> /dev/null; then
sudo apt-get update && sudo apt-get install -y azure-cli
fi
# 2. Set environment variables
export AZURE_STORAGE_ACCOUNT="$storageName"
export AZURE_STORAGE_KEY="$storageKey"
# 3. Create a test file
echo "Hello from the Hub VNet via VPN Tunnel" > /tmp/vpn-test.txt
# 4. Create container and upload file via Private Link
az storage container create --name "vpn-test-container" --public-access off
az storage blob upload --container-name "vpn-test-container" --file /tmp/vpn-test.txt --name "secret-data.txt"
# 5. List blobs to verify
az storage blob list --container-name "vpn-test-container" --output table
"@
# Execute the test
$result = Invoke-AzVMRunCommand -ResourceGroupName $rgName -VMName "VM-Alpha" `
-CommandId "RunShellScript" -ScriptString $testScript
๐งช The Proof: Zero-Trust Data Transfer
When we execute this script, VM-Alpha reaches out to the storage account. Because we disabled public access, this request would fail for anyone else on the planet. But for our Hub VM, the request is routed through the VPN to the Private Endpoint in the Branch VNet.
Successful Test Output:
{
"created": true
}
{
"client_request_id": "410d9589-1202-11f1-b4da-d3f7b8188762",
"content_md5": "IA6vTR1vHj8h81hFNXPZRA==",
"date": "2026-02-25T04:27:11+00:00",
"etag": "\"0x8DE742625901407\"",
"lastModified": "2026-02-25T04:27:12+00:00",
"request_id": "419f5bb6-901e-0070-150f-a6dc67000000",
"request_server_encrypted": true,
"version": "2026-02-06"
}
The File is Securely Stored:
Name Blob Type Blob Tier Length Content Type Last Modified
--------------- ----------- ----------- -------- -------------- -------------------------
secret-data.txt BlockBlob Hot 39 text/plain 2026-02-25T04:27:12+00:00
[stderr]
Finished[#############################################################] 100.0000%
๐ Conclusion: You Are Now a Cloud Architect
Congratulations! You have successfully progressed through three levels of Azure Networking:
- Level 1: Basic Connectivity (VPN Tunnel)
- Level 2: Service Discovery (Private DNS)
- Level 3: Data Sovereignty (Private Link)
Your infrastructure is now built on Zero Trust principles. Your data is encrypted, your services are hidden, and your architecture is professional-grade.
What's next? Now that your "Private Bridge" is complete, you could explore Hub-and-Spoke topologies or Azure Firewall to start inspecting the traffic passing through your tunnel!
Top comments (0)