pulumi-azure: Unable to assing keyvault Access Policy to function app identity

I try to set up a azure function with a managed identity to get permission to access a keyvault.

import * as pulumi from "@pulumi/pulumi";
import * as azure from "@pulumi/azure";

const current = pulumi.output(azure.core.getClientConfig({}));

const resourceGroup = new azure.core.ResourceGroup("resourceGroup", {
    location: "WestUS",
});

const plan = new azure.appservice.Plan("plan", {
    kind: "functionapp",
    location: resourceGroup.location,
    name: "plan",
    resourceGroupName: resourceGroup.name,
    sku: {
        size: "Y1",
        tier: "Dynamic",
    },
});

const storage = new azure.storage.Account("storage", {
    accountKind: "StorageV2",
    accountReplicationType: "LRS",
    accountTier: "Standard",
    location: resourceGroup.location,
    name: "storage",
    resourceGroupName: resourceGroup.name,
});

const functionApp = new azure.appservice.FunctionApp("function", {
    appServicePlanId: plan.id,
    identity: {
        type: "SystemAssigned",
    },
    location: resourceGroup.location,
    name: "function",
    resourceGroupName: resourceGroup.name,
    storageConnectionString: storage.primaryConnectionString,
    version: "~2",
});
const keyvault = new azure.keyvault.KeyVault("keyvault", {
    location: resourceGroup.location,
    name: "keyvault",
    resourceGroupName: resourceGroup.name,
    sku: {
        name: "standard",
    },
    tenantId: current.apply(current => current.tenantId),
});

const app = new azure.keyvault.AccessPolicy("app", {
    keyPermissions: [],
    keyVaultId: keyvault.id,
    objectId: functionApp.identity.apply(identity => identity.principalId),
    secretPermissions: ["get"],
    tenantId: functionApp.identity.apply(identity => identity.tenantId),
});

this script results in following error:

$ pulumi up
Previewing update (dev3):

     Type                             Name           Plan       Info
 +   pulumi:pulumi:Stack              test2-dev3     create
 +   ├─ azure:core:ResourceGroup      resourceGroup  create
 +   ├─ azure:keyvault:KeyVault       keyvault       create
 +   ├─ azure:appservice:Plan         plan           create
 +   ├─ azure:storage:Account         storage        create
 +   ├─ azure:appservice:FunctionApp  function       create
     └─ azure:keyvault:AccessPolicy   app                       2 errors

Diagnostics:
  azure:keyvault:AccessPolicy (app):
    error: azure:keyvault/accessPolicy:AccessPolicy resource 'app' has a problem: "tenant_id": required field is not set
    error: azure:keyvault/accessPolicy:AccessPolicy resource 'app' has a problem: "object_id": required field is not set

error: an error occurred while advancing the preview

Why does pulumi does not accept the tenant_id and object_id the pulumi.Output as field?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 30 (18 by maintainers)

Commits related to this issue

Most upvoted comments

I tried it with the latest version and, FWIW, the workaround still works both for the initial preview and subsequent updates, both for TypeScript and C#.

@ilmax This C# snippet resolves the problem for me:

var principalId = appService.Identity.Apply(id => id.PrincipalId ?? "11111111-1111-1111-1111-111111111111");

I agree the workaround isn’t great and is hard to discover.

Reopening - we’ve seen a lot of folks continue to hit this - and although it is arguably “by design” currently:

  1. That design leads to violating our type system
  2. It’s very unintuitive and hard to even figure out why it’s happening or what to do

I think we will need to continue to think about improving the experience here.

BTW - two available workaround until this is fixed:

  1. Do pulumi up --skip-preview on the first deployment. This issue only affects when a preview is done before any updates have been done, so will not occur on future pulumi ups.

  2. Add a default value in the .apply - like functionApp.identity.apply(identity => identity.principalId || "11111111-1111-1111-1111-111111111111") (in this case, ensuring the default passes the UUID length check). This default shouldn’t be needed (that’s the bug here), but will only be seen on the first ever preview before any deployment has completed.

As an update on this issue:

  • We closed this issue thinking https://github.com/pulumi/pulumi/issues/4992 addressed this issue. However, it only addresses the case for updates where the resource already exists (as pointed out above).
  • The previously documented workaround (to use apply(s => s || "default")) should continue to work in the create case. In the case of updates, pulumi/pulumi#4992 should address the spurious diffs previously seen. If you’re still seeing spurious diffs on preview, please post in this issue.
  • We’re investigating ways to improve the behavior for creates such that we can flow unknown values through.

I also run into that problem, this is not that intuitiv.

@pgavlin this is happening with the C# SDK as well and the identity.principalId ?? "11111111-1111-1111-1111-111111111111" doesn’t seems to work.

Sample code:

var appService = new AppService(name, appServiceArgs);
new AccessPolicy($"read-{name}", new AccessPolicyArgs
{
	KeyVaultId = GetOutputValue("Azure:KeyVault:Id"),
	ObjectId = appService.Identity.Apply(identity => identity.PrincipalId),
	TenantId = tenantId,
	SecretPermissions = new InputList<string>
	{
		"get",
		"list"
	}
});

Is there a work around also for the C# SDK other than pulumi up --skip-preview? Moreover do you want me to open a new issue?

@pat 🤦‍♂ I’m sorry for disturbing!