Usare script di distribuzione in Bicep

Usando la risorsa deploymentScripts, è possibile eseguire script nelle distribuzioni Bicep ed esaminare i risultati dell'esecuzione. È possibile usare questi script per eseguire passaggi personalizzati, ad esempio:

  • Aggiungere utenti a una directory.
  • Eseguire operazioni sul piano dati; ad esempio, copiare BLOB o fornire dati di inizializzazione a un database.
  • Cercare e convalidare un codice di licenza.
  • Creare un certificato autofirmato.
  • Creare un oggetto in Microsoft Entra ID.
  • Cercare blocchi di indirizzi IP da un sistema personalizzato.

I vantaggi degli script di distribuzione includono:

  • Sono facili da scrivere con codice, usare ed eseguirne il debug. È possibile sviluppare script di distribuzione negli ambienti di sviluppo preferiti. Gli script possono essere incorporati in file Bicep o in file di script esterni.
  • È possibile specificare la piattaforma e il linguaggio dello script. Attualmente, gli script di distribuzione di Azure PowerShell e dell'interfaccia della riga di comando di Azure nell'ambiente Linux sono supportati.
  • È possibile consentire il passaggio di argomenti della riga di comando allo script.
  • È possibile specificare gli output dello script e passarli di nuovo alla distribuzione.

La risorsa script di distribuzione è disponibile solo nelle aree in cui è Istanze di Azure Container è disponibile. Per altre informazioni, vedere Disponibilità di risorse per Istanze di Azure Container nelle aree di Azure.

Avviso

Il servizio script di distribuzione richiede due risorse aggiuntive per eseguire e risolvere i problemi degli script: un account di archiviazione e un'istanza del contenitore. In genere, il servizio ripulisce queste risorse al termine dello script di distribuzione. Vengono addebitati costi per queste risorse fino a quando non vengono rimosse.

Per informazioni sui prezzi, vedere Prezzi di Istanze di Container e Prezzi di Archiviazione di Azure. Per altre informazioni, vedere Pulire le risorse dello script di distribuzione.

Risorse di formazione

Se si preferisce ottenere materiale sussidiario dettagliato sugli script di distribuzione, vedere Estendere modelli Bicep e ARM usando script di distribuzione.

Configurare le autorizzazioni minime

Per la versione 2020-10-01 o successive dell'API dello script di distribuzione, due entità di sicurezza sono coinvolte nell'esecuzione dello script di distribuzione:

  • Entità di sicurezza di distribuzione: questa entità viene usata per distribuire il file Bicep. Essa crea le risorse sottostanti necessarie per l'esecuzione della risorsa script di distribuzione, ovvero un account di archiviazione e un'istanza del contenitore di Azure. Per configurare le autorizzazioni con privilegi minimi, assegnare un ruolo personalizzato con le proprietà seguenti all'entità di distribuzione:

    {
      "roleName": "deployment-script-minimum-privilege-for-deployment-principal",
      "description": "Configure least privilege for the deployment principal in deployment script",
      "type": "customRole",
      "IsCustom": true,
      "permissions": [
        {
          "actions": [
            "Microsoft.Storage/storageAccounts/*",
            "Microsoft.ContainerInstance/containerGroups/*",
            "Microsoft.Resources/deployments/*",
            "Microsoft.Resources/deploymentScripts/*"
          ],
        }
      ],
      "assignableScopes": [
        "[subscription().id]"
      ]
    }
    

    Se i provider di risorse di Archiviazione di Azure e Istanze di Azure Container non sono stati registrati, assicurarsi di aggiungere Microsoft.Storage/register/action e Microsoft.ContainerInstance/register/action.

  • Entità di sicurezza script di distribuzione: questa entità è necessaria solo se lo script di distribuzione deve eseguire l'autenticazione in Azure e chiamare l'interfaccia della riga di comando di Azure o PowerShell. Esistono due modi per specificare l'entità di sicurezza script di distribuzione:

    • Specificare un'identità gestita assegnata dall'utente nella proprietà identity. (Vedere la sintassi delle risorse dello script di distribuzione.) Quando si specifica un'identità gestita assegnata dall'utente, il servizio script chiama Connect-AzAccount -Identity prima di richiamare lo script di distribuzione. L'identità gestita deve avere l'accesso necessario per completare l'operazione nello script. Attualmente, è supportata solo un'identità gestita assegnata dall'utente per la proprietà identity. Per accedere con un'identità diversa, usare il secondo metodo qui elencato.
    • Passare le credenziali dell'entità di sicurezza del servizio come variabili di ambiente sicure e quindi chiamare Connect-AzAccount o az login nello script di distribuzione.

    Se si usa un'identità gestita, l'entità di distribuzione richiede che il ruolo Operatore identità gestita predefinito sia assegnato alla risorsa di identità gestita.

Attualmente, nessun ruolo predefinito è personalizzato per la configurazione delle autorizzazioni di script di distribuzione.

Creare script di distribuzione

L'esempio seguente illustra un semplice file Bicep con una risorsa script di distribuzione. Lo script accetta un parametro stringa e crea un'altra stringa.

param name string = 'John Dole'
param location string = resourceGroup().location

resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: 'inlineCLI'
  location: location
  kind: 'AzureCLI'
  properties: {
    azCliVersion: '2.52.0'
    arguments: name
    scriptContent: 'echo "The argument is ${name}."; jq -n -c --arg st "Hello ${name}" \'{"text": $st}\' > $AZ_SCRIPTS_OUTPUT_PATH'
    retentionInterval: 'PT1H'
  }
}

output text string = deploymentScript.properties.outputs.text

Per altre informazioni sulla creazione di risorse script di distribuzione, vedere Creare script di distribuzione. Per la creazione di script per la risorsa script di distribuzione, è consigliabile stabilire un ambiente di sviluppo di script dedicato, ad esempio un'istanza del contenitore di Azure o un'immagine Docker. Dopo aver sviluppato e testato accuratamente gli script, è possibile integrare o richiamare i file di script dalla risorsa script di distribuzione. Per altre informazioni, vedere Configurare ambienti di sviluppo di script.

Salvare lo script in un file inlineScript.bicep e quindi distribuire la risorsa usando lo script seguente:

$resourceGroupName = Read-Host -Prompt "Enter the name of the resource group to be created"
$location = Read-Host -Prompt "Enter the location (i.e. centralus)"

New-AzResourceGroup -Name $resourceGroupName -Location $location

New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile "inlineScript.bicep"

Write-Host "Press [ENTER] to continue ..."

Usare l'identità gestita

L'esempio seguente illustra come usare l'identità gestita per interagire con Azure dall'interno dello script di distribuzione.

@description('The location of the resources.')
param location string = resourceGroup().location

@description('The storage account to list blobs from.')
param storageAccountData {
  name: string
  container: string
}

@description('The role id of Storage Blob Data Reader.')
var storageBlobDataReaderRoleId = '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1'

@description('The storage account to read blobs from.')
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' existing = {
  name: storageAccountData.name
}

@description('The Storage Blob Data Reader Role definition from [Built In Roles](https://video2.skills-academy.com/en-us/azure/role-based-access-control/built-in-roles).')
resource storageBlobDataReaderRoleDef 'Microsoft.Authorization/roleDefinitions@2022-05-01-preview' existing = {
  scope: subscription()
  name: storageBlobDataReaderRoleId
}

@description('The user identity for the deployment script.')
resource scriptIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-07-31-preview' = {
  name: 'script-identity'
  location: location
}

@description('Assign permission for the deployment scripts user identity access to the read blobs from the storage account.')
resource dataReaderRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  scope: storageAccount
  name: guid(storageBlobDataReaderRoleDef.id, scriptIdentity.id, storageAccount.id)
  properties: {
    principalType: 'ServicePrincipal'
    principalId: scriptIdentity.properties.principalId
    roleDefinitionId: storageBlobDataReaderRoleDef.id
  }
}

@description('The deployment script.')
resource script 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: 'script'
  location: location
  kind: 'AzureCLI'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${scriptIdentity.id}': {}
    }
  }
  properties: {
    azCliVersion: '2.59.0'
    retentionInterval: 'PT1H'
    arguments: '${storageAccount.properties.primaryEndpoints.blob} ${storageAccountData.container}'
    scriptContent: '''
      #!/bin/bash
      set -e
      az storage blob list --auth-mode login --blob-endpoint $1 --container-name $2
    '''
  }
}

Monitorare e risolvere i problemi di uno script di distribuzione

Quando si distribuisce una risorsa script di distribuzione, è necessario un account di archiviazione per archiviare lo script utente, i risultati dell'esecuzione e il file stdout. È possibile specificare il proprio account di archiviazione. Per altre informazioni, vedere Usare un account di archiviazione esistente.

Un'alternativa a specificare il proprio account di archiviazione prevede l'impostazione di cleanupPreference su OnExpiration. È quindi possibile configurare retentionInterval per una durata che consenta tempo sufficiente per esaminare gli output prima che l'account di archiviazione venga rimosso. Per altre informazioni, vedere Ripulire risorse dello script di distribuzione.

Aggiungere la proprietà cleanupPreference al file Bicep precedente e impostare il valore su OnExpiration. Il valore predefinito è Always. Inoltre, impostare rentalInterval su PT1H (un'ora) o su un tempo più breve.

param name string = 'John Dole'
param location string = resourceGroup().location

resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: 'inlineCLI'
  location: location
  kind: 'AzureCLI'
  properties: {
    azCliVersion: '2.52.0'
    arguments: name
    scriptContent: 'echo "The argument is ${name}."; jq -n -c --arg st "Hello ${name}" \'{"text": $st}\' > $AZ_SCRIPTS_OUTPUT_PATH'
    cleanupPreference: 'OnExpiration'
    retentionInterval: 'PT1H'
  }
}

output text string = deploymentScript.properties.outputs.text

Dopo aver distribuito correttamente il file Bicep, usare il portale di Azure, l'interfaccia della riga di comando di Azure, Azure PowerShell o l'API REST per controllare i risultati.

Azure portal

Dopo aver distribuito una risorsa script di distribuzione, essa viene elencata nel gruppo di risorse nel portale di Azure. La pagina Panoramica elenca le due risorse di supporto oltre alla risorsa script di distribuzione. Le risorse di supporto verranno eliminate dopo la scadenza dell'intervallo di conservazione.

Notare che entrambe le risorse di supporto contengono il suffisso azscripts nei loro nomi, poiché create automaticamente. L'altro metodo per identificare le risorse di supporto consiste nell'usare tag.

Screenshot di un gruppo di risorse dello script di distribuzione.

Selezionare la risorsa script di distribuzione dall'elenco. La pagina Panoramica di una risorsa script di distribuzione mostra informazioni importanti sulla risorsa, ad esempio lo Stato di provisioning e le due risorse di supporto (Account di archiviazione e Istanza del contenitore). L'area Log mostra il testo di stampa dello script.

Screenshot delle informazioni su una risorsa dello script di distribuzione.

Selezionare Output per visualizzare gli output dello script.

Screenshot degli output dello script di distribuzione.

Tornare al gruppo di risorse, selezionare l'account di archiviazione, quindi Condivisioni file, e quindi selezionare la condivisione file con il suffisso azscripts aggiunto al nome condivisione. Nell'elenco vengono visualizzate due cartelle: azscriptinput e azscriptoutput. La cartella di output contiene un file di executionresult.json e il file di output dello script. Il file executionresult.json contiene il messaggio di errore di esecuzione dello script. Il file di output viene creato solo quando lo script viene eseguito correttamente.

Screenshot del contenuto della cartella di output di uno script di distribuzione.

La cartella di input contiene il file di script di sistema e il file di script di distribuzione dell’utente. È possibile sostituire il file di script di distribuzione dell'utente con uno modificato ed eseguire nuovamente lo script di distribuzione dall'istanza di contenitore di Azure.

Interfaccia della riga di comando di Azure

È possibile usare l'interfaccia della riga di comando di Azure per gestire gli script di distribuzione nell'ambito della sottoscrizione o del gruppo di risorse:

L'output del comando list è simile a questo esempio:

{
  "arguments": "John Dole",
  "azCliVersion": "2.52.0",
  "cleanupPreference": "OnExpiration",
  "containerSettings": {
    "containerGroupName": null
  },
  "environmentVariables": null,
  "forceUpdateTag": null,
  "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.Resources/deploymentScripts/inlineCLI",
  "identity": null,
  "kind": "AzureCLI",
  "location": "centralus",
  "name": "inlineCLI",
  "outputs": {
    "text": "Hello John Dole"
  },
  "primaryScriptUri": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "dsDemo",
  "retentionInterval": "1:00:00",
  "scriptContent": "echo \"The argument is John Dole.\"; jq -n -c --arg st \"Hello John Dole\" '{\"text\": $st}' > $AZ_SCRIPTS_OUTPUT_PATH",
  "status": {
    "containerInstanceId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.ContainerInstance/containerGroups/jgczqtxom5oreazscripts",
    "endTime": "2023-12-11T20:20:12.149468+00:00",
    "error": null,
    "expirationTime": "2023-12-11T21:20:12.149468+00:00",
    "startTime": "2023-12-11T20:18:26.674492+00:00",
    "storageAccountId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.Storage/storageAccounts/jgczqtxom5oreazscripts"
  },
  "storageAccountSettings": null,
  "supportingScriptUris": null,
  "systemData": {
    "createdAt": "2023-12-11T19:45:32.239063+00:00",
    "createdBy": "johndole@contoso.com",
    "createdByType": "User",
    "lastModifiedAt": "2023-12-11T20:18:26.183565+00:00",
    "lastModifiedBy": "johndole@contoso.com",
    "lastModifiedByType": "User"
  },
  "tags": null,
  "timeout": "1 day, 0:00:00",
  "type": "Microsoft.Resources/deploymentScripts"
}

Azure PowerShell

È possibile usare Azure PowerShell per gestire gli script di distribuzione nell'ambito della sottoscrizione o del gruppo di risorse:

L'output Get-AzDeploymentScript è simile all’esempio seguente:

Name                : inlinePS
Id                  : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.Resources/deploymentScripts/inlinePS
ResourceGroupName   : dsDemo
Location            : centralus
SubscriptionId      : aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e
ProvisioningState   : Succeeded
Identity            :
ScriptKind          : AzurePowerShell
AzPowerShellVersion : 10.0
StartTime           : 12/11/2023 9:45:50 PM
EndTime             : 12/11/2023 9:46:59 PM
ExpirationDate      : 12/11/2023 10:46:59 PM
CleanupPreference   : OnExpiration
StorageAccountId    : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.Storage/storageAccounts/ee5o4rmoo6ilmazscripts
ContainerInstanceId : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.ContainerInstance/containerGroups/ee5o4rmoo6ilmazscripts
Outputs             :
                      Key                 Value
                      ==================  ==================
                      text                Hello John Dole.

RetentionInterval   : PT1H
Timeout             : P1D

REST API

È possibile usare l'API REST per ottenere informazioni sulla risorsa script di distribuzione a livello di gruppo di risorse e a livello di sottoscrizione:

/subscriptions/<SubscriptionID>/resourcegroups/<ResourceGroupName>/providers/microsoft.resources/deploymentScripts/<DeploymentScriptResourceName>?api-version=2020-10-01
/subscriptions/<SubscriptionID>/providers/microsoft.resources/deploymentScripts?api-version=2020-10-01

L'esempio seguente usa ARMClient. ARMClient non è uno strumento Microsoft supportato.

armclient login
armclient get /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/myrg/providers/microsoft.resources/deploymentScripts/myDeployementScript?api-version=2020-10-01

L'output è simile all'esempio seguente:

{
  "kind": "AzureCLI",
  "identity": null,
  "location": "centralus",
  "systemData": {
    "createdAt": "2023-12-11T19:45:32.239063+00:00",
    "createdBy": "johndole@contoso.com",
    "createdByType": "User",
    "lastModifiedAt": "2023-12-11T20:18:26.183565+00:00",
    "lastModifiedBy": "johndole@contoso.com",
    "lastModifiedByType": "User"
  },
  "properties": {
    "provisioningState": "Succeeded",
    "azCliVersion": "2.52.0",
    "scriptContent": "echo \"The argument is John Dole.\"; jq -n -c --arg st \"Hello John Dole\" '{\"text\": $st}' > $AZ_SCRIPTS_OUTPUT_PATH",
    "arguments": "John Dole",
    "retentionInterval": "1:00:00",
    "timeout": "1 day, 0:00:00",
    "containerSettings": {
      "containerGroupName": null
    },
    "status": {
      "containerInstanceId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.ContainerInstance/containerGroups/jgczqtxom5oreazscripts",
      "endTime": "2023-12-11T20:20:12.149468+00:00",
      "error": null,
      "expirationTime": "2023-12-11T21:20:12.149468+00:00",
      "startTime": "2023-12-11T20:18:26.674492+00:00",
      "storageAccountId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.Storage/storageAccounts/jgczqtxom5oreazscripts"
    },
    "outputs": {
      "text": "Hello John Dole"
    },
    "cleanupPreference": "OnSuccess"
  },
  "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/dsDemo/providers/Microsoft.Resources/deploymentScripts/inlineCLI",
  "type": "Microsoft.Resources/deploymentScripts",
  "name": "inlineCLI",
}

L'API REST seguente restituisce il log:

/subscriptions/<SubscriptionID>/resourcegroups/<ResourceGroupName>/providers/microsoft.resources/deploymentScripts/<DeploymentScriptResourceName>/logs?api-version=2020-10-01

Funziona solo prima che vengano eliminate le risorse dello script di distribuzione.


Codici di errore dello script di distribuzione

Nella tabella seguente sono elencati i codici di errore per lo script di distribuzione:

Codice di errore Descrizione
DeploymentScriptInvalidOperation La definizione della risorsa script di distribuzione nel file Bicep contiene nomi di proprietà non validi.
DeploymentScriptResourceConflict Non è possibile eliminare una risorsa script di distribuzione se si trova in uno stato non deterministico e l'esecuzione non ha superato una durata di un'ora. In alternativa, non è possibile rieseguire lo stesso script di distribuzione con lo stesso identificatore di risorsa (stessa sottoscrizione, nome del gruppo di risorse e nome della risorsa) ma con contenuto del corpo dello script diverso.
DeploymentScriptOperationFailed L'operazione script di distribuzione è fallita internamente. Contattare il supporto tecnico Microsoft.
DeploymentScriptStorageAccountAccessKeyNotSpecified La chiave di accesso non è stata specificata per l'account di archiviazione esistente.
DeploymentScriptContainerGroupContainsInvalidContainers Un gruppo di contenitori creato dal servizio script di distribuzione è stato modificato esternamente e sono stati aggiunti contenitori non validi.
DeploymentScriptContainerGroupInNonterminalState Due o più risorse dello script di distribuzione usano lo stesso nome di istanza del contenitore di Azure nello stesso gruppo di risorse e una di esse non ha ancora completato l'esecuzione.
DeploymentScriptExistingStorageNotInSameSubscriptionAsDeploymentScript L'archiviazione esistente fornita nella distribuzione non viene trovata nella sottoscrizione in cui viene distribuito lo script.
DeploymentScriptStorageAccountInvalidKind L'account di archiviazione esistente del tipo BlobBlobStorage o BlobStorage non supporta le condivisioni file e non può essere usato.
DeploymentScriptStorageAccountInvalidKindAndSku L'account di archiviazione esistente non supporta le condivisioni file. Per un elenco dei tipi di account di archiviazione supportati, vedere Usare un account di archiviazione esistente.
DeploymentScriptStorageAccountNotFound L'account di archiviazione non è esistente o è stato eliminato da un processo o uno strumento esterno.
DeploymentScriptStorageAccountWithServiceEndpointEnabled L'account di archiviazione specificato ha un endpoint di servizio. Un account di archiviazione con un endpoint di servizio non è supportato.
DeploymentScriptStorageAccountInvalidAccessKey È stata specificata una chiave di accesso non valida per l'account di archiviazione esistente.
DeploymentScriptStorageAccountInvalidAccessKeyFormat La chiave dell'account di archiviazione ha un formato non valido. Vedere Gestire le chiavi di accesso dell'account di archiviazione.
DeploymentScriptExceededMaxAllowedTime Il tempo di esecuzione dello script di distribuzione ha superato il valore di tempo massimo specificato nella definizione della risorsa dello script di distribuzione.
DeploymentScriptInvalidOutputs L'output dello script di distribuzione non è un oggetto JSON valido.
DeploymentScriptContainerInstancesServiceLoginFailure L'identità gestita assegnata dall'utente non è riuscita ad accedere dopo 10 tentativi a intervalli di un minuto.
DeploymentScriptContainerGroupNotFound Uno strumento o processo esterno ha eliminato un gruppo di contenitori creato dal servizio script di distribuzione.
DeploymentScriptDownloadFailure Download di uno script di supporto non riuscito. Vedere Usare script di supporto.
DeploymentScriptError Lo script utente ha generato un errore.
DeploymentScriptBootstrapScriptExecutionFailed Lo script bootstrap ha generato un errore. Lo script bootstrap è lo script di sistema che coordina l'esecuzione dello script di distribuzione.
DeploymentScriptExecutionFailed Si è verificato un errore sconosciuto durante l'esecuzione dello script di distribuzione.
DeploymentScriptContainerInstancesServiceUnavailable Durante la creazione di un'istanza del contenitore, il servizio Istanze di Azure Container ha generato un errore "servizio non disponibile".
DeploymentScriptContainerGroupInNonterminalState Durante la creazione di un'istanza del contenitore, un altro script di distribuzione stava usando lo stesso nome di istanza del contenitore nello stesso ambito (stessa sottoscrizione, nome del gruppo di risorse e nome della risorsa).
DeploymentScriptContainerGroupNameInvalid Il nome di istanza del contenitore specificato non soddisfa i requisiti di Istanze di Azure Container. Vedere Risolvere i problemi comuni in Istanze di Azure Container.

Accedere a una rete virtuale privata

Con alcune configurazioni aggiuntive, è possibile eseguire script di distribuzione in reti private. Per altre informazioni, vedere Accedere a una rete virtuale privata usando l'endpoint di servizio o Eseguire lo script di distribuzione Bicep privatamente su un endpoint privato.

Passaggi successivi

In questo articolo si è appreso come usare gli script di distribuzione. Per altre informazioni, vedere: