Search code examples
azureazure-functionsazure-management-api

ArgumentNullException when attempting to create KeyVault via Azure Management Fluent Api in Azure Function


I've added a service bus triggered function to create a key vault via the Microsoft.Azure.Management.Fluent library.

The function runs fine locally and creates a new key vault within my MSDN subscription, however, when it's deployed into Azure and tries to create a Key Vault in our company test subscription using the function app managed service identity it fails with an ArgumentNullException from Guid.Parse.

Stack Trace

Inner exception System.ArgumentNullException handled at CollectorFunctions.Proxies.KeyVaultProxy+d__9.MoveNext:
at System.Guid.Parse (System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.Management.KeyVault.Fluent.VaultsImpl.WrapModel (Microsoft.Azure.Management.KeyVault.Fluent, Version=1.0.0.68, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
at Microsoft.Azure.Management.KeyVault.Fluent.VaultsImpl.Define (Microsoft.Azure.Management.KeyVault.Fluent, Version=1.0.0.68, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
at Microsoft.Azure.Management.KeyVault.Fluent.VaultsImpl.Microsoft.Azure.Management.ResourceManager.Fluent.Core.CollectionActions.ISupportsCreating<Microsoft.Azure.Management.KeyVault.Fluent.Vault.Definition.IBlank>.Define (Microsoft.Azure.Management.KeyVault.Fluent, Version=1.0.0.68, Culture=neutral, PublicKeyToken=31bf3856ad364e35)
at CollectorFunctions.Proxies.KeyVaultProxy+d__9.MoveNext (CollectorFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullCollectorFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\src\Server\CollectorFunctions\Proxies\IKeyVaultProxy.csCollectorFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: 86)

The error occurs running the following statement which was taken from the ManageKeyVault sample project linked from this repro. The supplied parameters all have valid values and the resourceGroup was looked up via IAzure.ResourceGroups.GetByNameAsync(resourceGroupName).

await _azure.Vaults
      .Define(newKeyVaultName)
      .WithRegion(resourceGroup.Region)
      .WithExistingResourceGroup(resourceGroupName)
      .WithEmptyAccessPolicy()
      .CreateAsync();

Solution

  • In my case, I didn't realize there's a tenantId parameter when getting credentials. I needed to supply tenantId:

    var msi = new MSILoginInformation(MSIResourceType.VirtualMachine);
    var creds = SdkContext.AzureCredentialsFactory.FromMSI(msi,
     AzureEnvironment.AzureGlobalCloud, 
    *** tenantId ***);
    

    Since your stack trace looks exactly like mine, I'm guessing this is the problem. If you specify the tenantID when you get credentials then I think it should work for you. To get the TenantId go to the Azure AD where your identity resides and it should be listed on the overview page.