Partager via


Tutoriel : Utiliser des scripts de déploiement pour créer un certificat auto-signé

Découvrez comment utiliser des scripts de déploiement dans des modèles Azure Resource Manager (modèles ARM). Les scripts de déploiement permettent d’effectuer des étapes personnalisées impossibles à réaliser avec des modèles ARM. Créer un certificat auto-signé est un exemple. Dans ce tutoriel, vous allez créer un modèle pour déployer un coffre de clés Azure, puis utiliser une ressource Microsoft.Resources/deploymentScripts dans le même modèle pour créer un certificat et enfin ajouter ce certificat au coffre de clés. Pour en savoir plus sur les scripts de déploiement, consultez Utiliser des scripts de déploiement dans des modèles ARM.

Important

Deux ressources de script de déploiement, un compte de stockage et une instance de conteneur, sont créées dans le même groupe de ressources pour l’exécution du script et la résolution de problèmes. Ces ressources sont généralement supprimées par le service de script lorsque l’exécution du script atteint un état terminal. Les ressources vous sont facturées jusqu’à leur suppression. Pour plus d’informations, consultez Nettoyer les ressources de script de déploiement.

Ce tutoriel décrit les tâches suivantes :

  • Ouvrir un modèle de démarrage rapide
  • Modifier le modèle
  • Déployer le modèle
  • Déboguer le script qui a échoué
  • Nettoyer les ressources

Pour lire un module Learn qui aborde les scripts de déploiement, consultez Étendre des modèles ARM à l’aide de scripts de déploiement.

Prérequis

Pour effectuer ce qui est décrit dans cet article, vous avez besoin des éléments suivants :

  • Visual Studio Code avec l’extension Outils Resource Manager. Consultez Démarrage rapide : Créer des modèles ARM avec Visual Studio Code.

  • Identité managée affectée par l’utilisateur. Cette identité est utilisée pour effectuer des actions propres à Azure dans le script. Pour en créer une, consultez Identité managée affectée par l’utilisateur. Vous avez besoin de l’ID d’identité lorsque vous déployez le modèle. Le format de l’identité est le suivant :

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

    Utilisez le script d’interface de ligne de commande suivant pour obtenir l’ID en fournissant le nom du groupe de ressources et le nom de l’identité.

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

Ouvrir un modèle de démarrage rapide

Au lieu de créer un modèle à partir de zéro, ouvrez un modèle à partir de Modèles de démarrage rapide Azure. Le dépôt Modèles de démarrage rapide Azure contient les modèles ARM.

Le modèle utilisé dans ce guide de démarrage rapide est appelé Créer un coffre de clés et un secret Azure. Le modèle crée un coffre de clés, puis y ajoute un secret.

  1. À partir de Visual Studio Code, sélectionnez Fichier>Ouvrir un fichier.

  2. Collez l’URL suivante dans Nom de fichier :

    https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.keyvault/key-vault-create/azuredeploy.json
    
  3. Sélectionnez Ouvrir pour ouvrir le fichier.

  4. Sélectionnez Fichier>Enregistrer sous pour enregistrer le fichier sous le nom azuredeploy.json sur votre ordinateur local.

Modifier le modèle

Apportez les modifications suivantes au modèle :

Nettoyer le modèle (facultatif)

Le modèle d’origine ajoute un secret au coffre de clés. Pour simplifier ce tutoriel, supprimez la ressource suivante :

  • Microsoft.KeyVault/vaults/secrets

Supprimez les deux définitions de paramètre suivantes :

  • secretName
  • secretValue

Si vous choisissez de ne pas supprimer ces définitions, vous devez spécifier les valeurs de paramètre pendant le déploiement.

Configurer la stratégie d’accès au coffre de clés

Le script de déploiement ajoute un certificat au coffre de clés. Configurez les stratégies d’accès au coffre de clés pour accorder l’autorisation à l’identité managée :

  1. Ajoutez un paramètre pour obtenir l’ID de l’identité managée :

    "identityId": {
      "type": "string",
      "metadata": {
        "description": "Specifies the ID of the user-assigned managed identity."
      }
    },
    

    Notes

    L’extension du modèle Resource Manager de Visual Studio Code ne peut pas encore mettre en forme des scripts de déploiement. N’utilisez pas les touches Maj+Alt+F pour mettre en forme les ressources deploymentScripts, comme la suivante.

  2. Ajoutez un paramètre pour configurer les stratégies d’accès au coffre de clés afin que l’identité managée puisse ajouter des certificats à ce coffre de clés :

    "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. Mettez à jour les stratégies d’accès au coffre de clés existantes comme suit :

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

    Deux stratégies sont définies : une pour l’utilisateur connecté et l’autre pour l’identité managée. L’utilisateur connecté n’a besoin que de l’autorisation Liste pour vérifier le déploiement. Pour simplifier ce tutoriel, le même certificat est affecté à l’identité managée et aux utilisateurs connectés.

Ajouter le script de déploiement

  1. Ajoutez trois paramètres utilisés par le script de déploiement :

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

    Notes

    Étant donné que les scripts de déploiement inclus sont placés entre guillemets doubles, les chaînes contenues dans les scripts de déploiement doivent être mises entre guillemets simples. Le caractère d’échappement PowerShell est l’accent grave (`).

    {
      "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"
      }
    }
    

    La ressource deploymentScripts dépend de la ressource du coffre de clés et de la ressource d’attribution de rôle. Ses propriétés sont les suivantes :

    • identity : Le script de déploiement utilise une identité managée affectée par l’utilisateur pour effectuer des opérations dans le script.
    • kind : Spécifiez le type de script. Seuls les scripts PowerShell sont actuellement pris en charge.
    • forceUpdateTag : Déterminez si le script de déploiement doit être exécuté même si la source du script n’a pas changé. Il peut s’agir de l’horodatage actuel ou d’un GUID. Pour plus d’informations, consultez Exécuter un script plusieurs fois.
    • azPowerShellVersion : Spécifie la version du module Azure PowerShell à utiliser. Actuellement, le script de déploiement prend en charge la version 2.7.0, 2.8.0 et 3.0.0.
    • timeout : précise la durée d’exécution maximale autorisée du script, définie au format ISO 8601. La valeur par défaut est P1D.
    • arguments : Spécifiez les valeurs de paramètre. Les valeurs sont séparées par des espaces.
    • scriptContent : Spécifiez le contenu du script. Pour exécuter un script externe, utilisez plutôt primaryScriptURI. Pour plus d’informations, consultez Utiliser un script externe. La déclaration de $DeploymentScriptOutputs est uniquement nécessaire lors du test du script sur une machine locale. La déclaration de la variable permet d’exécuter le script sur une machine locale et dans une ressource deploymentScript sans avoir à apporter de modifications. La valeur affectée à $DeploymentScriptOutputs est disponible en tant que sortie dans les déploiements. Pour plus d’informations, consultez Utiliser les sorties des scripts de déploiement PowerShell ou Utiliser les sorties des scripts de déploiement CLI.
    • cleanupPreference : Spécifiez votre préférence quant à la suppression des ressources de script de déploiement. La valeur par défaut est Toujours, ce qui signifie que les ressources de script de déploiement sont supprimées quel que soit l’état terminal (réussite, échec, annulation). Dans ce tutoriel, OnSuccess est utilisé pour vous permettre de voir les résultats de l’exécution du script.
    • retentionInterval : Spécifiez l’intervalle pendant lequel le service conserve les ressources de script une fois qu’il a atteint un état terminal. Les ressources sont supprimées à l’issue de cet interval. La durée s’appuie sur le modèle ISO 8601. Ce tutoriel utilise P1D, ce qui correspond à une journée. Cette propriété est utilisée quand cleanupPreference a la valeur OnExpiration. Cette propriété n’est pas activée pour le moment.

    Le script de déploiement prend trois paramètres : keyVaultName, certificateName et subjectName. Il crée un certificat, puis l’ajoute au coffre de clés.

    $DeploymentScriptOutputs est utilisé pour stocker la valeur de sortie. Pour en savoir plus, consultez Utiliser les sorties des scripts de déploiement PowerShell ou Utiliser les sorties des scripts de déploiement CLI.

    Le modèle complet est disponible ici.

  3. Pour voir le processus de débogage, placez une erreur dans le code en ajoutant la ligne suivante au script de déploiement :

    Write-Output1 $keyVaultName
    

    La commande correcte est Write-Output plutôt que Write-Output1.

  4. Sélectionnez Fichier>Enregistrer pour enregistrer le fichier.

Déployer le modèle

  1. Se connecter à Azure Cloud Shell

  2. Choisissez votre environnement préféré en sélectionnant PowerShell ou Bash (pour CLI) en haut à gauche. Il est nécessaire de redémarrer l’interpréteur de commandes lors d’un tel changement.

    Azure portal Cloud Shell upload file

  3. Sélectionnez Charger/Télécharger des fichiers, puis Charger. Consultez la capture d’écran précédente. Sélectionnez le fichier que vous avez enregistré dans la section précédente. Après avoir chargé le fichier, vous pouvez utiliser la commande ls et la commande cat pour vérifier que le chargement a été correctement effectué.

  4. Exécutez le script PowerShell ou Azure CLI suivant pour déployer le modèle.

    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
    

    Le service de script de déploiement a besoin de créer des ressources de script de déploiement supplémentaires pour l’exécution du script. La préparation et le processus de nettoyage peuvent prendre jusqu’à une minute, en plus de la durée réelle d’exécution du script.

    Le déploiement a échoué en raison de la commande non valide, Write-Output1, utilisée dans le script. Vous recevez une erreur indiquant :

    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.
    

    Le résultat de l’exécution du script de déploiement est stocké dans les ressources de script de déploiement à des fins de résolution des problèmes.

Déboguer le script qui a échoué

  1. Connectez-vous au portail Azure.

  2. Ouvrez le groupe de ressources. Il s’agit du nom du projet auquel rg est ajouté. Vous devez voir deux ressources supplémentaires dans le groupe de ressources. Ces ressources sont appelées ressources de script de déploiement.

    Resource Manager template deployment script resources

    Les deux fichiers portent le suffixe azscripts. L’un est un compte de stockage et l’autre est une instance de conteneur.

    Sélectionnez Afficher les types masqués pour lister la ressource deploymentScripts.

  3. Sélectionnez le compte de stockage portant le suffixe azscripts.

  4. Sélectionnez la vignette Partages de fichiers. Vous voyez un dossier azscripts qui contient les fichiers d’exécution du script de déploiement.

  5. Sélectionnez azscripts. Vous devez voir deux dossiers : azscriptinput et azscriptoutput. Le dossier input contient un fichier de script PowerShell système et les fichiers de script de déploiement utilisateur. Le dossier output contient un fichier executionresult.json et le fichier de sortie du script. Vous pouvez voir le message d’erreur dans executionresult.json. Le fichier de sortie n’est pas là en raison de l’échec de l’exécution.

Supprimez la ligne Write-Output1 et redéployez le modèle.

Quand la seconde exécution du déploiement réussit, les ressources de script de déploiement doivent être supprimées par le service de script, car la propriété cleanupPreference a la valeur OnSuccess.

Nettoyer les ressources

Lorsque vous n’en avez plus besoin, nettoyez les ressources Azure que vous avez déployées en supprimant le groupe de ressources.

  1. Dans le portail Azure, sélectionnez Groupe de ressources dans le menu de gauche.
  2. Entrez le nom du groupe de ressources dans le champ Filtrer par nom.
  3. Sélectionnez le nom du groupe de ressources.
  4. Sélectionnez Supprimer le groupe de ressources dans le menu supérieur.

Étapes suivantes

Dans ce tutoriel, vous avez appris à utiliser un script de déploiement dans des modèles ARM. Pour savoir comment déployer des ressources Azure en fonction des conditions, consultez :