Delen via


Zelfstudie: Implementatiescripts gebruiken om een zelfondertekend certificaat te maken

Meer informatie over het gebruik van implementatiescripts in Azure Resource Manager-sjablonen (ARM-sjablonen). Implementatiescripts kunnen worden gebruikt om aangepaste stappen uit te voeren die niet door ARM-sjablonen kunnen worden uitgevoerd. Bijvoorbeeld het maken van een zelfondertekend certificaat. In deze zelfstudie maakt u een sjabloon voor het implementeren van een Azure-sleutelkluis en gebruikt u vervolgens een Microsoft.Resources/deploymentScripts resource in dezelfde sjabloon om een certificaat te maken en voegt u het certificaat vervolgens toe aan de sleutelkluis. Zie Implementatiescripts gebruiken in ARM-sjablonen voor meer informatie over implementatiescripts.

Belangrijk

Er worden twee implementatiescriptresources, een opslagaccount en een containerinstantie, gemaakt in dezelfde resourcegroep voor het uitvoeren en oplossen van problemen. Deze resources worden meestal verwijderd door de scriptservice wanneer de scriptuitvoering een terminalstatus krijgt. U wordt gefactureerd voor de resources totdat de resources zijn verwijderd. Zie Implementatiescriptresources opschonen voor meer informatie.

In deze handleiding worden de volgende taken behandeld:

  • Een snelstartsjabloon openen
  • De sjabloon bewerken
  • De sjabloon implementeren
  • Fouten opsporen in het mislukte script
  • De hulpbronnen opschonen

Zie ARM-sjablonen uitbreiden met behulp van implementatiescripts voor een Learn-module die betrekking heeft op implementatiescripts.

Vereiste voorwaarden

U hebt het volgende nodig om dit artikel te voltooien:

  • Visual Studio Code.

  • Een door de gebruiker toegewezen beheerde identiteit. Deze identiteit wordt gebruikt om Azure-specifieke acties uit te voeren in het script. Zie Door de gebruiker toegewezen beheerde identiteit om er een te maken. U hebt de id nodig wanneer u de sjabloon implementeert. De indeling van de identiteit is:

    /subscriptions/<SubscriptionID>/resourcegroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<IdentityID>
    

    Gebruik het volgende CLI-script om de id op te halen door de naam van de resourcegroep en de identiteitsnaam op te geven.

    echo "Enter the Resource Group name:" &&
    read resourceGroupName &&
    az identity list -g $resourceGroupName
    

Een snelstartsjabloon openen

In plaats van een volledig nieuwe sjabloon te maken, opent u een sjabloon vanuit Azure-quickstartsjablonen. Azure-snelstartsjablonen is een opslagplaats voor ARM-sjablonen.

De sjabloon die in deze quickstart wordt gebruikt, heet Een Azure Key Vault en een geheim maken. De sjabloon maakt een sleutelkluis en voegt vervolgens een geheim toe aan de sleutelkluis.

  1. In Visual Studio Code, selecteer Bestand>Openen.

  2. Plak in de bestandsnaam de volgende URL:

    https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.keyvault/key-vault-create/azuredeploy.json
    
  3. Selecteer Openen om het bestand te openen.

  4. Selecteer Bestand>opslaan als om het bestand op te slaan alsazuredeploy.json op uw lokale computer.

De sjabloon bewerken

Breng de volgende wijzigingen aan in de sjabloon:

De sjabloon opschonen (optioneel)

De oorspronkelijke sjabloon voegt een geheim toe aan de sleutelkluis. Verwijder de volgende resource om de zelfstudie te vereenvoudigen:

  • Microsoft.KeyVault/vaults/secrets

Verwijder de volgende twee parameterdefinities:

  • secretName
  • secretValue

Als u ervoor kiest deze definities niet te verwijderen, moet u de parameterwaarden opgeven tijdens de implementatie.

Toegangsbeleid voor key vault configureren

Het implementatiescript voegt een certificaat toe aan de sleutelkluis. Configureer het Key Vault-toegangsbeleid om toestemming te geven aan de beheerde identiteit:

  1. Voeg een parameter toe om de id van de beheerde identiteit op te halen:

    "identityId": {
      "type": "string",
      "metadata": {
        "description": "Specifies the ID of the user-assigned managed identity."
      }
    },
    
  2. Voeg een parameter toe voor het configureren van het toegangsbeleid voor de sleutelkluis, zodat de beheerde identiteit certificaten kan toevoegen aan de sleutelkluis:

    "certificatesPermissions": {
      "type": "array",
      "defaultValue": [
        "get",
        "list",
        "update",
        "create"
      ],
      "metadata": {
      "description": "Specifies the permissions to certificates in the vault. Valid values are: all, get, list, update, create, import, delete, recover, backup, restore, manage contacts, manage certificate authorities, get certificate authorities, list certificate authorities, set certificate authorities, delete certificate authorities."
      }
    }
    
  3. Werk het bestaande toegangsbeleid voor de sleutelkluis van de Microsoft.KeyVault/vaults resource bij naar:

    "accessPolicies": [
      {
        "objectId": "[parameters('objectId')]",
        "tenantId": "[parameters('tenantId')]",
        "permissions": {
          "keys": "[parameters('keysPermissions')]",
          "secrets": "[parameters('secretsPermissions')]",
          "certificates": "[parameters('certificatesPermissions')]"
        }
      },
      {
        "objectId": "[reference(parameters('identityId'), '2018-11-30').principalId]",
        "tenantId": "[parameters('tenantId')]",
        "permissions": {
          "keys": "[parameters('keysPermissions')]",
          "secrets": "[parameters('secretsPermissions')]",
          "certificates": "[parameters('certificatesPermissions')]"
        }
      }
    ],
    

    Er zijn twee beleidsregels gedefinieerd, één voor de aangemelde gebruiker en de andere is voor de beheerde identiteit. De aangemelde gebruiker heeft alleen de lijstmachtiging nodig om de implementatie te verifiëren. Ter vereenvoudiging van de zelfstudie wordt hetzelfde certificaat toegewezen aan zowel de beheerde identiteit als de aangemelde gebruikers.

Het implementatiescript toevoegen

  1. Voeg drie parameters toe die worden gebruikt door het implementatiescript:

    "certificateName": {
      "type": "string",
      "defaultValue": "DeploymentScripts2019"
    },
    "subjectName": {
      "type": "string",
      "defaultValue": "CN=contoso.com"
    },
    "utcValue": {
      "type": "string",
      "defaultValue": "[utcNow()]"
    }
    
  2. deploymentScripts Een resource toevoegen:

    Opmerking

    Omdat de inline-implementatiescripts tussen dubbele aanhalingstekens staan, moeten de tekenreeksen in de implementatiescripts tussen enkele aanhalingstekens worden geplaatst. Het Escape-teken van PowerShell is de backtick (`).

    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "createAddCertificate",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
      ],
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "[parameters('identityId')]": {
          }
        }
      },
      "kind": "AzurePowerShell",
      "properties": {
        "forceUpdateTag": "[parameters('utcValue')]",
        "azPowerShellVersion": "3.0",
        "timeout": "PT30M",
        "arguments": "[format(' -vaultName {0} -certificateName {1} -subjectName {2}', parameters('keyVaultName'), parameters('certificateName'), parameters('subjectName'))]", // can pass an argument string, double quotes must be escaped
        "scriptContent": "
          param(
            [string] [Parameter(Mandatory=$true)] $vaultName,
            [string] [Parameter(Mandatory=$true)] $certificateName,
            [string] [Parameter(Mandatory=$true)] $subjectName
          )
    
          $ErrorActionPreference = 'Stop'
          $DeploymentScriptOutputs = @{}
    
          $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName
    
          if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) {
    
            Write-Host 'Certificate $certificateName in vault $vaultName is already present.'
    
            $DeploymentScriptOutputs['certThumbprint'] = $existingCert.Thumbprint
            $existingCert | Out-String
          }
          else {
            $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose
    
            # private key is added as a secret that can be retrieved in the Resource Manager template
            Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose
    
            # it takes a few seconds for KeyVault to finish
            $tries = 0
            do {
              Write-Host 'Waiting for certificate creation completion...'
              Start-Sleep -Seconds 10
              $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName
              $tries++
    
              if ($operation.Status -eq 'failed')
              {
                throw 'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)'
              }
    
              if ($tries -gt 120)
              {
                throw 'Timed out waiting for creation of certificate $certificateName in vault $vaultName'
              }
            } while ($operation.Status -ne 'completed')
    
            $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName
            $DeploymentScriptOutputs['certThumbprint'] = $newCert.Thumbprint
            $newCert | Out-String
          }
        ",
        "cleanupPreference": "OnSuccess",
        "retentionInterval": "P1D"
      }
    }
    

    De deploymentScripts resource is afhankelijk van de sleutelkluisresource en de roltoewijzingsresource. Deze heeft de volgende eigenschappen:

    • identity: Implementatiescript maakt gebruik van een door de gebruiker toegewezen beheerde identiteit om de bewerkingen in het script uit te voeren.
    • kind: Geef het type script op. Momenteel worden alleen PowerShell-scripts ondersteund.
    • forceUpdateTag: Bepaal of het implementatiescript moet worden uitgevoerd, zelfs als de scriptbron niet is gewijzigd. Dit kan de huidige tijdstempel of een GUID zijn. Zie Script meer dan één keer uitvoeren voor meer informatie.
    • azPowerShellVersion: Hiermee geeft u de versie van de Azure PowerShell-module op die moet worden gebruikt. Momenteel ondersteunt het implementatiescript versie 2.7.0, 2.8.0 en 3.0.0.
    • timeout: Geef de maximale toegestane uitvoeringstijd voor scripts op die is opgegeven in de ISO 8601-indeling. De standaardwaarde is P1D.
    • arguments: Geef de parameterwaarden op. De waarden worden gescheiden door spaties.
    • scriptContent: Geef de scriptinhoud op. Als u een extern script wilt uitvoeren, gebruikt u primaryScriptURI in plaats daarvan. Zie Extern script gebruiken voor meer informatie. Declareren $DeploymentScriptOutputs is alleen vereist bij het testen van het script op een lokale computer. Als u de variabele declareren, kan het script worden uitgevoerd op een lokale computer en in een deploymentScript resource zonder dat u wijzigingen hoeft aan te brengen. De waarde waaraan is toegewezen $DeploymentScriptOutputs , is beschikbaar als uitvoer in de implementaties. Zie Werken met uitvoer van PowerShell-implementatiescripts of Werken met uitvoer van CLI-implementatiescripts voor meer informatie.
    • cleanupPreference: Geef de voorkeur op wanneer u de resources van het implementatiescript wilt verwijderen. De standaardwaarde is Altijd, wat betekent dat de resources van het implementatiescript worden verwijderd ondanks de terminalstatus (Geslaagd, Mislukt, Geannuleerd). In deze zelfstudie wordt OnSuccess gebruikt, zodat u de resultaten van de uitvoering van het script kunt bekijken.
    • retentionInterval: Geef het interval op waarvoor de service de scriptbronnen bewaart nadat deze een terminalstatus heeft bereikt. Resources worden verwijderd wanneer deze duur verloopt. De duur is gebaseerd op het ISO 8601-patroon. In deze zelfstudie wordt P1D gebruikt. Dit betekent één dag. Deze eigenschap wordt gebruikt wanneer cleanupPreference is ingesteld op OnExpiration. Deze eigenschap is momenteel niet ingeschakeld.

    Het implementatiescript heeft drie parameters: keyVaultName, certificateNameen subjectName. Er wordt een certificaat gemaakt en vervolgens wordt het certificaat toegevoegd aan de sleutelkluis.

    $DeploymentScriptOutputs wordt gebruikt om uitvoerwaarde op te slaan. Zie Werken met uitvoer van PowerShell-implementatiescripts of Werken met uitvoer van CLI-implementatiescripts voor meer informatie.

    De voltooide sjabloon vindt u hier.

  3. Als u het foutopsporingsproces wilt zien, plaatst u een fout in de code door de volgende regel toe te voegen aan het implementatiescript:

    Write-Output1 $keyVaultName
    

    De juiste opdracht is Write-Output in plaats van Write-Output1.

  4. Selecteer Bestand>opslaan om het bestand op te slaan.

De sjabloon implementeren

  1. Aanmelden bij Azure Cloud Shell

  2. Kies uw voorkeursomgeving door PowerShell of Bash (voor CLI) in de linkerbovenhoek te selecteren. Het opnieuw opstarten van de shell is vereist wanneer u overschakelt.

    Azure Portal Cloud Shell bestand uploaden

  3. Selecteer Bestanden uploaden/downloaden; selecteer vervolgens Uploaden. Zie de vorige schermopname. Selecteer het bestand dat u in de vorige sectie hebt opgeslagen. Nadat u het bestand hebt geüpload, kunt u de ls opdracht en de cat opdracht gebruiken om te controleren of het bestand is geüpload.

  4. Voer het volgende Azure CLI- of Azure PowerShell-script uit om de sjabloon te implementeren.

    echo "Enter a project name that is used to generate resource names:" &&
    read projectName &&
    echo "Enter the location (i.e. centralus):" &&
    read location &&
    echo "Enter your email address used to sign in to Azure:" &&
    read upn &&
    echo "Enter the user-assigned managed identity ID:" &&
    read identityId &&
    adUserId=$((az ad user show --id ${upn}) | jq -r '.id') &&
    resourceGroupName="${projectName}rg" &&
    keyVaultName="${projectName}kv" &&
    az group create --name $resourceGroupName --location $location &&
    az deployment group create --resource-group $resourceGroupName --template-file "$HOME/azuredeploy.json" --parameters identityId=$identityId keyVaultName=$keyVaultName objectId=$adUserId
    

    De implementatiescriptservice moet extra implementatiescriptbronnen maken voor het uitvoeren van scripts. Het kan tot één minuut duren voordat de voorbereiding en het opschonen zijn voltooid, naast de werkelijke uitvoeringstijd van het script.

    De implementatie is mislukt omdat de ongeldige opdracht Write-Output1 wordt gebruikt in het script. U krijgt een foutmelding met de mededeling:

    The term 'Write-Output1' is not recognized as the name of a cmdlet, function, script file, or operable
    program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    

    Het resultaat van het uitvoeren van het implementatiescript wordt opgeslagen in de resources van het implementatiescript voor het oplossen van problemen.

Fouten opsporen in het mislukte script

  1. Meld u aan bij het Azure-portaal.

  2. Open de resourcegroep. Dit is de projectnaam waaraan rg is toegevoegd. U ziet twee extra bronnen in de resourcegroep. Deze resources worden implementatiescriptbronnen genoemd.

    Resources voor scriptimplementatie van Resource Manager-sjablonen

    Beide bestanden hebben het achtervoegsel azscripts . De ene is een opslagaccount en de andere is een containerinstantie.

    Selecteer Verborgen typen weergeven om de deploymentScripts resource weer te geven.

  3. Selecteer het opslagaccount met het achtervoegsel azscripts .

  4. Selecteer de tegel Gedeelde bestanden. U ziet een azscripts-map met de uitvoeringsbestanden van het implementatiescript.

  5. Selecteer azscripts. U ziet twee mappen azscriptinput en azscriptoutput. De invoermap bevat een PowerShell-scriptbestand van het systeem en de scriptbestanden voor gebruikersimplementatie. De uitvoermap bevat een executionresult.json en het scriptuitvoerbestand. U ziet het foutbericht in executionresult.json. Het uitvoerbestand is er niet omdat de uitvoering is mislukt.

Verwijder de Write-Output1 regel en implementeer de sjabloon opnieuw.

Wanneer de tweede implementatie is uitgevoerd, worden de resources van het implementatiescript verwijderd door de scriptservice, omdat de cleanupPreference eigenschap is ingesteld op OnSuccess.

De hulpbronnen opschonen

Wanneer de Azure-resources niet meer nodig zijn, schoont u de resources op die u hebt geïmplementeerd door de resourcegroep te verwijderen.

  1. In de Azure-portal, selecteer de resourcegroep in het menu links.
  2. Voer de naam van de resourcegroep in het veld Filteren op naam in.
  3. Selecteer de naam van de resourcegroep.
  4. Selecteer Resourcegroep verwijderen in het bovenste menu.

Volgende stappen

In deze zelfstudie hebt u geleerd hoe u een implementatiescript gebruikt in ARM-sjablonen. Zie voor meer informatie over het implementeren van Azure-resources op basis van voorwaarden: