Condividi tramite


Esercitazione: Usare gli script di distribuzione per creare un certificato autofirmato

Informazioni su come usare gli script di distribuzione nei modelli di Azure Resource Manager (modelli arm). Gli script di distribuzione possono essere usati per eseguire passaggi personalizzati che non possono essere eseguiti dai modelli ARM. Ad esempio, la creazione di un certificato autofirmato. In questa esercitazione, si crea un modello per distribuire un Azure Key Vault e si utilizza una risorsa Microsoft.Resources/deploymentScripts nello stesso modello per creare un certificato e aggiungere il certificato al Key Vault. Per altre informazioni sullo script di distribuzione, vedere Usare gli script di distribuzione nei modelli di ARM templates.

Importante

Due risorse dello script di distribuzione, un account di archiviazione e un'istanza del contenitore, vengono create nello stesso gruppo di risorse per l'esecuzione di script e la risoluzione dei problemi. Queste risorse vengono in genere eliminate dal servizio script quando l'esecuzione dello script diventa in uno stato terminale. Le risorse vengono fatturate fino a quando le risorse non vengono eliminate. Per altre informazioni, vedere Pulire le risorse dello script di distribuzione.

Questa esercitazione illustra le attività seguenti:

  • Aprire un modello di avvio rapido
  • Modificare il modello
  • Implementare il modello
  • Eseguire il debug dello script non riuscito
  • Pulire le risorse

Per un modulo Learn che illustra gli script di distribuzione, vedere Estendere i modelli di ARM utilizzando script di distribuzione.

Prerequisiti

Per completare questo articolo, devi avere quanto segue:

  • Visual Studio Code.

  • Identità gestita assegnata dall'utente. Questa identità viene usata per eseguire azioni specifiche di Azure nello script. Per crearne uno, vedere Identità gestita assegnata dall'utente. È necessario l'ID identità quando si distribuisce il modello. Il formato dell'identità è:

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

    Usare il seguente script CLI per ottenere l'ID specificando il nome del gruppo di risorse e il nome dell'identità.

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

Aprire un modello di avvio rapido

Anziché creare un modello da zero, aprire un modello da Modelli di avvio rapido di Azure. Modelli di avvio rapido di Azure è un repository di modelli di Resource Manager.

Il modello usato in questa guida introduttiva è denominato Crea un Azure Key Vault e un segreto. Il modello crea un'insieme di credenziali delle chiavi e quindi aggiunge un segreto all'insieme di credenziali delle chiavi.

  1. In Visual Studio Code selezionare File>apri file.

  2. In Nome file incollare l'URL seguente:

    https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.keyvault/key-vault-create/azuredeploy.json
    
  3. Selezionare Apri per aprire il file.

  4. Selezionare File>Salva con Nome per salvare il file come azuredeploy.json nel computer locale.

Modificare il modello

Apportare le modifiche seguenti al modello:

Pulire il modello (facoltativo)

Il modello originale aggiunge un segreto al Key Vault. Per semplificare l'esercitazione, rimuovere la risorsa seguente:

  • Microsoft.KeyVault/vaults/secrets

Rimuovere le due definizioni di parametro seguenti:

  • secretName
  • secretValue

Se si sceglie di non rimuovere queste definizioni, è necessario specificare i valori dei parametri durante la distribuzione.

Configurare i criteri di accesso dell'insieme di credenziali delle chiavi

Lo script di distribuzione aggiunge un certificato al Key Vault. Configurare i criteri di accesso dell'insieme di credenziali delle chiavi per concedere l'autorizzazione all'identità gestita:

  1. Aggiungere un parametro per ottenere l'ID identità gestita:

    "identityId": {
      "type": "string",
      "metadata": {
        "description": "Specifies the ID of the user-assigned managed identity."
      }
    },
    
  2. Aggiungere un parametro per la configurazione delle politiche di accesso del Key Vault in modo che l'identità gestita possa aggiungere certificati al Key Vault.

    "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. Aggiornare i criteri di accesso esistenti del servizio Key Vault della risorsa Microsoft.KeyVault/vaults in modo che:

    "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')]"
        }
      }
    ],
    

    Sono definiti due criteri, uno per l'utente connesso e l'altro per l'identità gestita. L'utente connesso necessita solo dell'autorizzazione elenco per verificare la distribuzione. Per semplificare l'esercitazione, lo stesso certificato viene assegnato sia all'identità gestita che agli utenti connessi.

Aggiungere lo script di distribuzione

  1. Aggiungere tre parametri usati dallo script di distribuzione:

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

    Annotazioni

    Poiché gli script di distribuzione inline sono racchiusi tra virgolette doppie, le stringhe all'interno degli script di distribuzione devono invece essere racchiuse tra virgolette singole. Il carattere di escape per PowerShell è l'apice inverso (`).

    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2023-08-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"
      }
    }
    

    La risorsa deploymentScripts dipende dalla risorsa dell'insieme di credenziali delle chiavi e dalla risorsa di assegnazione di ruolo. Ha queste proprietà:

    • identity: lo script di distribuzione usa un'identità gestita assegnata dall'utente per eseguire le operazioni nello script.
    • kind: specificare il tipo di script. Attualmente sono supportati solo gli script di PowerShell.
    • forceUpdateTag: determinare se lo script di distribuzione deve essere eseguito anche se l'origine dello script non è stata modificata. Può essere il timestamp corrente o un GUID. Per altre informazioni, vedere Eseguire più volte lo script.
    • azPowerShellVersion: specifica la versione del modulo di Azure PowerShell da usare. Attualmente, lo script di distribuzione supporta la versione 2.7.0, 2.8.0 e 3.0.0.
    • timeout: specificare il tempo massimo consentito di esecuzione dello script specificato nel formato ISO 8601. Il valore predefinito è P1D.
    • arguments: specificare i valori dei parametri. I valori sono separati da spazi.
    • scriptContent: specificare il contenuto dello script. Per eseguire uno script esterno, usare primaryScriptURI invece . Per altre informazioni, vedere Usare script esterni. La dichiarazione $DeploymentScriptOutputs è necessaria solo quando si testa lo script in un computer locale. La dichiarazione della variabile consente l'esecuzione dello script in un computer locale e in una deploymentScript risorsa senza dover apportare modifiche. Il valore assegnato a $DeploymentScriptOutputs è disponibile come output nelle distribuzioni. Per altre informazioni, vedere Usare gli output degli script di distribuzione di PowerShell o Usare gli output dagli script di distribuzione dell'interfaccia a riga di comando.
    • cleanupPreference: specificare la preferenza su quando eliminare le risorse dello script di distribuzione. Il valore predefinito è Always, ovvero le risorse dello script di distribuzione vengono eliminate nonostante lo stato del terminale (Succeeded, Failed, Canceled). In questa esercitazione viene usato OnSuccess in modo da poter visualizzare i risultati dell'esecuzione dello script.
    • retentionInterval: specificare l'intervallo per il quale il servizio mantiene le risorse dello script dopo che raggiunge lo stato del terminale. Le risorse verranno eliminate alla scadenza di questa durata. La durata è basata sul modello ISO 8601. Questa esercitazione usa P1D, ovvero un giorno. Questa proprietà viene utilizzata quando cleanupPreference è impostata su OnExpiration. Questa proprietà non è attualmente abilitata.

    Lo script di distribuzione accetta tre parametri: keyVaultName, certificateNamee subjectName. Crea un certificato e quindi aggiunge il certificato all'archivio delle chiavi.

    $DeploymentScriptOutputs viene usato per archiviare il valore di output. Per ulteriori informazioni, vedere Usare gli output degli script di distribuzione di PowerShell o Usare gli output degli script di distribuzione dell'interfaccia della riga di comando.

    Il modello completato è disponibile qui.

  3. Per visualizzare il processo di debug, inserire un errore nel codice aggiungendo la riga seguente allo script di distribuzione:

    Write-Output1 $keyVaultName
    

    Il comando corretto è Write-Output invece di Write-Output1.

  4. SelezionareFile Save (>) per salvare il file.

Implementare il modello

  1. Accedi a Azure Cloud Shell

  2. Scegliere l'ambiente preferito selezionando PowerShell o Bash (per l'interfaccia della riga di comando) nell'angolo superiore sinistro. Quando si cambia interfaccia, è necessario riavviare la shell.

    File di caricamento di Cloud Shell nel portale di Azure

  3. Selezionare Carica/Scarica file e quindi Carica. Vedere lo screenshot precedente. Selezionare il file salvato nella sezione precedente. Dopo aver caricato il file, è possibile usare il ls comando e il cat comando per verificare che il file sia stato caricato correttamente.

  4. Esegui il seguente script di Azure CLI o Azure PowerShell per effettuare il deployment del modello.

    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
    

    Il servizio script di distribuzione deve creare risorse di script di distribuzione aggiuntive per l'esecuzione degli script. Il completamento della preparazione e del processo di pulizia può richiedere fino a un minuto oltre al tempo di esecuzione effettivo dello script.

    La distribuzione non è riuscita perché il comando non è valido, Write-Output1 viene usato nello script. Verrà visualizzato un errore che indica:

    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.
    

    Il risultato dell'esecuzione dello script di distribuzione viene archiviato nelle risorse dello script di distribuzione per lo scopo della risoluzione dei problemi.

Eseguire il debug dello script non riuscito

  1. Accedi al portale di Azure.

  2. Aprire il gruppo di risorse. È il nome del progetto con rg aggiunto. Nel gruppo di risorse verranno visualizzate due risorse aggiuntive. Queste risorse sono denominate risorse script di distribuzione.

    Risorse dello script di distribuzione del modello di Resource Manager

    Entrambi i file hanno il suffisso azscripts. Uno è un account di archiviazione e l'altro è un'istanza del contenitore.

    Selezionare Mostra tipi nascosti per elencare la deploymentScripts risorsa.

  3. Selezionare l'account di archiviazione con suffisso azscripts.

  4. Selezionare il riquadro Condivisioni file. Verrà visualizzata una cartella azscripts che contiene i file di esecuzione dello script di distribuzione.

  5. Selezionare azscripts. Verranno visualizzate due cartelle azscriptinput e azscriptoutput. La cartella di input contiene un file di script di PowerShell di sistema e i file di script di distribuzione utente. La cartella di output contiene un executionresult.json e il file di output dello script. È possibile visualizzare il messaggio di errore in executionresult.json. Il file di output non è presente perché l'esecuzione non è riuscita.

Rimuovere la Write-Output1 riga e ridistribuire il modello.

Quando la seconda distribuzione viene eseguita correttamente, le risorse dello script di distribuzione verranno rimosse dal servizio script, perché la cleanupPreference proprietà è impostata su OnSuccess.

Pulire le risorse

Quando le risorse di Azure non sono più necessarie, pulire le risorse distribuite eliminando il gruppo di risorse.

  1. Nel portale di Azure selezionare Gruppo di risorse dal menu a sinistra.
  2. Immettere il nome del gruppo di risorse nel campo Filtra per nome .
  3. Selezionare il nome del gruppo di risorse.
  4. Selezionare Elimina gruppo di risorse dal menu in alto.

Passaggi successivi

Questa esercitazione ha illustrato come usare uno script di distribuzione nei modelli di Azure Resource Manager. Per informazioni su come distribuire le risorse di Azure in base alle condizioni, vedere: