Använda Azure Key Vault till att säkert skicka parametervärden under en distribution

I stället för att placera ett säkert värde (t.ex. ett lösenord) direkt i mallen eller parameterfilen kan du hämta värdet från en Azure-Key Vault under en distribution. Du hämtar värdet genom att referera till nyckelvalvet och hemligheten i parameterfilen. Värdet exponeras aldrig eftersom du bara refererar till dess nyckelvalvs-ID.

Viktigt

Den här artikeln fokuserar på hur du skickar ett känsligt värde som en mallparameter. När hemligheten skickas som en parameter kan nyckelvalvet finnas i en annan prenumeration än den resursgrupp som du distribuerar till.

Den här artikeln beskriver inte hur du anger en virtuell datoregenskap till ett certifikats URL i ett nyckelvalv. En snabbstartsmall för det scenariot finns i Installera ett certifikat från Azure Key Vault på en virtuell dator.

Distribuera nyckelvalv och hemligheter

Om du vill komma åt ett nyckelvalv under malldistributionen ställer du in enabledForTemplateDeployment nyckelvalvet truepå .

Om du redan har ett nyckelvalv kontrollerar du att det tillåter malldistributioner.

az keyvault update  --name ExampleVault --enabled-for-template-deployment true

Om du vill skapa ett nytt nyckelvalv och lägga till en hemlighet använder du:

az group create --name ExampleGroup --location centralus
az keyvault create \
  --name ExampleVault \
  --resource-group ExampleGroup \
  --location centralus \
  --enabled-for-template-deployment true
az keyvault secret set --vault-name ExampleVault --name "ExamplePassword" --value "hVFkk965BuUv"

Som ägare till nyckelvalvet har du automatiskt åtkomst till att skapa hemligheter. Om du behöver låta en annan användare skapa hemligheter använder du:

az keyvault set-policy \
  --upn <user-principal-name> \
  --name ExampleVault \
  --secret-permissions set delete get list

Åtkomstprinciperna behövs inte om användaren distribuerar en mall som hämtar en hemlighet. Lägg bara till en användare i åtkomstprinciperna om användaren behöver arbeta direkt med hemligheterna. Distributionsbehörigheterna definieras i nästa avsnitt.

Mer information om hur du skapar nyckelvalv och lägger till hemligheter finns i:

Bevilja distributionsåtkomst till hemligheterna

Den användare som distribuerar mallen Microsoft.KeyVault/vaults/deploy/action måste ha behörighet för resursgruppens och nyckelvalvets omfång. Genom att kontrollera den här åtkomsten förhindrar Azure Resource Manager en icke-godkänd användare från att komma åt hemligheten genom att skicka in resurs-ID:t för nyckelvalvet. Du kan bevilja distributionsåtkomst till användare utan att ge skrivåtkomst till hemligheterna.

Rollerna Ägare och Deltagare beviljar båda den här åtkomsten. Om du har skapat nyckelvalvet är du ägare och har behörigheten .

För andra användare beviljar du behörigheten Microsoft.KeyVault/vaults/deploy/action . Följande procedur visar hur du skapar en roll med minsta behörighet och tilldelar den till en användare.

  1. Skapa en JSON-fil för anpassad rolldefinition:

    {
      "Name": "Key Vault resource manager template deployment operator",
      "IsCustom": true,
      "Description": "Lets you deploy a resource manager template with the access to the secrets in the Key Vault.",
      "Actions": [
        "Microsoft.KeyVault/vaults/deploy/action"
      ],
      "NotActions": [],
      "DataActions": [],
      "NotDataActions": [],
      "AssignableScopes": [
        "/subscriptions/00000000-0000-0000-0000-000000000000"
      ]
    }
    

    Ersätt "00000000-0000-0000-0000-000000000000" med prenumerations-ID:t.

  2. Skapa den nya rollen med JSON-filen:

    az role definition create --role-definition "<path-to-role-file>"
    az role assignment create \
      --role "Key Vault resource manager template deployment operator" \
      --scope /subscriptions/<Subscription-id>/resourceGroups/<resource-group-name> \
      --assignee <user-principal-name> \
      --resource-group ExampleGroup
    

    Exemplen tilldelar den anpassade rollen till användaren på resursgruppsnivå.

När du använder ett nyckelvalv med mallen för ett hanterat program måste du bevilja åtkomst till tjänstens huvudnamn för installationsresursprovidern . Mer information finns i Access Key Vault secret when deploying Azure Managed Applications (Åtkomst Key Vault hemlighet när du distribuerar Azure Managed Applications).

Referenshemligheter med statiskt ID

Med den här metoden refererar du till nyckelvalvet i parameterfilen, inte mallen. Följande bild visar hur parameterfilen refererar till hemligheten och skickar det värdet till mallen.

Diagram som visar Resource Manager key vault-integrering med statiskt ID.

Självstudie: Integrera Azure Key Vault i distribution av Resource Manager-mall använder den här metoden.

Följande mall distribuerar en SQL-server som innehåller ett administratörslösenord. Lösenordsparametern är inställd på en säker sträng. Men mallen anger inte var värdet kommer från.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "sqlServerName": {
      "type": "string"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "adminLogin": {
      "type": "string"
    },
    "adminPassword": {
      "type": "securestring"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2021-11-01",
      "name": "[parameters('sqlServerName')]",
      "location": "[parameters('location')]",
      "properties": {
        "administratorLogin": "[parameters('adminLogin')]",
        "administratorLoginPassword": "[parameters('adminPassword')]",
        "version": "12.0"
      }
    }
  ]
}

Skapa nu en parameterfil för föregående mall. I parameterfilen anger du en parameter som matchar namnet på parametern i mallen. För parametervärdet refererar du till hemligheten från nyckelvalvet. Du refererar till hemligheten genom att skicka resursidentifieraren för nyckelvalvet och namnet på hemligheten:

I följande parameterfil måste nyckelvalvshemligheten redan finnas och du anger ett statiskt värde för dess resurs-ID.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminLogin": {
      "value": "exampleadmin"
    },
    "adminPassword": {
      "reference": {
        "keyVault": {
          "id": "/subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<vault-name>"
        },
        "secretName": "ExamplePassword"
      }
    },
    "sqlServerName": {
      "value": "<your-server-name>"
    }
  }
}

Om du behöver använda en annan version av hemligheten än den aktuella versionen inkluderar du secretVersion egenskapen .

"secretName": "ExamplePassword",
"secretVersion": "cd91b2b7e10e492ebb870a6ee0591b68"

Distribuera mallen och skicka parameterfilen:

az group create --name SqlGroup --location westus2
az deployment group create \
  --resource-group SqlGroup \
  --template-uri <template-file-URI> \
  --parameters <parameter-file>

Referenshemligheter med dynamiskt ID

I föregående avsnitt visades hur du skickar ett statiskt resurs-ID för nyckelvalvshemligheten från parametern . I vissa fall måste du referera till en nyckelvalvshemlighet som varierar beroende på den aktuella distributionen. Eller så kanske du vill skicka parametervärden till mallen i stället för att skapa en referensparameter i parameterfilen. Lösningen är att dynamiskt generera resurs-ID:t för en nyckelvalvshemlighet med hjälp av en länkad mall.

Du kan inte generera resurs-ID:t dynamiskt i parameterfilen eftersom malluttryck inte tillåts i parameterfilen.

I den överordnade mallen lägger du till den kapslade mallen och skickar in en parameter som innehåller det dynamiskt genererade resurs-ID:t. Följande bild visar hur en parameter i den länkade mallen refererar till hemligheten.

Diagram som illustrerar dynamisk ID-generering för key vault-hemlighet.

Följande mall skapar dynamiskt nyckelvalvs-ID:t och skickar det som en parameter.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
      "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]",
        "metadata": {
          "description": "The location where the resources will be deployed."
        }
      },
      "vaultName": {
        "type": "string",
        "metadata": {
          "description": "The name of the keyvault that contains the secret."
        }
      },
      "secretName": {
        "type": "string",
        "metadata": {
          "description": "The name of the secret."
        }
      },
      "vaultResourceGroupName": {
        "type": "string",
        "metadata": {
          "description": "The name of the resource group that contains the keyvault."
        }
      },
      "vaultSubscription": {
        "type": "string",
        "defaultValue": "[subscription().subscriptionId]",
        "metadata": {
          "description": "The name of the subscription that contains the keyvault."
        }
      }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2020-10-01",
      "name": "dynamicSecret",
      "properties": {
        "mode": "Incremental",
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {
            "adminLogin": {
              "type": "string"
            },
            "adminPassword": {
              "type": "securestring"
            },
            "location": {
              "type": "string"
            }
          },
          "variables": {
            "sqlServerName": "[concat('sql-', uniqueString(resourceGroup().id, 'sql'))]"
          },
          "resources": [
            {
              "type": "Microsoft.Sql/servers",
              "apiVersion": "2021-11-01",
              "name": "[variables('sqlServerName')]",
              "location": "[parameters('location')]",
              "properties": {
                "administratorLogin": "[parameters('adminLogin')]",
                "administratorLoginPassword": "[parameters('adminPassword')]"
              }
            }
          ],
          "outputs": {
            "sqlFQDN": {
              "type": "string",
              "value": "[reference(variables('sqlServerName')).fullyQualifiedDomainName]"
            }
          }
        },
        "parameters": {
          "location": {
            "value": "[parameters('location')]"
          },
          "adminLogin": {
            "value": "ghuser"
          },
          "adminPassword": {
            "reference": {
              "keyVault": {
                "id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
              },
              "secretName": "[parameters('secretName')]"
            }
          }
        }
      }
    }
  ]
}

Nästa steg