Compartir a través de


Uso de scripts de implementación en Bicep

Mediante el uso del recurso deploymentScripts, puede ejecutar scripts en implementaciones de Bicep y revisar los resultados de la ejecución. Puede usar estos scripts para realizar pasos personalizados, por ejemplo:

  • Adición de usuarios a un directorio.
  • Realizar operaciones de plano de datos como, por ejemplo, copiar blobs o inicializar una base de datos.
  • Búsqueda y validación de una clave de licencia.
  • Cree un certificado autofirmado.
  • Cree un objeto en Microsoft Entra ID.
  • Buscar bloques de direcciones IP desde un sistema personalizado.

Entre las ventajas de los scripts de implementación se incluye lo siguiente:

  • Son fáciles de programar, usar y depurar. Puede desarrollar scripts de implementación en sus entornos de desarrollo favoritos. Los scripts se pueden insertar en archivos de Bicep o en archivos de script externos.
  • Puede especificar el lenguaje y la plataforma del script. Actualmente, se admiten scripts de implementación de Azure PowerShell y la CLI de Azure en el entorno de Linux.
  • Puede permitir el paso de argumentos de la línea de comandos al script.
  • Puede especificar salidas de script y pasarlas de nuevo a la implementación.

El recurso de script de implementación solo está disponible en las regiones donde Azure Container Instances está disponible. Para obtener más información, vea Disponibilidad de recursos para Azure Container Instances en las regiones de Azure.

Advertencia

El servicio de script de implementación requiere dos recursos adicionales para ejecutar y solucionar problemas de scripts: una cuenta de almacenamiento y una instancia de contenedor. Por lo general, el servicio limpia estos recursos cuando finaliza el script de implementación. Incurrirá en cargos por estos recursos hasta que se quiten.

Para obtener información sobre los precios, consulte los precios de Container Instances y los precios de Azure Storage. Para obtener más información, vea el artículo sobre limpieza de los recursos del script de implementación.

Recursos de aprendizaje

Si prefiere obtener información sobre los scripts de implementación a través de una guía paso a paso, consulte Extensión de las plantillas de Bicep y ARM mediante scripts de implementación.

Configuración de los permisos mínimos

En el caso de la API de script de implementación versión 2020-10-01 o posterior, hay dos entidades de seguridad implicadas en la ejecución del script de implementación:

  • Entidad de seguridad de implementación: esta entidad de seguridad se usa para implementar el archivo de Bicep. Crea recursos subyacentes necesarios para que el recurso de script de implementación se ejecute: una cuenta de almacenamiento y una instancia de contenedor de Azure. Para configurar los permisos con menos privilegios, asigne un rol personalizado con las siguientes propiedades a la entidad de seguridad de implementación:

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

    En caso de que los proveedores de recursos de Azure Storage y Azure Container Instances no se hayan registrado, asegúrese de agregar Microsoft.Storage/register/action y Microsoft.ContainerInstance/register/action.

  • Entidad de seguridad de implementación: esta entidad de seguridad solo es necesaria si el script de implementación tiene que autenticarse en Azure y llamar a la CLI de Azure o PowerShell. Hay dos maneras de especificar la entidad de seguridad del script de implementación:

    • Especifique una identidad administrada asignada por el usuario en la propiedad identity. (Consulte la sintaxis del recurso de script de implementación). Al especificar una identidad administrada asignada por el usuario, el servicio de script llama a Connect-AzAccount -Identity antes de invocar el script de implementación. La identidad administrada debe tener el acceso necesario para completar la operación del script. Actualmente, solo se admiten identidades asignadas por el usuario para la propiedad identity. Para iniciar sesión con una identidad diferente, use el segundo método de esta lista.
    • Pase las credenciales de la entidad de servicio como variables de entorno seguras y, a continuación, llame a Connect-AzAccount o az login en el script de implementación.

    Si usa una identidad administrada, la entidad de seguridad de implementación necesita que el rol de Operador de identidades administradas integrado esté asignado al recurso de identidad administrada.

Actualmente, no hay un rol integrado adaptado para configurar permisos de script de implementación.

Creación de scripts de implementación

El siguiente ejemplo muestra un archivo de Bicep sencillo con un recurso de script de implementación. El script toma un parámetro de cadena y crea otra cadena.

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

Para obtener más información sobre cómo crear recursos de script de implementación, consulte Creación de scripts de implementación. Para la creación de scripts para el recurso de script de implementación, le aconsejamos establecer un entorno de desarrollo de scripts dedicado, como una instancia de contenedor de Azure o una imagen de Docker. Una vez que haya desarrollado y probado exhaustivamente los scripts, puede integrar o invocar los archivos de script desde el recurso de script de implementación. Para obtener más información, consulte Configuración del entorno de desarrollo para scripts.

Guarde el script en un archivo inlineScript.bicep y, a continuación, implemente el recurso mediante el siguiente script:

$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 ..."

Uso de identidad administrada

En el ejemplo siguiente se muestra cómo usar la identidad administrada para interactuar con Azure desde dentro del script de implementación.

@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://learn.microsoft.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
    '''
  }
}

Supervisión y solución de problemas de scripts de implementación

Al implementar un recurso de script de implementación, se requiere una cuenta de almacenamiento para almacenar el script de usuario, los resultados de la ejecución y el archivo stdout. Puede especificar su propia cuenta de almacenamiento. Para obtener más información, consulte Uso de una cuenta de almacenamiento existente.

Una alternativa a especificar su propia cuenta de almacenamiento implica establecer cleanupPreference en OnExpiration. A continuación, configure retentionInterval para una duración que permita un tiempo suficiente para revisar las salidas antes de quitar la cuenta de almacenamiento. Para más información, consulte Limpieza de los recursos del script de implementación.

Agregue la propiedad cleanupPreference al archivo Bicep anterior y establezca el valor en OnExpiration. El valor predeterminado es Always. Además, establezca rentalInterval en PT1H (una hora) o menos.

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

Una vez implementado correctamente el archivo de Bicep, use Azure Portal, la CLI de Azure, Azure PowerShell o la API de REST para comprobar los resultados.

Azure portal

Después de implementar un recurso de script de implementación, el recurso se muestra en el grupo de recursos de Azure Portal. En la página de información general se enumeran los dos recursos auxiliares además del recurso de script de implementación. Los recursos auxiliares se eliminarán después de que expire el intervalo de retención.

Observe que ambos recursos admitidos tienen el sufijo azscripts en sus nombres porque estos recursos se crean automáticamente. La otra manera de identificar los recursos auxiliares es mediante etiquetas.

Captura de pantalla de un grupo de recursos de script de implementación.

Seleccione el recurso de script de implementación de la lista. La página de información general de un recurso de script de implementación muestra información importante sobre el recurso, como el estado de aprovisionamiento y los dos recursos auxiliares (la cuenta de almacenamiento y la instancia de contenedor). El área Registros muestra el texto impreso del script.

Captura de pantalla de un recurso de script de implementación.

Seleccione Salidas para mostrar las salidas del script.

Captura de pantalla de las salida de script de implementación.

Vuelva al grupo de recursos y seleccione sucesivamente la cuenta de almacenamiento, Recursos compartidos de archivos y el recurso compartido de archivos con azscripts anexado al nombre del recurso compartido. Aparecen dos carpetas en la lista: azscriptinput y azscriptoutput. La carpeta de salida contiene un archivo executionresult.json y el archivo de salida del script. El archivo executionresult.json contiene el mensaje de error de ejecución del script. El archivo de salida solo se crea cuando el script se ejecuta correctamente.

Captura de pantalla del contenido de la carpeta de salida de un script de implementación.

La carpeta de entrada contiene el archivo de script del sistema y el archivo de script de implementación del usuario. Puede reemplazar el archivo de script de implementación de usuario por uno revisado y volver a ejecutar el script de implementación en la instancia de Azure Container.

CLI de Azure

Puede usar la CLI de Azure para administrar scripts de implementación en el ámbito de la suscripción o del grupo de recursos:

La salida del comando de lista es similar a este ejemplo:

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

Puede usar Azure PowerShell para administrar scripts de implementación en el ámbito de la suscripción o del grupo de recursos:

El resultado de Get-AzDeploymentScript es similar a este ejemplo:

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

Puede usar la API de REST para obtener información acerca del recurso de script de implementación en el nivel de grupo de recursos y en el nivel de suscripción:

/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

En el ejemplo siguiente se usa ARMClient. ARMClient no es una herramienta compatible con Microsoft.

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

El resultado es similar a este ejemplo:

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

La siguiente API REST devuelve el registro:

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

Solo funciona antes de que se eliminen los recursos del script de implementación.


Códigos de error del script de implementación

En la tabla siguiente se enumeran los códigos de error del script de implementación:

Código de error Descripción
DeploymentScriptInvalidOperation La definición del recurso de script de implementación del archivo de Bicep contiene nombres de propiedad no válidos.
DeploymentScriptResourceConflict No puede eliminar un recurso del script de implementación si se encuentra en un estado no terminal cuando la ejecución no ha superado una hora. O bien, no puede volver a ejecutar el mismo script de implementación con el mismo identificador de recurso (la misma suscripción, el mismo nombre de grupo de recursos y el mismo nombre de recurso) pero con un contenido de cuerpo del script diferente al mismo tiempo.
DeploymentScriptOperationFailed Error interno en la operación del script de implementación. Póngase en contacto con el soporte técnico de Microsoft.
DeploymentScriptStorageAccountAccessKeyNotSpecified No se especificó la clave de acceso para la cuenta de almacenamiento existente.
DeploymentScriptContainerGroupContainsInvalidContainers Un grupo de contenedores creado por el servicio de script de implementación se modificó externamente y se agregaron contenedores no válidos.
DeploymentScriptContainerGroupInNonterminalState Dos o más recursos del script de implementación usan el mismo nombre de instancia de contenedor de Azure en el mismo grupo de recursos, y uno de ellos todavía no ha terminado de ejecutarse.
DeploymentScriptExistingStorageNotInSameSubscriptionAsDeploymentScript El almacenamiento existente proporcionado en la implementación no se encuentra en la suscripción donde se implementa el script.
DeploymentScriptStorageAccountInvalidKind La cuenta de almacenamiento existente del tipo BlobBlobStorage o BlobStorage no admite recursos compartidos de archivos y, por tanto, no se puede usar.
DeploymentScriptStorageAccountInvalidKindAndSku La cuenta de almacenamiento existente no admite recursos compartidos de archivos. Para obtener una lista de los tipos de cuenta de almacenamiento admitidos, vea Uso de una cuenta de almacenamiento existente.
DeploymentScriptStorageAccountNotFound La cuenta de almacenamiento no existe, o bien una herramienta o proceso externo la ha eliminado.
DeploymentScriptStorageAccountWithServiceEndpointEnabled La cuenta de almacenamiento especificada tiene un punto de conexión de servicio. No se admite una cuenta de almacenamiento con un punto de conexión de servicio.
DeploymentScriptStorageAccountInvalidAccessKey Se ha especificado una clave de acceso no válida para la cuenta de almacenamiento existente.
DeploymentScriptStorageAccountInvalidAccessKeyFormat La clave de la cuenta de almacenamiento tiene un formato no válido. Vea Administración de las claves de acceso de la cuenta de almacenamiento.
DeploymentScriptExceededMaxAllowedTime El tiempo de ejecución del script de implementación superó el valor de tiempo de espera especificado en la definición de recursos del script de implementación.
DeploymentScriptInvalidOutputs La salida del script de implementación no es un objeto JSON válido.
DeploymentScriptContainerInstancesServiceLoginFailure La identidad administrada asignada por el usuario no pudo iniciar sesión después de 10 intentos con un intervalo de un minuto.
DeploymentScriptContainerGroupNotFound Una herramienta o un proceso externo eliminó un grupo de contenedores que había creado el servicio de script de implementación.
DeploymentScriptDownloadFailure Error al descargar un script auxiliar. Consulte Uso de scripts auxiliares.
DeploymentScriptError El script de usuario generó un error.
DeploymentScriptBootstrapScriptExecutionFailed El script de arranque produjo un error. El script de arranque es el script del sistema que organiza la ejecución del script de implementación.
DeploymentScriptExecutionFailed Se ha producido un error desconocido durante la ejecución del script de implementación.
DeploymentScriptContainerInstancesServiceUnavailable Durante la creación de una instancia de contenedor, el servicio Azure Container Instances emitió un error de "servicio no disponible".
DeploymentScriptContainerGroupInNonterminalState Durante la creación de una instancia de contenedor, otro script de implementación usaba el mismo nombre de instancia de contenedor en el mismo ámbito (misma suscripción, nombre de grupo de recursos y nombre de recurso).
DeploymentScriptContainerGroupNameInvalid El nombre de instancia de contenedor especificado no cumple los requisitos de Azure Container Instances. Vea Solución de problemas habituales de Azure Container Instances.

Acceso a una red virtual privada

Puede ejecutar scripts de implementación en redes privadas con algunas configuraciones adicionales. Para obtener más información, vea Acceso a una red virtual privada mediante el punto de conexión de servicio o Ejecutar script de implementación de Bicep de forma privada a través de un punto de conexión privado.

Pasos siguientes

En este artículo, aprendió a usar scripts de implementación. Para obtener más información, consulte: