Azure DevOps Pipeline— Blocked by Network Rules of Storage Account

tanut aran
3 min readMay 2, 2023

--

This article talks about the super basic CI/CD of

Deploying static web site: Azure DevOps → Azure Storage Account

Yes. How many night sacrifice fixing Azure issues?

One easy practice is allowing access by IP by doing something like

myip=$(curl -s ipv4.icanhazip.com | tr -d '\n')
echo "=== THIS MACHINE IP IS $myip"

az storage account network-rule add
--resource-group my-resource-group
--account-name mystorage
--ip-address $myip

az storage blob upload-batch -s ./out -d '$web'
--overwrite --account-name mystorage

This will not work when it is in the same Azure region. You will see the error like this:

ERROR: 
The request may be blocked by network rules of storage account. Please check network rule set using 'az storage account show -n accountname --query networkRuleSet'.
If you want to change the default action to apply when no rule matches, please use 'az storage account update'.

IP Whitelisting does not work due to Azure Private Network Routing

And there is no way to allow such private IP range.

The Community Hack: On-Off Technique

This hack originates from issue that Microsoft have never fixed since 2018
https://github.com/MicrosoftDocs/azure-docs/issues/19456

Azure route its same zone traffic through its backbone and no way to allow such vnet/ip despite the doc advestises it is possible but there is no concrete example or implementation steps
https://learn.microsoft.com/en-us/azure/storage/common/storage-network-security?tabs=azure-portal#grant-access-from-an-internet-ip-range

The Github suggested to turn on public, do your stuff then turn off public access quickly.

This is safe enough because we still have user/pass protection (Layer 7). Only network is exposed temporarily (Layer 4).

The script looks like below:

# Turn on public access
az storage account update
--resource-group "my-resource-group"
--name "mystorage"
--default-action Allow

# Or your operation here
az storage blob upload-batch
-s ./out -d '$web'
--overwrite --account-name myaccountname

# Turn off public access
az storage account update
--resource-group "my-resource-group"
--name "mystorage"
--default-action Deny

From the UI, it just switch the radio here

When switch back to Deny it will use the second option with your last configuration.

Good thing is that you don’t have to allow vnet/ip again when switch back.

The delay bug

Sometimes the Azure have the delay. Sleep will do the trick here.

# Turn on
sleep 10

# Your operation
...
# Turn off

Or you can break the Azure Pipeline Step into multiple steps. However, this still bug sometimes.

So if this is the case for you, add the sleep will help.

The Full Script

 - task: AzureCLI@2
displayName: Temporary Allow Public Access
inputs:
azureSubscription: 'service-connection...'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az storage account update --resource-group "rg-..." --name "myaccountname" --default-action Allow

- task: AzureCLI@2
displayName: Azure Storage Batch Upload
inputs:
azureSubscription: 'service-connection...'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az storage blob upload-batch -s ./out -d '$web' --overwrite --account-name myaccountname

- task: AzureCLI@2
displayName: Turn off Public Access
inputs:
azureSubscription: 'service-connection...'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az storage account update --resource-group "rg-..." --name "myaccountname" --default-action Deny

Hope this help !

--

--