En quoi consiste les scripts de déploiement ?

Effectué

Dans cette unité, vous découvrez comment la ressource deploymentScripts peut étendre les modèles Azure Resource Manager (ARM).

Les modèles ARM sont des outils merveilleux. Vous pouvez les utiliser pour déclarer l’état souhaité de votre infrastructure cloud, et laisser les API et les services trouver la façon de le faire. Toutefois, vous devez parfois effectuer des actions en dehors de la sphère d’Azure Resource Manager.

En quoi consiste les scripts de déploiement ?

Les ressources deploymentScripts sont des scripts PowerShell ou Bash qui s’exécutent dans un conteneur Docker dans le cadre du déploiement de votre modèle. Les images conteneur par défaut proposent aussi bien Azure CLI qu’Azure PowerShell. Ces scripts s’exécutent pendant le traitement du modèle ARM, ce qui vous permet d’ajouter un comportement personnalisé au processus de déploiement.

Les scripts de déploiement utilisent une identité managée pour s’authentifier sur Azure. Une identité managée est un principal de service dont les informations d’identification et le cycle de vie sont gérés par la plateforme Azure. Cette identité est utilisée par les commandes Azure PowerShell ou Azure CLI pour agir sur l’environnement. Comme vous attribuez l’identité, vous contrôlez l’étendue affectée par la ressource deploymentScripts.

La ressource deploymentScripts produit une sortie que les autres ressources du déploiement peuvent utiliser. Vous pouvez ensuite rechercher des informations à partir d’un système externe ou fournir des données en fonction de l’état actuel de votre environnement pour affecter le reste du déploiement.

Comment fonctionnent les scripts de déploiement

Une ressource deploymentScripts prend un script fourni par l’utilisateur (à partir du modèle ou d’un URI) et éventuellement des scripts complémentaires, puis les exécute dans une instance de conteneur Azure. L’instance de conteneur reçoit l’identité managée que vous fournissez. Les scripts et leur sortie sont stockés dans un partage de fichiers pour un compte de stockage Azure.

Quand le déploiement de modèle s’exécute, il vérifie s’il existe une ressource deploymentScripts dans le groupe de ressources ciblé. Si c’est le cas, il compare les propriétés. Si tout correspond, rien de nouveau ne se produit. Si la ressource n’existe pas ou a été changée, Azure Resource Manager crée une instance de conteneur et y exécute les scripts de déploiement. Toutes les sorties définies sont renvoyées à Azure Resource Manager pour une utilisation ultérieure dans le déploiement.

Structure du script de déploiement

Pour ajouter un comportement personnalisé à un modèle ARM, vous commencez par la ressource deploymentScripts. Au minimum, vous devez fournir des détails courants comme :

  • Un name pour la ressource deploymentScripts.
  • Les valeurs type et apiVersion.
  • L’emplacement (valeur location) où créer les ressources complémentaires.
  • Objet properties vide. Vous y viendrez bientôt.

Deux valeurs propres à deploymentScripts sont nécessaires :

  • kind : le type de script à exécuter (AzurePowerShell ou AzureCLI).

    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "myFirstDeploymentScript",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid": {}
        }
      }
    }
    
    resource myFirstDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
      name: 'myFirstDeploymentScript'
      location: resourceGroup().location
      kind: 'AzurePowerShell'
      identity: {
        type: 'UserAssigned'
        userAssignedIdentities: {
          '/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
        }
      }
    }
    
  • identity : l’identité managée que l’instance de conteneur doit utiliser. Vous pouvez créer l’identité managée à l’avance et la spécifier comme dans l’exemple suivant. Vous pouvez également la créer dans le modèle et la référencer (ce que vous allez faire dans l’exercice suivant).

    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "myFirstDeploymentScript",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid": {}
        }
      }
    }
    
    resource myFirstDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
      name: 'myFirstDeploymentScript'
      location: resourceGroup().location
      kind: 'AzurePowerShell'
      identity: {
        type: 'UserAssigned'
        userAssignedIdentities: {
          '/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
        }
      }
    }
    

Une fois que vous avez défini ces éléments, vous pouvez passer à la section properties de la ressource deploymentScripts. La partie principale de cette section est le scriptContent, qui spécifie le script réel à exécuter :

"properties": {
  "scriptContent": "
      $output = 'Hello Learner!'
      Write-Output $output
      $DeploymentScriptOutputs = @{}
      $DeploymentScriptOutputs['text'] = $output
  ",
}
properties: {
  scriptContent: '''
    $output = 'Hello Learner!'
    Write-Output $output
    $DeploymentScriptOutputs = @{}
    $DeploymentScriptOutputs['text'] = $output
  '''
}

Notez que scriptContent utilise une chaîne multiligne. Dans Bicep, vous pouvez spécifier une chaîne multiligne en utilisant trois guillemets (''') avant et après votre chaîne.

Les scripts de déploiement renvoient souvent les sorties au déploiement. Par exemple, si vous utilisez un script pour rechercher des informations à partir d’une API, vous pouvez renvoyer les informations au déploiement sous forme de sortie. D’autres ressources dans le déploiement peuvent ensuite utiliser les informations dans leurs propres définitions.

Pour un script PowerShell, vous renvoyez les sorties en créant une variable nommée $DeploymentScriptOutputs, qui doit être une table de hachage. L’exemple de script initialise la table de hachage, puis crée une sortie appelée text, qui prend sa valeur dans la variable locale $output :

$output = 'Hello Learner!'
Write-Output $output
$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['text'] = $output
$output = 'Hello Learner!'
Write-Output $output
$DeploymentScriptOutputs = @{}
$DeploymentScriptOutputs['text'] = $output

Conseil

Vous pouvez également écrire des scripts de déploiement dans Bash. Pour créer des sorties à partir d’un script Bash, vous devez créer un fichier JSON dans un emplacement spécifié par la variable d’environnement AZ_SCRIPTS_OUTPUT_PATH.

Dans la section properties, vous définissez également les différentes options que peut prendre deploymentScripts. Dans ce module, pour simplifier, nous ajoutons juste ce qu’il faut pour que le script s’exécute. Au minimum, vous devez fournir la version d’Azure PowerShell ou l’Azure CLI à utiliser, un script à exécuter et un intervalle de conservation.

L’intervalle de conservation est la durée pendant laquelle les résultats doivent être conservés si vous voulez garder les ressources. Par défaut, les résultats sont supprimés après l’exécution du script.

"properties": {
  "azPowerShellVersion": "3.0",
  "scriptContent": "
      $output = 'Hello Learner!'
      Write-Output $output
      $DeploymentScriptOutputs = @{}
      $DeploymentScriptOutputs['text'] = $output
  ",
  "retentionInterval": "P1D"
}
properties: {
  azPowerShellVersion: '3.0'
  scriptContent: '''
    $output = 'Hello Learner!'
    Write-Output $output
    $DeploymentScriptOutputs = @{}
    $DeploymentScriptOutputs['text'] = $output
  '''
  retentionInterval: 'P1D'
}

Notre modèle complet ressemble alors à ceci :

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.1",
  "apiProfile": "",
  "parameters": {},
  "variables": {},
  "functions": [],
  "resources": [
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "myFirstDeploymentScript",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid": {}
        }
      },
      "properties": {
        "azPowerShellVersion": "3.0",
        "scriptContent": "
            $output = 'Hello Learner!'
            Write-Output $output
            $DeploymentScriptOutputs = @{}
            $DeploymentScriptOutputs['text'] = $output
        ",
        "retentionInterval": "P1D"
      }
    }
  ],
  "outputs": {
    "scriptResult": {
      "type": "string",
      "value": "[reference('myFirstDeploymentScript').outputs.text]"
    }
  }
}
resource myFirstDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
  name: 'myFirstDeploymentScript'
  location: resourceGroup().location
  kind: 'AzurePowerShell'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/deploymenttest/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myscriptingid': {}
    }
  }
  properties: {
    azPowerShellVersion: '3.0'
    scriptContent: '''
      $output = 'Hello Learner!'
      Write-Output $output
      $DeploymentScriptOutputs = @{}
      $DeploymentScriptOutputs['text'] = $output
    '''
    retentionInterval: 'P1D'
  }
}

output scriptResult string = myFirstDeploymentScript.properties.outputs.text

Ajouter des fichiers de script

L’incorporation de scripts inline dans les modèles peut être fastidieuse, difficile à lire et à comprendre, et difficile à changer. Bicep utilise la fonction loadTextContent() pour incorporer un fichier texte externe dans votre déploiement. Quand Bicep compile votre modèle en JSON, il incorpore le fichier externe dans le modèle qu’il émet.

Supposons que vous avez un fichier PowerShell nommé myscript.ps1 dans le même dossier que votre modèle Bicep. Vous pouvez indiquer à Bicep d’incorporer le fichier de la façon suivante :

properties: {
  azPowerShellVersion: '3.0'
  scriptContent: loadTextContent('myscript.ps1')
  retentionInterval: 'P1D'
}

Toutes les propriétés de la ressource deploymentScripts se trouvent dans la documentation de référence des modèles ARM.