Deploying ARM template (stored in private BLOB Container) using Managed Identity (without SAS)

Copper Contributor

We have a requirement for deploying Azure ARM template(s) which are stored in Storage Account BLOB container (Private access level), from an Azure function app.

 

We have configured managed Identity (system assigned) for Azure function app. Have configured RBAC for Azure function app managed identity to give 'Storage Blob Data Reader' access to respective Storage Account.

 

Executing below command fails:

New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name "StorageAccountARMDeployment-Anil" -TemplateUri $blobFromContainer.BlobClient.Uri
 

Receive below error (when Blob container is set to private access without SAS token being passed):

-------------------------------------------------------------------------------------------------------------

Line |
126 | … eployment = New-AzResourceGroupDeployment -ResourceGroupName $resourc …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1:07:13 PM - Error: Code=InvalidContentLink; Message=Unable to download deployment content from
| 'https://saam02.blob.core.windows.net/ciam02/azuredeploy.json'. The tracking Id is
| 'd6c54597-c70b-4fb4-b636-735fe21f868c'. Please see https://aka.ms/arm-deploy for usage details.

New-AzResourceGroupDeployment: C:\Anil\HandsOn\Cloud\Azure\SourceCode\Utility.Powershell\ps_deploy_armtemplate_blob.ps1:126
Line |
126 | … eployment = New-AzResourceGroupDeployment -ResourceGroupName $resourc …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The deployment validation failed

 

-------------------------------------------------------------------------------------------------------------

 

Note:

1.) When Blob Container access level is set to anonymous it works successfully (but for security reason we need to set Blob Container to private access).

2.) When we explicit pass SAS token while deploying ARM template (stored in private Blob Container) it works.

 

Need clarity & confirmation, if it is possible to deploy ARM template (stored in private BLOB Container) using Managed Identity, without the need of SAS.

 

Any help is much appreciated. Thanks.

1 Reply

@AnilKumar82 

Alternatively, you can try Azure SDK. make sure you have the correct permissions on the IAM of the storage account.

from azure.identity import ManagedIdentityCredential
from azure.storage.blob import BlobServiceClient
from azure.core.exceptions import ResourceNotFoundError
from azure.mgmt.resource import ResourceManagementClient

# Authenticate with the function app's managed identity
credential = ManagedIdentityCredential()

# Get the blob storage account connection string from the app settings
connection_string = os.environ['AzureWebJobsStorage']

# Get a reference to the ARM template blob
blob_service_client = BlobServiceClient.from_connection_string(connection_string, credential=credential)
container_client = blob_service_client.get_container_client('templates')
blob_client = container_client.get_blob_client('template.json')

# Download the ARM template contents to a local file
try:
    template_contents = blob_client.download_blob().content_as_text()
except ResourceNotFoundError:
    logging.error("ARM template blob not found")
    return

# Use the Azure SDK to deploy the ARM template
resource_client = ResourceManagementClient(credential, subscription_id)
deployment_properties = {
    'mode': DeploymentMode.incremental,
    'template': json.loads(template_contents),
    'parameters': {}
}
deployment_async_operation = resource_client.deployments.begin_create_or_update(
    resource_group_name,
    deployment_name,
    deployment_properties
)
deployment_async_operation.wait()