Skip to content

Azure Storage Output binding doesn't work with ACL only right #2578

Open
@hugogirard

Description

@hugogirard

Using Azure Functions in Isolated worker process using .NET 8, I am trying to use the BlobOutput trigger to write to a storage account using identity-based connections (managed identity).

I am not using RBAC but rather ACL in the storage account (datalake storage)
I am getting a permissions denied when trying to write to a folder.

Image

For reference here is the ACL configuration:
On the root container

Image

On the folder:

Image

Here is the code (very simple example):

Image

Is there something in the BlobOutput code that makes writing to ACL not working? Using pure SDK code, as shown below, it works. As you can see, we are using the ManagedIdentityCredential to connect to the storage.

using System;
using System.Net;
using System.Reflection.Metadata;
using System.Text;
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace Contoso
{
    public class GetFile
    {
        private readonly ILogger _logger;
        private readonly BlobServiceClient _blobServiceClient;

        public GetFile(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<GetFile>();

            _blobServiceClient = new BlobServiceClient(new Uri($"https://dteastushg29.blob.core.windows.net"),
                                                       new ManagedIdentityCredential());
        }

        [Function("GetFile")]
        public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req, FunctionContext context)
        //public void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer)
        {
            _logger.LogInformation($"Function executed: {DateTime.Now}");

            var container = _blobServiceClient.GetBlobContainerClient("doc");

            string inputFolder = "result/";
            string outputFolder = "labs";

            await foreach (BlobItem blobItem in container.GetBlobsAsync(prefix: inputFolder))
            {
                Console.WriteLine($"Found blob: {blobItem.Name}");

                BlobClient blobClient = container.GetBlobClient(blobItem.Name);

                // Download the blob's content
                BlobDownloadInfo download = await blobClient.DownloadAsync();

                // Read the content
                using (StreamReader reader = new StreamReader(download.Content))
                {
                    string content = await reader.ReadToEndAsync();
                    _logger.LogInformation($"Content of {blobItem.Name}:\n{content}\n");

                    string outputBlob = $"{outputFolder}/{blobItem.Name.Split('/')[1]}";
                    var output = container.GetBlobClient(outputBlob);

                    try
                    {
                        byte[] bytes = Encoding.UTF8.GetBytes(content);
                        using (MemoryStream stream2 = new MemoryStream(bytes))
                        {
                            var uploadOptions = new BlobUploadOptions
                            {
                                Conditions = new BlobRequestConditions() // This allows overwriting the blob
                            };
                            await output.UploadAsync(stream2, uploadOptions);
                        }

                    }
                    catch (System.Exception ex)
                    {
                        _logger.LogError(ex.Message);
                    }
                }
            }

            var httpResponse = req.CreateResponse(HttpStatusCode.OK);

            return httpResponse;
        }
    }
}

Side note that the BlobTrigger works using ACL, only the output binding doesn't.

Thank

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions