Search code examples
azureazure-web-app-serviceazure-keyvaultapplication-serverpulumi

pulumi: add web app to key vault access policy, read secrets and set them as app setting


I'm using the azure nextgen provider. Given a key vault vault with a stored secret secret1.

  • How can I add the web app to the key vault's access policies?
  • How can I read the secret (get the url including version) and set it to a web app's setting?
  • What needs to be done first?

I haven't found any function in the pulumi documentation for these scenarios.

Script including missing parts:

import * as pulumi from "@pulumi/pulumi";
import * as random from "@pulumi/random";
import * as resources from "@pulumi/azure-nextgen/resources/latest";
import * as web from "@pulumi/azure-nextgen/web/latest";

const config = new pulumi.Config();
const location = config.require("location");

const resourceGroup = new resources.ResourceGroup("rootResourceGroup", {
    resourceGroupName: "resources",
    location,
});

const suffix = new random.RandomString("suffix", {
    length: 6,
    special: false,
    upper: false,
});

const appServicePlan = new web.AppServicePlan("appserviceplan", {
    name: "my-appservice-plan",
    resourceGroupName: resourceGroup.name,
    location,
    kind: "Linux",
    reserved: true,
    sku: {
        name: "B1",
        tier: "Basic",
    },
});


const vault = ???; // Get the vault by name
const secret1Identifier = vault.???; // fetch the secret by name

const webApp = new web.WebApp("web-app", {
    name: pulumi.interpolate`webapp${suffix.result}`,
    resourceGroupName: resourceGroup.name,
    location,
    serverFarmId: appServicePlan.id,
    identity: {
        type: "SystemAssigned",
    },
    siteConfig: {
        appSettings: [
            {
                name: "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
                value: "false",
            },
            {
                name: "SECRET1",
                value: pulumi.interpolate`@Microsoft.KeyVault(SecretUri=${secret1Identifier})`
            }
        ],
        alwaysOn: true,
    },
});

const principalId = webApp.identity.apply(id => id?.principalId);

vault.??? // Set access policy for web apps principal id

Solution

  • The correct order is:

    1. Secret
    2. Web App with the secret
    3. Access Policy

    KeyVault has an odd API model that is only partially exposed via Azure Resource Manager. At the moment, Azure NextGen doesn't have support for secrets, keys, certificates, or access policies. This is tracked in this issue.

    Meanwhile, you can use the "old" Azure provider to add missing objects. The two providers can be used from the same program. This example is close to what you are trying to achieve order-wise.