The idea is to have a small "workload" / "pipeline" with a function app used for calling some 3rd party API at scheduled intervals and writing the response to a blob storage.
So in terms of resources I need / want to have:
I pretty much want to have a reusable template, so I am trying to use bicep modules. This is so far the structure of my IaC project:
./main.bicep
./modules/AppServicePlan/ConsumptionPlan.bicep
./modules/FunctionApp/FunctionApp.bicep
./modules/KeyVault/KeyVault.bicep
./modules/KeyVault/Secret.bicep
./modules/Storage/StorageAccount.bicep
So, I am using StorageAccount.bicep
to create storage for data (from main.bicep
as a module) as well as storage for function (from FunctionApp.bicep
as a module). FunctionApp.bicep
is also creating an app service plan resource, and also assigns initial app settings (i.e. AzureWebJobsStorage
setting linking it to the storage for function).
I am also proceeding in a similar fashion with the keyvault. So I create a keyvault from main.bicep
as a module, passing in as parameter the object id of the function app so that it is allowed in the key vault access policies to get and list secrets.
Finally I am trying to update the app settings in the function app, to include reference to the secret in the keyvault. First I was trying the approach to "extend" with the new app settings as described in the Is there a workaround to keep app settings which not defined in Bicep template? I could not get it working. So now I am trying with a simpler approach, to replace the app settings entirely. However I am receiving an error saying the storage for function resource is not found (?)
"error\": {\r\n \"code\": \"ResourceNotFound\",\r\n \"message\": \"The Resource 'Microsoft.Storage/storageAccounts/<storageForFuncName>' under resource group '<resourceGroup>' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix\"\r\n }\r\n}"}
If I look in the deployment, all the sub-deployments including the one for storage for function succeeded, and it is only the main one that failed with the above error details. And in fact all the resources, apart from the updated app settings are created. Even the storage for function in question, and even the initial app settings that I create as part of the FunctionApp.bicep
, which by the way contains exactly the same AzureWebJobsStorage
key-value, that gives problem in main.bicep
when I try to create the updated app settings.
How could I fix this? Or should I change my approach with modules entirely?
(By the way, this is my first IaC project, I am new to bicep, but I am already pretty annoyed I need to do things like having to effectively re-declare resources using resource
and existing
, even though that were declared with module
, while also having to specifically mention the api version and type of resource. Just venting my frustration... ;) )
I tested deploying with empty initial app settings (i.e. app settings as part of the FunctionApp.bicep
) - I got the same outcome.
Every resource I created as module
I am declaring again as resource
and using existing
keyword, and adding it to the dependencies of the appsettings:
resource functionApp1AppSettings 'Microsoft.Web/sites/config@2022-09-01' = {
kind: 'string'
name: 'appsettings'
parent: functionApp1r // resource //https://github.com/Azure/bicep/issues/7328
properties: {
// these settings were created at the point of function app creation with the `FunctionApp.bicep`
AzureWebJobsFeatureFlags: 'EnableWorkerIndexing'
// the below line is the problematic one and the one giving error
AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount4funcName};EndpointSuffix=${environment().suffixes.storage};AccountKey=${storageAccount4func1r.listKeys().keys[0].value}'
FUNCTIONS_EXTENSION_VERSION: '~4'
FUNCTIONS_WORKER_RUNTIME: 'python'
WEBSITE_TIME_ZONE: 'Europe/Amsterdam'
// this is the "new" setting we are trying to update the appsettings with
KV_SOME_SECRET: '@Microsoft.KeyVault(VaultName=${keyVaultName};SecretName=${secret.name})'
}
dependsOn: [
functionApp1 //module
kv //module
kvr //existing resource of the above
storageAccounts4func //module
storageAccount4func1r //existing resource of the above
]
}
This did not help.
main.bicep
the following:var dummy = storageAccount4func1r.identity.principalId
output dummy string = dummy
as per the advice in: https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/error-not-found?tabs=bicep#solution-4-get-managed-identity-from-resource
but that did not help.
You can't declare the storage account resource and then use the existing function to retrieve the same storage account in the same bicep file. The error you are getting is likely from the existing function, because you cannot set a dependency for that. (Ie: It's trying to reference a resource that doesn't exist yet).
Try declaring the storage account in a level above your appSettings, then pass through the StorageAccount name to your appSettings bicep file. Then you can use the existing function there to retrieve your Storage Account reference and it should work.
If you post your bicep files it might also be easier to assist.