Currently, I am facing a problem with mounting a File Share to Azure Container App Environment.
The problem is that volume mounting is not idempotent and if the volume mount with the same name already exists, on running the pipeline and bicep I get an error:
Invalid request body for managed environment storage 'storageMountName'. Only 'properties.azureFile.AccountKey' can be updated
My bicep module:
param storageName string
param storageMountName string
param storageFileShareName string
param ACAEnvironmentResourceName string
@secure()
param storageAccountKey string
resource containerEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' existing = {
name: ACAEnvironmentResourceName
}
resource qdrantstorage 'Microsoft.App/managedEnvironments/storages@2023-05-01' = {
parent: containerEnvironment
name: storageMountName
properties: {
azureFile: {
accountName: storageName
shareName: storageFileShareName
accountKey: storageAccountKey
accessMode: 'ReadWrite'
}
}
}
I've tried mounting a volume with a unique name and there is no issue at all, everything runs smoothly.
The problem is when I try to 're-mount' the volume.
I get why it could be a problem, but that behavior makes the bicep template 'Microsoft.App/managedEnvironments/storages@2023-05-01'
idempotent.
What I am currently trying is to find a workaround in which I can check if a mounted volume with the given name already exists, if it does I will make the step of mounting conditional.
Please note just, I am new to bicep and if my approach is wrong let me know.
From what I can see in your Bicep code, you are trying to mount File Share to an Azure Container Apps Environment in Bicep. I can not see your storage creation information. In other words, 'Microsoft.App/managedEnvironments/storages@2023-05-01'
does not either create a storage account or file share, or/and one of your storage parameter names has a capital letter, as mentioned in note one below.
With that said you need to add the missing elements, so something like the following is a working example:
var storageName = 'uniquenamemax24chr'
var shareName = 'share'
var mountName = 'storagemountname'
resource containerEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' existing = {
name: ACAEnvironmentResourceName
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageName
location: location
kind: 'Storage'
sku: {
name: 'Standard_LRS'
}
}
resource fileService 'Microsoft.Storage/storageAccounts/fileServices/shares@2023-01-01' = {
name: '${storageAccount.name}/default/${shareName}'
properties: {}
}
resource qdrantstorage 'Microsoft.App/managedEnvironments/storages@2023-05-01' = {
parent: containerEnvironment
name: mountName
properties: {
azureFile: {
accountName: storageName
shareName: shareName
accountKey: storageAccount.listKeys().keys[0].value
accessMode: 'ReadWrite'
}
}
}
If you have the storage account and file storage created already, you can use the same concept you could either pass it as a parameter or use existing to fetch the object of storage and pass the required variables.
Notes
the storage naming conventions, should always be small letters. So all parameters like accountname
, sharename
, and mountname
should be small letters.
When I deploy my solution, I use incremental mode.
And it works, here are the final results: