-
Notifications
You must be signed in to change notification settings - Fork 461
Description
Is your question related to a specific version? If so, please specify:
Azure Functions running under Linux Flex Consumption
What language does your question apply to? (e.g. C#, JavaScript, Java, All)
All
Question
It would appear that even with sufficient permissions, Flex Consumption Azure Functions on Linux do not support disabling system assigned managed identities. The scenario is I want to use user assigned managed identities exclusively in my development, but this seems like it is not documented.
I'd also like to avoid having to specify any connection strings, as the system assigned managed identity IaC Bicep example has (this is confirmed to be working)
Another example:
https://github.com/azure-samples/function-app-arm-templates/blob/main/function-app-linux-flex-consumption/azuredeploy.json#L220C5-L231C6
I would like to understand if this is a technical limitation and perhaps update the documentation which implies we can use user assigned managed identities here:
"When you use a user-assigned managed identity, the provided identity gets linked to the function app. The Storage Blob Data Contributor role scoped to the deployment storage account also gets assigned to the identity."
The actual error seen is during deployment with a command such as func azure functionapp publish appName --build remote
, it says it succeeds but will fail to Sync triggers with an error. Worth noting that attempting to run a HelloWorld function within the Azure Function results in 500:
Getting site publishing info...
[2025-03-04T22:46:17.400Z] Starting the function app deployment...
[2025-03-04T22:46:17.581Z] Creating archive for current directory...
Performing remote build for functions project.
Uploading 100.06 MB [#############################################################################]
Deployment in progress, please wait...
Starting deployment pipeline.
[SourcePackageUriDownloadStep] starting.
Zip package is present at /tmp/zipdeploy/576c41ce-f720-4f81-ae50-4bd7b7d331f4.zip
[ValidationStep] starting.
[AppSettingValidation] starting.
[DeploymentStorageValidation] starting.
Validation completed
[SourcePackageUriDownloadStep] starting.
Zip package is present at /tmp/zipdeploy/576c41ce-f720-4f81-ae50-4bd7b7d331f4.zip
[ExtractZipStep] starting.
Cleaning files in /tmp/zipdeploy/extracted
Extracted zip package in /tmp/zipdeploy/extracted
[OryxBuildStep] starting.
Running oryx build command: oryx build /tmp/zipdeploy/extracted -o /home/site/wwwroot --platform dotnet
Completed oryx build. Output is in /home/site/wwwroot
[PackageZipStep] starting.
Linux Consumption plan has a 1.5 GB memory limit on a remote build container. To check our service limit, please visit https://docs.microsoft.com/en-us/azure/azure-functions/functions-scale#service-limits
Artifact source for DotNet is /home/site/wwwroot.
Created zip file with artifacts as /home/site/artifacts/576c41ce-f720-4f81-ae50-4bd7b7d331f4.zip.
[UploadPackageStep] starting.
Using Kudu.Legion.Core.Storage.BlobContainerStorage
Created blob name: released-package.zip
Created blob uri: https://redacted.blob.core.windows.net/app-package-redacted-func-nvifxks/released-package.zip
Token Endpoint: http://169.254.255.2:8081/msi/token?api-version=1.0&resource=https://redacted.blob.core.windows.net&mi_res_id=/subscriptions/redacted/resourceGroups/redacted/providers/Microsoft.ManagedIdentity/userAssignedIdentities/redacted
Received Token using user assigned identity
Uploaded blob successfully.
Uploaded package to storage blob. Deployment is partially successful from here.
[RemoveWorkersStep] starting.
RemoveAllWorkers, statusCode = NoContent
Reset all workers was successful.
[SyncTriggerStep] starting.
Waiting 60 seconds for the workers to recycle with deployed content.
[CleanUpStep] starting.
Cleaned the source packages directory.
Cleaned the result artifact directory.
Finished deployment pipeline.
FunctionHostSyncTrigger, statusCode = InternalServerError
FunctionHostSyncTrigger, statusCode = InternalServerError
Checking the app health...................Deployment was successful but the app appears to be unhealthy, please check the app logs.
Here is my example Bicep template if that helps illustrate what I am attempting to do and how to reproduce the issue. Pardon any redacted inaccuracies.
param location string
param storageAccountName string
param functionAppName string
param appServicePlanName string
param appInsightsInstrumentationKey string
param userAssignedIdentityId string
param principalId string
var deploymentStorageContainerName = 'app-package-${take(functionAppName, 32)}-${take(uniqueString(subscription().id, functionAppName), 7)}'
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' existing = {
name: storageAccountName
}
resource blobService 'Microsoft.Storage/storageAccounts/blobServices@2023-05-01' = {
parent: storageAccount
name: 'default'
}
resource storageContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = {
parent: blobService
name: deploymentStorageContainerName
properties: {
publicAccess: 'None'
}
}
resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: appServicePlanName
location: location
sku: {
name: 'FC1'
tier: 'FlexConsumption'
}
properties: {
reserved: true
}
}
resource flexFuncApp 'Microsoft.Web/sites@2024-04-01' = {
name: functionAppName
location: location
kind: 'functionapp,linux'
identity: {
type: 'SystemAssigned, UserAssigned' // Once remove SystemAssigned, everything stops working. This can be reproduced by turning off SystemAssigned in Azure Portal.
userAssignedIdentities: {
'${userAssignedIdentityId}': {}
}
}
properties: {
serverFarmId: resourceId('Microsoft.Web/serverfarms', appServicePlanName)
siteConfig: {
appSettings: [
{
name: 'AzureWebJobsStorage__accountName'
value: storageAccount.name
}
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: appInsightsInstrumentationKey
}
]
cors: {
allowedOrigins: [
'*'
]
}
publicNetworkAccess: 'Enabled'
}
functionAppConfig: {
deployment: {
storage: {
type: 'blobContainer'
value: '${storageAccount.properties.primaryEndpoints.blob}${deploymentStorageContainerName}'
authentication: {
type: 'UserAssignedIdentity'
userAssignedIdentityResourceId: userAssignedIdentityId
}
}
}
scaleAndConcurrency: {
maximumInstanceCount: 100
instanceMemoryMB: 2048
}
runtime: {
name: 'dotnet-isolated'
version: '8.0'
}
}
}
dependsOn: [
storageContainer
]
}
var storageRoleDefinitionId = 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b' //Storage Blob Data Owner role
var storageContributorRole = subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'ba92f5b4-2d11-453d-a403-e96b0029c9fe'
) // Storage Blob Data Contributor
resource storageContainerAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
scope: storageAccount // Use when specifying a scope that is different than the deployment scope
name: guid(subscription().id, resourceGroup().id, flexFuncApp.id, storageContributorRole)
properties: {
roleDefinitionId: storageContributorRole
principalType: 'ServicePrincipal'
principalId: principalId
}
}
resource storageRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid('blobOwner', storageAccount.id, storageRoleDefinitionId)
scope: storageAccount
properties: {
description: 'Storage Blob Data Owner'
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageRoleDefinitionId)
principalType: 'ServicePrincipal'
principalId: principalId
}
}