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

I stället för att lägga till ett säkert värde (till exempel 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. Nyckelvalvet kan finnas i en annan prenumeration än den resursgrupp som du distribuerar till.

Den här artikeln fokuserar på hur du skickar ett känsligt värde som en mallparameter. Artikeln beskriver inte hur du anger en egenskap för en virtuell dator 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 anger enabledForTemplateDeployment du för nyckelvalvet till true .

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 måste ha behörighet Microsoft.KeyVault/vaults/deploy/action för omfånget för resursgruppen och nyckelvalvet. Genom att kontrollera den här åtkomsten 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 bevilja skrivbehörighet 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 Microsoft.KeyVault/vaults/deploy/action behörigheten. 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-0000000000000" 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" \
      --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 programmåste du bevilja åtkomst till tjänstens huvudnamn för resursprovidern för installationen. Mer information finns i Access Key Vault secret when deploying Azure Managed Applications.

Referera till hemligheter 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.

Resource Manager statiskt ID-diagram för Key Vault-integrering

Självstudie: Integrera Azure Key Vault i Resource Manager Malldistribution 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": {
    "adminLogin": {
      "type": "string"
    },
    "adminPassword": {
      "type": "securestring"
    },
    "sqlServerName": {
      "type": "string"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2015-05-01-preview",
      "name": "[parameters('sqlServerName')]",
      "location": "[resourceGroup().location]",
      "tags": {},
      "properties": {
        "administratorLogin": "[parameters('adminLogin')]",
        "administratorLoginPassword": "[parameters('adminPassword')]",
        "version": "12.0"
      }
    }
  ],
  "outputs": {
  }
}

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>

Referera till hemligheter med dynamiskt ID

Föregående avsnitt visade 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 dynamiskt generera resurs-ID:t i parameterfilen eftersom malluttryck inte tillåts i parameterfilen.

I den överordnade mallen lägger du till den kapslade mallen och skickar 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.

Dynamiskt ID

Följande mall skapar nyckelvalvs-ID:t dynamiskt 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": "2018-06-01-preview",
              "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')]"
            }
          }
        }
      }
    }
  ],
  "outputs": {
  }
}

Nästa steg