Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Support Managed Service Identity for Storage connections #2109

Open
PhoenixHe-NV opened this issue Feb 1, 2019 · 12 comments

Comments

@PhoenixHe-NV
Copy link

Please provide a succinct description of the issue.

Repro steps

Currently Azure Storage supports Managed Service Identity. But azure webjob sdk only spports connection string for storage account. It would be great that webjob sdk support MSI.

Known workarounds

I've found some workarounds by inject storage account on registering. First I need to generate the CloudStorageAccount by MSI in advance. Then, there are two services I need to inject:

var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("webjob-lock");

var builder = new HostBuilder()
   .ConfigureWebJobs(b =>
   {
     b.Services.AddSingleton(new DistributedLockManagerContainerProvider
     {
       InternalContainer = container
     });
     b.Services.AddSingleton<StorageAccountProvider>(new ManagedIdentityStorageAccountProvider(storageAccount));

     b.AddAzureStorageCoreServices();
     b.AddAzureStorage();
     b.AddTimers();
   })
public class ManagedIdentityStorageAccountProvider : StorageAccountProvider
{
  private readonly CloudStorageAccount storageAccount;

  public ManagedIdentityStorageAccountProvider(CloudStorageAccount storageAccount) : base(null)
  {
    this.storageAccount = storageAccount;
  }

  public override StorageAccount Get(string name)
  {
    return StorageAccount.New(this.storageAccount);
  }
}

I'm still looking for official MSI support.

@PhoenixHe-NV
Copy link
Author

Any update on this one?

@ross-p-smith
Copy link

The above code fails for me as the StorageCredentails does not have an AccountName when created with a Token Credential. This would work if we could approve Pull Request #2000

@mmusin
Copy link

mmusin commented Oct 23, 2019

A year had passed...

@mdddev
Copy link

mdddev commented Jan 19, 2020

I want to try out the proposed workaround of @NullMDR but I am to inexperienced to actually apply it properly. Unfortunately the information in the code snippet provided, I don't know where to actually implement it. Is this program.cs or function.cs? Sorry for the lack of knowledge..

@mdddev
Copy link

mdddev commented Jan 20, 2020

Nevermind the above, it appears I have not read thoroughly enough.
The way I see it, you're explicitly defining the kind of storage account (i.e. the way it is created) in the DI. I am still new to all this, so apologies.

@mdddev
Copy link

mdddev commented May 14, 2020

FYI, this is working for Service Bus and Event Hub. Jeff Hollan, principal pm on the azure functions team informed on the reason why this is on twitter

https://twitter.com/jeffhollan/status/1260600212617179137

@cn894
Copy link

cn894 commented Dec 8, 2020

Hi, my team is still looking for official MSI support in the SDK. Has there been any update on this issue?

@GoradeAarti
Copy link

We are looking for official MSI support to get rid of storage connection string for WebJobs. any update on this issue?

@Erikvdv
Copy link

Erikvdv commented Feb 1, 2022

After a long search I found out it is now possible by just adding some settings in your appsettings.json:

"AzureWebJobsStorage": { "blobServiceUri": "https://{storageaccount}.blob.core.windows.net/", "queueServiceUri": "https://{storageaccount}.queue.core.windows.net/" },

@thegrahamking
Copy link

After a long search I found out it is now possible by just adding some settings in you appsettings.json:

"AzureWebJobsStorage": { "blobServiceUri": "https://{storageaccount}.blob.core.windows.net/", "queueServiceUri": "https://{storageaccount}.queue.core.windows.net/" },

Did you find this in the documentation?

@Erikvdv
Copy link

Erikvdv commented Feb 1, 2022

Found it in the azure functions docs:
https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference?tabs=blob#common-properties-for-identity-based-connections

@franklixuefei
Copy link
Member

it works for me using the following settings in appsettings.config with the latest release of the storage extension (5.0.0)

"AzureWebJobsStorage": {
    "accountName": "moxycpsa"
    // the following 2 lines need to be commented out in local dev mode. 
    // Otherwise, the Microsoft.Azure.WebJobs.Extensions.Storage extension will
    // try only to connect to MSI service ignoring local windows/azcli creds.
    // ONLY ENABLE THE FOLLOWING IN PROD ENV
    //"credential": "managedidentity",
    //"clientId": ""
  }

However, if webjobs.AddDurableTask(); is specified, then the above won't work, and the work around for that is using MSI to retrieve the account key and assemble the connection string:

private static string BuildAzureStorageConnectionString(IConfiguration config)
{
    var accountName = config.GetValue<string>("AzureWebJobsStorage:accountName");
    var subscription = config.GetValue<string>("AzureWebJobsStorage:subscription");
    var resourceGroup = config.GetValue<string>("AzureWebJobsStorage:resourceGroup");
    var clientId = config.GetValue<string?>("AzureWebJobsStorage:clientId", default);

    var creds = new DefaultAzureCredential(new DefaultAzureCredentialOptions
    {
        ManagedIdentityClientId = clientId,
    });
    var management = new ArmClient(creds);

    Console.WriteLine($"[{DateTime.UtcNow.ToString("u")}]\tGetting storage keys...");
    var account = management.GetStorageAccount(StorageAccount.CreateResourceIdentifier(subscription, resourceGroup, accountName));
    var keys = account.GetKeys();
    var key = keys.Value.Keys.First(k => k.Permissions == KeyPermission.Full).Value;
    Console.WriteLine($"[{DateTime.UtcNow.ToString("u")}]\tStorage key retrieved.");
    return $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={key};EndpointSuffix=core.windows.net";
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants