azureazure-functionsazure-storage-accountvnetazure-blob-trigger

Azure Function App Blob trigger using Managed Identity not working


In azure I have got a Function App deployed in a VNET, alongside a subnet containing a private endpoint connected to a Storage Account through private DNS zones (one for each of the storage types), which is configured to only allow access from selected virtual networks and IP addresses. The RBAC role of Storage Blob Data Owner has been assigned to the function app.

I have created a blob trigger using Visual Studio:

    [Function(nameof(BlobTriggered))]
     public async Task BlobTriggered([BlobTrigger("testContainer/{name}", Connection = "Storage")] Stream stream, string name) {
       // Log information
    }

In the portal I have set the following environment variables:

Storage = DefaultEndpointsProtocol=https;AccountName=testStorage2342;EndpointSuffix=core.windows.net;Authentication=ManagedIdentity
Storage__blobServiceUri = https://testStorage2342.blob.core.windows.net

My Storage Account has the following containers:

testContainer
azure-webjobs-hosts
azure-webjobs-secrets

Alongside Visual Studio created two containers in the Storage and an environment variable called AzureWebJobsStorage__AccountName.

Whenever I deploy the Function App and add a file to the testContainer, nothing happens. If I click on the function in the portal and select "Integration" and click on the Trigger, it shows no existing storage account connection. Any ideas how to solve this?

EDIT:

I tried with the proposed approach, by letting the storage account reside in the same VNET as the subnet of the function app, and created a service endpoint to the function app subnet from the storage account. However, I get "This requeist is not authorized to perform this operation using this permission" in the overview of my function app.

My environment variables now looks as follows:

AzureWebJobsStorage__accountName = testStorage2342
Storage__accountName = testStorage2342
Storage__blobServiceUri = https://testStorage2342.blob.core.windows.net
Storage__credential = managedidentity

Any idea why it is still not working?


Solution

  • Firstly, In Storage account Integrated with Vnet:

    enter image description here

    Then, Created a Function App in same Location as Storage account and Integrated Same Vnet:

    enter image description here

    Enabled Managed Identity in it:

    enter image description here

    Gave Storage blob Owner and Contributor Role to Function App Managed Identity:

    enter image description here

    Then added below app settings:

    enter image description here

    {
        "name": "rithcon__accountName",
        "value": "rithwik81cf",
        "slotSetting": false
      },
      {
        "name": "rithcon__blobServiceUri",
        "value": "https://rithwik81cf.blob.core.windows.net/",
        "slotSetting": false
      },
      {
        "name": "rithcon__credential",
        "value": "managedIdentity",
        "slotSetting": false
      },
      {
        "name": "rithcon__queueServiceUri",
        "value": "https://rithwik81cf.queue.core.windows.net/",
        "slotSetting": false
      }
    

    Code:

    Function.cs:

    using System.IO;
    using System.Threading.Tasks;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;
    
    namespace FunctionApp16
    {
        public class Function1
        {
            private readonly ILogger<Function1> _logger;
    
            public Function1(ILogger<Function1> logger)
            {
                _logger = logger;
            }
    
            [Function(nameof(Function1))]
            public async Task Run([BlobTrigger("rithcnt/{name}", Connection = "rithcon")] Stream stream, string name)
            {
                using var blobStreamReader = new StreamReader(stream);
                var content = await blobStreamReader.ReadToEndAsync();
                _logger.LogInformation($"C# Blob trigger function Processed blob\n Name: {name} \n Data: {content}");
            }
        }
    }
    

    Integration section looks like this:

    enter image description here

    Output:

    Function app gets triggered:

    enter image description here