Använd Key Vault referenser som appinställningar i Azure App Service och Azure Functions

Den här artikeln visar hur du använder hemligheter från Azure Key Vault som värden för appinställningar eller anslutningssträngar i dina App Service eller Azure Functions appar.

Azure Key Vault är en tjänst som tillhandahåller centraliserad hantering av hemligheter med fullständig kontroll över åtkomstprinciper och granskningshistorik. När en appinställning eller anslutningssträng är en referens för nyckelvalvet kan din programkod använda den som vilken annan appinställning eller anslutningssträng som helst. På så sätt kan du bevara hemligheter förutom appens konfiguration. Appinställningarna krypteras säkert i vila, men om du behöver funktioner för hemlighetshantering bör de gå till ett nyckelvalv.

Ge din app åtkomst till ett nyckelvalv

För att kunna läsa hemligheter från ett nyckelvalv måste du ha skapat ett valv och ge din app behörighet att komma åt det.

  1. Skapa ett nyckelvalv genom att följa Key Vault snabbstart.

  2. Skapa en hanterad identitet för ditt program.

    Nyckelvalvsreferenser använder appens systemtilldelade identitet som standard, men du kan ange en användartilldelad identitet.

  3. Auktorisera läsåtkomst till hemligheter i nyckelvalvet för den hanterade identitet som du skapade tidigare. Hur du gör det beror på behörighetsmodellen för ditt nyckelvalv:

Åtkomst till nätverksbegränsade valv

Om valvet har konfigurerats med nätverksbegränsningar kontrollerar du att programmet har nätverksåtkomst. Valv bör inte vara beroende av appens offentliga utgående IP-adresser eftersom ursprungs-IP-adressen för den hemliga begäran kan vara annorlunda. I stället ska valvet konfigureras för att acceptera trafik från ett virtuellt nätverk som används av appen.

  1. Kontrollera att programmet har konfigurerat utgående nätverksfunktioner enligt beskrivningen i App Service nätverksfunktioner och Azure Functions nätverksalternativ.

    Linux-program som ansluter till privata slutpunkter måste uttryckligen konfigureras för att dirigera all trafik via det virtuella nätverket. Det här kravet tas bort i en kommande uppdatering. Kör följande kommando för att konfigurera den här inställningen:

    az webapp config set --subscription <sub> -g <group-name> -n <app-name> --generic-configurations '{"vnetRouteAllEnabled": true}'
    
  2. Kontrollera att valvets konfiguration tillåter det nätverk eller undernät som appen använder för att komma åt det.

Få åtkomst till valv med en användartilldelad identitet

Vissa appar måste referera till hemligheter när de skapas, när en systemtilldelad identitet inte är tillgänglig ännu. I dessa fall kan en användartilldelad identitet skapas och ges åtkomst till valvet i förväg.

När du har beviljat behörigheter till den användartilldelade identiteten följer du dessa steg:

  1. Tilldela identiteten till ditt program om du inte redan har gjort det.

  2. Konfigurera appen så att den använder den här identiteten för key vault-referensåtgärder genom att ange keyVaultReferenceIdentity egenskapen till resurs-ID för den användartilldelade identiteten.

    identityResourceId=$(az identity show --resource-group <group-name> --name <identity-name> --query id -o tsv)
    az webapp update --resource-group <group-name> --name <app-name> --set keyVaultReferenceIdentity=${identityResourceId}
    

Den här inställningen gäller för alla key vault-referenser för appen.

Rotation

Om den hemliga versionen inte anges i referensen använder appen den senaste versionen som finns i nyckelvalvet. När nyare versioner blir tillgängliga, till exempel med en rotationshändelse, uppdateras appen automatiskt och börjar använda den senaste versionen inom 24 timmar. Fördröjningen beror på att App Service cachelagrar värdena för nyckelvalvsreferenser och gör en ny hämtning var 24:e timme. Alla konfigurationsändringar i appen orsakar en omstart av appen och en omedelbar ominstallation av alla refererade hemligheter.

Inställningar för källappen från nyckelvalvet

Om du vill använda en key vault-referens anger du referensen som värdet för inställningen. Din app kan referera till hemligheten via dess nyckel som vanligt. Inga kodändringar krävs.

Tips

De flesta appinställningar som använder key vault-referenser bör markeras som platsinställningar, eftersom du bör ha separata valv för varje miljö.

En key vault-referens har formatet @Microsoft.KeyVault({referenceString}), där {referenceString} finns i något av följande format:

Referenssträng Description
SecretUri=secretUri SecretUri ska vara den fullständiga dataplans-URI:n för en hemlighet i valvet, eventuellt inklusive en version, t.ex. https://myvault.vault.azure.net/secrets/mysecret/ ellerhttps://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931
VaultName=vaultName; SecretName=secretName; SecretVersion=secretVersion VaultName krävs och är valvnamnet. SecretName krävs och är det hemliga namnet. SecretVersion är valfritt, men om det finns anger den version av hemligheten som ska användas.

En fullständig referens skulle till exempel se ut som följande sträng:

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)

Du kan också:

@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)

Att tänka på vid montering av Azure Files

Appar kan använda programinställningen WEBSITE_CONTENTAZUREFILECONNECTIONSTRING för att montera Azure Files som filsystem. Den här inställningen har valideringskontroller för att säkerställa att appen kan startas korrekt. Plattformen förlitar sig på att ha en innehållsresurs inom Azure Files och förutsätter ett standardnamn om inget anges via inställningenWEBSITE_CONTENTSHARE. För begäranden som ändrar de här inställningarna verifierar plattformen om den här innehållsresursen finns och försöker skapa den om den inte finns. Om den inte kan hitta eller skapa innehållsresursen blockeras begäran.

När du använder key vault-referenser i den här inställningen misslyckas valideringskontrollen som standard eftersom själva hemligheten inte kan matchas när den inkommande begäran bearbetas. För att undvika det här problemet kan du hoppa över verifieringen genom att ange WEBSITE_SKIP_CONTENTSHARE_VALIDATION till "1". Den här inställningen instruerar App Service att kringgå alla kontroller och skapar inte innehållsresursen åt dig. Du bör se till att den skapas i förväg.

Varning

Om du hoppar över valideringen och anslutningssträngen eller innehållsresursen är ogiltig kan appen inte starta korrekt och kommer bara att hantera HTTP 500-fel.

Som en del av skapandet av appen kan monteringsförsök av innehållsresursen misslyckas på grund av att hanterade identitetsbehörigheter inte sprids eller att integreringen av det virtuella nätverket inte har konfigurerats. Du kan skjuta upp konfigurationen av Azure Files till senare i distributionsmallen för att hantera detta. Mer information finns i Distribution av Azure Resource Manager. I det här fallet använder App Service ett standardfilsystem tills Azure Files har konfigurerats och filer inte kopieras över. Du måste se till att inga distributionsförsök görs under övergångsperioden innan Azure Files monteras.

Överväganden för Application Insights-instrumentation

Appar kan använda APPINSIGHTS_INSTRUMENTATIONKEY programinställningarna eller APPLICATIONINSIGHTS_CONNECTION_STRING för att integrera med Application Insights. Portalupplevelser för App Service och Azure Functions även använda de här inställningarna för att visa telemetridata från resursen. Om dessa värden refereras från Key Vault är dessa funktioner inte tillgängliga, och du måste i stället arbeta direkt med Application Insights-resursen för att visa telemetrin. Dessa värden betraktas dock inte som hemligheter, så du kan också överväga att konfigurera dem direkt i stället för att använda key vault-referenser.

Azure Resource Manager-distribution

När du automatiserar resursdistributioner via Azure Resource Manager mallar kan du behöva sekvensera dina beroenden i en viss ordning för att den här funktionen ska fungera. Se till att definiera dina appinställningar som en egen resurs i stället för att använda en siteConfig egenskap i appdefinitionen. Det beror på att appen måste definieras först så att den systemtilldelade identiteten skapas med den och kan användas i åtkomstprincipen.

Följande pseudomall är ett exempel på hur en funktionsapp kan se ut:

{
    //...
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            //...
        },
        {
            "type": "Microsoft.Insights/components",
            "name": "[variables('appInsightsName')]",
            //...
        },
        {
            "type": "Microsoft.Web/sites",
            "name": "[variables('functionAppName')]",
            "identity": {
                "type": "SystemAssigned"
            },
            //...
            "resources": [
                {
                    "type": "config",
                    "name": "appsettings",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('storageConnectionStringName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('appInsightsKeyName'))]"
                    ],
                    "properties": {
                        "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "APPINSIGHTS_INSTRUMENTATIONKEY": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('appInsightsKeyName')).secretUriWithVersion, ')')]",
                        "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                        //...
                    }
                },
                {
                    "type": "sourcecontrols",
                    "name": "web",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                    ],
                }
            ]
        },
        {
            "type": "Microsoft.KeyVault/vaults",
            "name": "[variables('keyVaultName')]",
            //...
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                //...
                "accessPolicies": [
                    {
                        "tenantId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.tenantId]",
                        "objectId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                        "permissions": {
                            "secrets": [ "get" ]
                        }
                    }
                ]
            },
            "resources": [
                {
                    "type": "secrets",
                    "name": "[variables('storageConnectionStringName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
                    ],
                    "properties": {
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),'2019-09-01').key1)]"
                    }
                },
                {
                    "type": "secrets",
                    "name": "[variables('appInsightsKeyName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
                    ],
                    "properties": {
                        "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2019-09-01').InstrumentationKey]"
                    }
                }
            ]
        }
    ]
}

Anteckning

I det här exemplet beror distributionen av källkontroll på programinställningarna. Detta är normalt osäkert eftersom uppdateringen av appinställningen fungerar asynkront. Men eftersom vi har inkluderat programinställningen WEBSITE_ENABLE_SYNC_UPDATE_SITE är uppdateringen synkron. Det innebär att distributionen av källkontrollen bara startar när programinställningarna har uppdaterats helt. Fler appinställningar finns i Miljövariabler och appinställningar i Azure App Service.

Felsöka key vault-referenser

Om en referens inte matchas korrekt används referenssträngen i stället (till exempel @Microsoft.KeyVault(...)). Det kan orsaka att programmet genererar fel eftersom det förväntar sig en hemlighet med ett annat värde.

Det går inte att lösa problemet på grund av en felaktig konfiguration av Key Vault åtkomstprincip. Men det kan också bero på att en hemlighet inte längre finns eller ett syntaxfel i själva referensen.

Om syntaxen är korrekt kan du visa andra orsaker till fel genom att kontrollera aktuell lösningsstatus i portalen. Gå till Programinställningar och välj Redigera för referensen i fråga. Redigeringsdialogrutan visar statusinformation, inklusive eventuella fel. Om du inte ser statusmeddelandet innebär det att syntaxen är ogiltig och inte känns igen som en referens för nyckelvalvet.

Du kan också använda en av de inbyggda detektorerna för att få ytterligare information.

Använda detektorn för App Service

  1. I portalen navigerar du till din app.
  2. Välj Diagnostisera och lösa problem.
  3. Välj Tillgänglighet och prestanda och välj Webbapp nedåt.
  4. I sökrutan söker du efter och väljer Key Vault Diagnostik för programinställningar.

Använda detektorn för Azure Functions

  1. I portalen navigerar du till din app.
  2. Gå till Plattformsfunktioner.
  3. Välj Diagnostisera och lösa problem.
  4. Välj Tillgänglighet och prestanda och välj Funktionsappen är nere eller rapporterar fel.
  5. Välj Key Vault Diagnostik för programinställningar.