Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
429 stars 182 forks source link

Azure Functions: Exception with Managed Identity and EventGrid source for Blob Trigger #1890

Open gp-nttdata opened 1 year ago

gp-nttdata commented 1 year ago

Hello everyone. I am having a problem with Azure Function with a Blob Trigger: Environment:

.NET: 7
Function SDK: 4
Blob Extension Version: 6.1.0
Process Mode: Isolated

After following this tutorial https://learn.microsoft.com/en-us/azure/azure-functions/functions-event-grid-blob-trigger to change the transport from BlobTriggerSource.LogsAndContainerScan to BlobTriggerSource.EventGrid everything was working fine. I was able to enter (and debug) the function when I uploaded a new file to the storage account.

When I tried to use Managed Identity, instead of a connection string, I got the following error:

Exception: Microsoft.Azure.Functions.Worker.FunctionInputConverterException: Error converting 1 input parameters for Function '<FUNCTION_NAME>': Cannot convert input parameter 'stream' to type 'System.IO.Stream' from type 'Microsoft.Azure.Functions.Worker.Grpc.Messages.GrpcModelBindingData'. Error:System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString')

with the following call stack:

- at Microsoft.Azure.Functions.Worker.BlobStorageConverter.CreateBlobContainerClient(String connectionName, String containerName) in D:\a\_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:line 253
- at Azure.Storage.StorageConnectionString.Parse(String connectionString)
- at Azure.Storage.Blobs.BlobServiceClient..ctor(String connectionString, BlobClientOptions options)
- at Microsoft.Azure.Functions.Worker.BlobStorageConverter.ConvertModelBindingDataAsync(Type targetType, BlobBindingData blobData) in D:\a\_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:line 118
- at Microsoft.Azure.Functions.Worker.BlobStorageConverter.ConvertFromBindingDataAsync(ConverterContext context, ModelBindingData modelBindingData) in D:\a\_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\BlobStorageConverter.cs:line 63
- at Microsoft.Azure.Functions.Worker.BlobStorageBindingOptions.CreateClient() in D:\a\_work\1\s\extensions\Worker.Extensions.Storage.Blobs\src\Config\BlobStorageBindingOptions.cs:line 35
- at Microsoft.Azure.Functions.Worker.Context.Features.DefaultFunctionInputBindingFeature.BindFunctionInputAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Context\Features\DefaultFunctionInputBindingFeature.cs:line 105

In my local.settings.json I have added the settings as per described here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-trigger (section "Identity-based connections").

Is Managed Identity with EventGrid source for Blob Trigger Azure Function supported ?

gp-nttdata commented 1 year ago

@fabiocav Hello again. I am coming back in just to check if there has been any investigation going on ? As this functionality is very important to us, I would be really glad if you could share any update on the ticket?

Thanks again for your help and cooperation. Kind regards.

hunderi commented 1 year ago

This is an issue for us as well.

.NET: 7
Function SDK: 4
Blob Extension Version: 6.2.0
Process Mode: Isolated

If I use a managed identity connection and BlobTrigger I get the same error:

Exception: Microsoft.Azure.Functions.Worker.FunctionInputConverterException: Error converting 1 input parameters for 
Function 'IngestFunction': Cannot convert input parameter 'stream' to type 'System.IO.Stream' from type 
'Microsoft.Azure.Functions.Worker.Grpc.Messages.GrpcModelBindingData'. Error:System.ArgumentNullException: Value cannot 
be null. (Parameter 'connectionString')

The connectionstring parameter is stored with the __serviceUri suffix.

Attribute binding:

public async Task UploadFile([BlobTrigger("archive-json/{name}", 
Connection = "StorageAccountConnectionString")] Stream stream, string name)

We will move away from manged identity and back to using a storage key for the time being.

kurt-mueller-osumc commented 1 year ago

Hi @hunderi and @gp-nttdata,

I ran into this exact same problem and I managed to get my blob trigger working by enabling the blob storage extension. You can find an official azure function template example here:

https://github.com/Azure/azure-functions-templates/blob/dev/Functions.Templates/ProjectTemplate_v4.x/FSharp-Isolated/Program.fs#L15

Specifically, I enabled this line:

appBuilder.ConfigureBlobStorageExtension() |> ignore

I believe I also had to install this nuget package.

https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Storage

edit - I just realized you all are probably using the C# isolated version of Azure Functions, not the F# isolated version. My apologies. Hopefully, enabling the right extension may still be applicable.

NathanAWhitworth commented 11 months ago

We also ran into this issue while using the serviceUri form and the Queue access seems to have been the problem.

The blob trigger handles failure across multiple retries by writing poison blobs to a queue. In the serviceUri form, the AzureWebJobsStorage connection is used.

https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-trigger#identity-based-connections

We were using Azurite for AzureWebJobsStorage when testing this, which doesn't appear to work with this setup.

Passing blobServiceUri and queueServiceUri separately (both pointing to a storage account) and assigning Storage Queue Data Contributor on the account got it working.

MatthiasVnh commented 6 months ago

Is there any update on this ticket? I have just recently run into this very same issue when upgrading from .NET 6 (in-process) to .NET 8 (Isolated).

rav4coding commented 6 months ago

I got same issue when upgrading from .NET 6 (in-process) to .NET 8 (Isolated). It works if I switch back to full connection string (with key).

ZurenoC commented 5 months ago

I'm also very interested in this issue, connection string works perfectly. Using "blobservice__serviceUri": "https://.blob.core.windows.net/", it fires when it detects a file, but doesn't even get to the method's { before failing. Also running .NET 8 isolated

ibis7 commented 4 months ago

Having the same problem upgrading from .NET 6 in-process to .NET 8 isolated.

Edit:

What @NathanAWhitworth said works, in the Function Environment Variables I had to add two new ones:

StorageAccountConnectionblobServiceUri and StorageAccountConnectionqueueServiceUri

With those variables it should work fine (you should also check the roles, in my case I already had those)

enzosambucetti commented 4 months ago

Same problem here.

pianomanjh commented 3 months ago

Having the same problem upgrading from .NET 6 in-process to .NET 8 isolated.

Edit:

What @NathanAWhitworth said works, in the Function Environment Variables I had to add two new ones:

StorageAccountConnectionblobServiceUri and StorageAccountConnectionqueueServiceUri

With those variables it should work fine (you should also check the roles, in my case I already had those)

@ibis7 Did you have StorageAccountConnectionserviceUri and StorageAccountConnectionblobServiceUri pointing to the same url? I've also run into this issue. Additionally, is your function storage account (AzureWebJobsStorage) the same or a different storage account? Thanks!

ibis7 commented 3 months ago

@pianomanjh I don't remember the initial value of serviceUri, but blobServiceUri and queueServiceUri ended up with different urls (one pointing to the queue service and the other one to the blob service). We also were able to remove the old serviceUri variable. Regarding the storage account, we are pointing to a different one from the function storage account.

DC0507 commented 2 months ago

Hello everyone, I was working hard with @pianomanjh to get the right approach to enable Managed Identity for his Blob Trigger.

Finally, we got it with the below steps:

Steps.docx

Any questions or comments, feel free to reach me out.

kurt-mueller-osumc commented 2 months ago

Hello everyone, I was working hard with @pianomanjh to get the right approach to enable Managed Identity for his Blob Trigger.

Finally, we got it with the below steps:

Steps.pdf

Any questions or comments, feel free to reach me out.

@DC0507 unfortunately I don't have the necessary permissions to access the doc.

DC0507 commented 2 months ago

Hi, @kurt-mueller-osumc. I updated the file. Please let me know if you can view the contents. If no, I could paste here the steps.

kurt-mueller-osumc commented 2 months ago

No joy. Now I get prompted to sign in to my microsoft account.

DC0507 commented 2 months ago

Testing resources:

• Function App: dotnet-isolated-test • Storage Account: devtestingba05

  1. In my Function App, I enabled Managed Identity (System Assigned):
  2. In the Storage Accout (IAM) blade, I added the three roles: Storage Blob Data Owner, Storage Account Contributor and Storage Queue Data Contributor.
  3. In my code, I left the prefix of my Storage Account (devtestingba05_STORAGE):
  4. In the App Settings, I modify the AzureWebJobsStorage setting and value. Also, I added the required settings for the blob and queue:

"name": AzureWebJobsStorage__accountname", "value": "devtestingba05" #The name of your Storage Account

"name": "devtestingba05_STORAGE__blobServiceUri" #StorageAccountName_STORAGE__blobServiceURI "value": "https://devtestingba05.blob.core.windows.net/" #https://StorageAccountName.blob.core.windows.net/

"name": "devtestingba05_STORAGE__queueServiceUri" #StorageAccountName_STORAGE__queueServiceURI "value": "https://devtestingba05.queue.core.windows.net/" #https://StorageAccountName.queue.core.windows.net/

pianomanjh commented 2 months ago

Note, I was able to get the blob trigger and Stream parameter working with just the MyAccount__blobServiceUri and MyAccount__queueServiceUri configuration set. (Set to the triggering blob account). I did not need the __accountname. I also have not attempted to use Managed Identity for the actual AzureWebJobs storage account yet.