My Brain Dump
How can a Function App access Azure Key Vault secrets?

Known Issue and workaround:
I referenced the issue I was observing and used the recommended work around.
Below is the workaround.
Function App
First, provide an identity value to the Function App declaration:
Identity = new FunctionAppIdentityArgs { Type = "SystemAssigned" },
Here’s a code snippet that includes the declaration:
return
new FunctionApp(functionApp, new FunctionAppArgs()
{
Identity = new FunctionAppIdentityArgs { Type = "SystemAssigned" },
Name = functionApp,
Location = resourceGroup.Location,
ResourceGroupName = resourceGroup.Name,
AppServicePlanId = plan.Id,
StorageAccountName = storageAccount.Name,
AppSettings = new InputMap<string>() { appSettings, lookup },
StorageAccountAccessKey = storageAccount.PrimaryAccessKey
});
ObjectId = functionApps.First().Identity.Apply(v => v.PrincipalId ?? "11111111-1111-1111-1111-111111111111")
Key Vault
Here’s a code snippet for the Key Vault:
new Classic.KeyVault.Inputs.KeyVaultAccessPolicyArgs
{
TenantId = current.TenantId,
//////////////////////////////////////////////////////////////////////
// THIS LINE
ObjectId = functionApps.First().Identity.Apply(v => v.PrincipalId ?? "11111111-1111-1111-1111-111111111111"),
//////////////////////////////////////////////////////////////////////
KeyPermissions = new[]
{
"List", "Create", "Get"
},
SecretPermissions = new[]
{
"List", "Get", "Set", "Delete", "Purge", "Recover"
},
},
Here’s the full KeyVault declaration:
using System.Linq;
using Pulumi;
using Pulumi.Azure.AppService;
using Pulumi.AzureNative.Resources;
using System.Collections.Generic;
using Classic = Pulumi.Azure;
namespace IaC.MyApp.Client;
public static class ClassicVault
{
public static Classic.KeyVault.KeyVault Build(ResourceGroup resourceGroup, string vaultName, IEnumerable<FunctionApp> functionApps)
{
var current = Classic.Core.GetClientConfig.InvokeAsync().Result;
return
new Classic.KeyVault.KeyVault(vaultName, new Classic.KeyVault.KeyVaultArgs()
{
Name = vaultName,
Location = resourceGroup.Location,
ResourceGroupName = resourceGroup.Name,
EnabledForDiskEncryption = true,
TenantId = current.TenantId,
SoftDeleteRetentionDays = 7,
PurgeProtectionEnabled = false,
SkuName = "standard",
AccessPolicies = new[]
{
new Classic.KeyVault.Inputs.KeyVaultAccessPolicyArgs
{
TenantId = current.TenantId,
ObjectId = current.ObjectId,
KeyPermissions = new[]
{
"List", "Create", "Get"
},
SecretPermissions = new[]
{
"List", "Get", "Set", "Delete", "Purge", "Recover"
},
},
new Classic.KeyVault.Inputs.KeyVaultAccessPolicyArgs
{
TenantId = current.TenantId,
ObjectId = functionApps.First().Identity.Apply(v => v.PrincipalId ?? "11111111-1111-1111-1111-111111111111"),
KeyPermissions = new[]
{
"List", "Create", "Get"
},
SecretPermissions = new[]
{
"List", "Get", "Set", "Delete", "Purge", "Recover"
},
},
},
});
}
}
Declare Azure Resources
var functionApps = FunctionsApps .Build(resourceGroup, storageAccount, plan, container, busNamespace, authRule, configuration.AppProfiles);
var vault = ClassicVault .Build(resourceGroup, KeyVault, functionApps);
var secrets = ClassicSecrets .Build(vault, new LabelValues(configuration.Secrets));