Search code examples
azureazure-devopsazure-storageazure-bicepazure-container-apps

How to mount File Share to an Azure Container Apps Environment in Bicep?


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.


Solution

  • 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

    1. the storage naming conventions, should always be small letters. So all parameters like accountname, sharename, and mountname should be small letters.

    2. When I deploy my solution, I use incremental mode.

    And it works, here are the final results:

    enter image description here