Use managed identity instead of AzureWebJobsStorage to connect a function app to a storage account
Published Oct 23 2022 08:45 PM 34.7K Views
Microsoft

In a function app, usually we use appsetting AzureWebJobsStorage to connect to storage. This blog shows you how to configure a function app using Azure Active Directory identities instead of secrets or connection strings, where possible. Using identities helps you avoid accidentally leaking sensitive secrets and can provide better visibility into how data is accessed.

 

This will not work if the storage account is in a sovereign cloud or has a custom DNS.

 

Below are the steps to do configuration.

 

1. Enable system assigned identity in your function app and save it.

Bobi_Bao_12-1666252447891.png

 

2. Give storage access to your function app. Search for Storage Blob Data Owner, select it.

Bobi_Bao_13-1666252447894.png

 

 

Bobi_Bao_14-1666252447896.png

 

Bobi_Bao_15-1666252447901.png

 

 

 

3. If you configure a blob-triggered function app, repeat the step 2 to add Storage Account Contributor and Storage Queue Data Contributor roles which will be used for blob trigger.

Bobi_Bao_16-1666252447903.png

 

Bobi_Bao_17-1666252447905.png

 

 

4. Return to Access Control (IAM), click Role assignments, search for your function app name to confirm the roles are added successfully.

Bobi_Bao_18-1666252447910.png

 

 

5. Navigate to your function app. Select Configuration and edit AzureWebJobsStorage. Change the name to AzureWebJobsStorage__accountname.  Change the value to your storage account name. (The new setting uses a double underscore (__), which is a special character in application settings.) 

Bobi_Bao_0-1666332053179.png

 

 

6. Delete the previous AzureWebJobsStorage. Then you will find your function app still works fine.

 

 

 

 

 

31 Comments
Brass Contributor

I use exactly that for a Function App I have. I replaced the setting AzureWebJobsStorage by AzureWebJobsStorage__accountname and removed the WEBSITE_CONTENTAZUREFILECONNECTIONSTRING which also contains the connection string to the storage account. However, I have a warning message because the WEBSITE_CONTENTAZUREFILECONNECTIONSTRING setting is needed for Azure Files mounting which is used by Azure Functions at the platform layer. However, having this implies using the secret connection string for the storage, and the whole point of using Managed Identity for Azure Storage was to avoid using a secret for Azure Storage. This issue says that Azure Files does not support using AAD identities for SMB mounting. So my question is:  when is it planned to be supported? Is it already the case and I'm missing something?

AlexandreNedelec_0-1666602840211.png

 

Iron Contributor

UI does not like missing AzureWebJobsStorage

 

GregorySuvalian_0-1666640576759.png

 

Copper Contributor

Is this possible using using User-Assigned Managed Identity? I posted a question around this on StackOverflow a while back https://stackoverflow.com/questions/73456357/user-assigned-managed-identity-for-function-app-to-acce...

Microsoft

Hi @Alexandre Nedelec, although both of AzureWebJobsStorage and WEBSITE_CONTENTAZUREFILECONNECTIONSTRING are pointed to the storage, it doesn't mean they have equal effect. WEBSITE_CONTENTAZUREFILECONNECTIONSTRING only be used in consumption plan and elastic premium plan. Besides, WEBSITE_CONTENTSHARE and WEBSITE_CONTENTAZUREFILECONNECTIONSTRING, these two settings are essential for the normal scale of the dynamic plan. The AzureWebJobsStorage__accountName can only replace AzureWebJobsStorage.

Brass Contributor

@Bobi_Bao Thanks for your answer. Do you know when will we be able to use WEBSITE_CONTENTAZUREFILECONNECTIONSTRING with managed identities? Because 
the whole point of using Managed Identity for Azure Storage was to avoid using a secret for Azure Storage. If we can remove the secret for AzureWebJobsStorage but have to let the same secret for other secret settings used for the consumption plan, it's a shame.

Microsoft

Does this work on Azure Functions Linux and Azure Functions Linux Containers?

Microsoft

@DanielLarsenNZ Yes it works when you use Linux Function app. 

Microsoft

@Alexandre Nedelec There is no eta for this feature. You can use key vault to store your secret: Use Key Vault references - Azure App Service | Microsoft Learn

 

Copper Contributor

I have this setup with system assigned identity, will it work with user assigned managed identity?

Brass Contributor

@Bobi_Bao I know that Azure Key Vault can be used here. Yet no secret is better than a secret. Using Managed Identities to remove one and not the other is kind of weird. I love developing using Azure Functions but this kind of missing feature is what makes me want to switch to other services.

Microsoft

@Bobi_Bao , Unfortunately if I have to keep using the secret to enable deployment and scale-out operations, I lose one of the key benefits of ManagedIdentity -- the benefit of not needing to automate secret rotation.  As far as I know there isn't even linkage built into KeyVault that would allow for automated secret rotation, so now I have to do all the work to generate new secret, insert it into KV, and update settings.  If I've built that much infra, why would I use a managed identity for AzureWebJobsStorage_accountName when I can just use the same KV reference to secret for AzureWebJobsStorage?
This is an honest question -- what are the pro's of using managed identity in this scenario?

Copper Contributor

 I have tested it with System Assigned Identity, and this works well. I have tested it  with user assigned managed identity, but it doesn't work.
Is there another way?

Microsoft

@Alexandre Nedelec @NeilHall-MSFT Currently it's recommended to use identity on dedicated app service plan as it doesn't need WEBSITE_CONTENTAZUREFILECONNECTIONSTRING for file share. Comparing with secret, managed identity allows you to grant access to resources based on roles and permissions, providing greater control and granularity over access to storage resources. Administrator can assign the appropriate roles to different users and service principals to limit permissions and enforce a principle of least privilege. Storage shared key provides more granular control over access to resources, allowing you to define specific permissions related to different operations, such as read, write, or delete operations. The choice of which method to use typically depends on the specific needs, security concerns, and implementation requirements of your application or service.

 

 

 

Microsoft

@sassaf_expertime @DirkSeLab System-assigned managed identities work by automatically creating an identity for the Azure service instance (such as a Function App), whereas user-assigned managed identities are created and managed by you, the user. As of now, only system-assigned managed identities have the capability to use managed identity for authenticating with Azure Storage, while user-assigned managed identities do not have this feature yet.

Microsoft

@Bobi_Bao any plans to add support for user-assigned identities? Our organization requires use of user-assigned identities that are managed via a separate Terraform deployment process. We don't have permission to assign RBAC roles to a system-assigned identity. We add the user-defined identities to the app service, and use the steps documented in https://learn.microsoft.com/en-us/azure/azure-app-configuration/howto-integrate-azure-managed-servic... to specify the client ID when initializing our blob storage client in code. Specifying the user-defined identity client ID as an app setting (or something similar) is something that would greatly simplify things.  It sounds like others on this thread would also benefit from this.

Microsoft

@dwhathaway , I think support for user-assigned managed identities is already delivered recently, but it works a little differently -- you have to add additional fx environment variables.  My teammate just discovered this yesterday, so your timing is great :).


https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference?tabs=blob#connecting-to-...

TL;DR; we had to set
AzureWebJobsStorage__credential: managedidentity
AzureWebJobsStorage__clientId: <client Id of the uami>
AzureWebJobsStorage__accountname: <storage account name>

And use RBAC to assign several roles.
Not sure all these are needed, especially if you aren't using durable functions, but we have `Storage Account Contributor`, `Storage Blob Data Owner` and `Storage Queue Data Contributor` assigned currently and may still be working through some issues with our durable azure function instance.

 

Microsoft

Thanks @NeilHall-MSFT! I'll give that a try.  We're still in the process of updating to the project to be able to use the extensions packages required, but this looks promising.

Copper Contributor

@dwhathaway - I just tried the recommendation by @NeilHall-MSFT and this works like a charm.


I do have the same question / feedback as @Alexandre Nedelec , without being able to use the MI for the
WEBSITE_CONTENTAZUREFILECONNECTIONSTRING setting as well, we cannot close local authentication on the storage account down. So supporting MI for this setting as well, would be great and an ETA appreciated!

Microsoft

hi @Bobi_Bao @NeilHall-MSFT @henrybeen 

 

How can I use other environment variables such as StorageConnectionString , 
AzureWebJobsDashboard,WEBSITE_DAAS_STORAGE_CONNECTIONSTRING

Copper Contributor

Hi @Bobi_Bao 

 

I am having an issue connecting a function app with a storage account when storage account key access is disabled. I get the error "System.Private.CoreLib: Access to the path 'C:\home\site\wwwroot\host.json' is denied." in the function app.

BernaldEze_0-1700810764182.png

 

the aim is to connect to the storage account without sharing secrets.

Any advice?

 

Microsoft

I am trying to setup my logic app(Standared) connecting to storage account via user managed identity .
I have applied all possible settings but could not get right  solution .

I have added below settings to app config
AzureWebJobsStorage__accountName,
AzureWebJobsStorage__credential ="managedidentity"
AzureWebJobsStorage__clientid,
AzureWebJobsStorAGE__blobServiceUri,
AzureWebJobsStorAGE__queueServiceUri,
AzureWebJobsStorAGE__fileServiceUri,
AzureWebJobsStorAGE__tableServiceUri

I have given "Storage account, blob, queue, file data contributor" data permission to User assigned MSI.
am I mssing in my settings?

Copper Contributor

I have the same situation as srinivas330.

I tried all settings, but logging complaints about only expecting connectionString or serviceUri.

When I only provide AzureWebJobsStorage__serviceUri and I point it to blob, I can instantiate only a blobserviceclient.

I also need a QueueClient...

Copper Contributor
@henrybeen  I am in similar situation, please let know if you got any solution for this ?

 

Copper Contributor

@umswamyNot yet, I haven't found an alternative. I also raised this in an other location to MS, but no reply so far. It seems that this is an open problem still. Unless I am mistaken, in that case I would love it if someone pointed me into the right direction :)

Microsoft

my function app has WEBSITE_CONTENTAZUREFILECONNECTIONSTRING and WEBSITE_CONTENTSHARE in the deployment arm template and everything was working. Removed these properties from arm template and that results in deployment failure Bad Request. 

Microsoft

@hponagantiIf your function app is running on a consumption/EP plan, these are two necessary settings that cannot be removed. In the case of a dynamic function app, which doesn't have dedicated workers on the backend, these settings are required to point out the file share.

Furthermore, it's important to note that, currently, the identity to connect Azure File is not supported. This means that if your function app is running on a consumption/EP plan, it is not recommended to use the identity method. As a result, you won't be able to utilize the identity in the WEBSITE_CONTENTAZUREFILECONNECTIONSTRING and WEBSITE_CONTENTSHARE settings, and consequently, you won't be able to disable shared key authentication.

Microsoft

My Function app is using App service plan and when i switch from AzureWebJobsStorage to AzureWebJobsStorage__accountname .
and given all roles to Identity on storage account.
The UI starts to fail with error:
Microsoft.Azure.WebJobs.Extensions.DurableTask: Unable to find an Azure Storage connection string to use for this binding.
any resolution for this issue?

i tried both user and system managed identity

 

Microsoft

@kamal600 Please scroll up and read my earlier comment to dwhathaway - they said what I suggested worked for them and we have used it successfully with durable functions.  There are additional variables and RBAC you need to set/apply when you're dealing with a *durable* Azure function.  

We still have not been able to move away from use of WEBSITE_CONTENT* with our use of an EP1 App Service Plan and our Functions on VNet(s), but for our durable functions that are using a PremiumV3 plan we're currently using only Azure Managed Identities.

Microsoft

hi @NeilHall-MSFT , i tried using user managed identity 
with following variables:
AzureWebJobsStorage__credential: managedidentity
AzureWebJobsStorage__clientId: <client Id of the uami>
AzureWebJobsStorage__accountname: <storage account name>

with these roles: Storage Blob Data Owner, Storage Queue Data Contributor, Storage Blob Data Contributor, Storage Table Data Contributor, Storage Account contributor.
but still getting error : Microsoft.Azure.WebJobs.Extensions.DurableTask: Unable to find an Azure Storage connection string to use for this binding.

and using system managed identity, using same above mentioned roles, and AzureWebJobsStorage__accountname: <storage account name>
still facing same error.
is there any step i am missing ? our function app has App Service Plan- P3V2

Microsoft

i was able to resolve above issue by updating the version of below package :

<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.11.0" />

Microsoft

@kamal600 for durable function, the best practice would be using Durable Functions extension versions 2.7.0 and greater. Reference: Configure Durable Functions with Microsoft Entra ID | Microsoft Learn

Co-Authors
Version history
Last update:
‎Oct 24 2022 02:30 AM
Updated by: