O que são scripts de implantação?

Concluído

Nesta unidade, você aprenderá como o recurso pode estender os deploymentScripts modelos do Azure Resource Manager (ARM).

Os modelos ARM são coisas maravilhosas. Você pode usá-los para declarar o estado desejado de sua infraestrutura de nuvem e deixar as APIs e serviços descobrirem como chegar lá. No entanto, ocasionalmente você precisa executar ações que estão fora do que o Azure Resource Manager fornece.

O que são scripts de implantação?

deploymentScripts recursos são scripts PowerShell ou Bash que são executados em um contêiner do Docker como parte da implantação do modelo. As imagens de contêiner padrão têm a CLI do Azure ou o Azure PowerShell disponíveis. Esses scripts são executados durante o processamento do modelo ARM, para que você possa adicionar um comportamento personalizado ao processo de implantação.

Os scripts de implantação usam uma identidade gerenciada para autenticar no Azure. Uma identidade gerenciada é uma entidade de serviço cuja credencial e ciclo de vida são gerenciados pela plataforma Azure. Essa identidade é o que os comandos do Azure PowerShell ou da CLI do Azure usarão para agir no ambiente. Como você atribui a identidade, controla o escopo do que um deploymentScripts recurso pode afetar.

O deploymentScripts recurso produz uma saída que outros recursos na implantação podem usar. Em seguida, você pode procurar informações de um sistema externo ou fornecer dados com base no estado atual do seu ambiente para afetar o restante da implantação.

Como funcionam os scripts de implantação

Um deploymentScripts recurso usa um script fornecido pelo usuário (do modelo ou por URI) e, possivelmente, alguns scripts de suporte e os executa em uma instância de contêiner do Azure. Essa instância de contêiner recebe a identidade gerenciada que você fornece. Os scripts e sua saída são armazenados em um compartilhamento de arquivos para uma conta de armazenamento do Azure.

Quando a implantação do modelo é executada, ela verifica se há um recurso existente deploymentScripts no grupo de recursos de destino. Em caso afirmativo, compara as propriedades. Se tudo corresponder, nada de novo acontece. Se o recurso não existir ou tiver sido alterado, o Azure Resource Manager criará uma nova instância de contêiner e executará os scripts de implantação dentro dessa instância de contêiner. Qualquer saída definida será passada de volta para o Azure Resource Manager para uso posterior na implantação.

Estrutura do script de implantação

Para adicionar um comportamento personalizado a um modelo ARM, comece com o deploymentScripts recurso. No mínimo, você precisa fornecer detalhes comuns como:

  • A name para o deploymentScripts recurso.
  • O type e apiVersion valores.
  • O local (location valor) onde os recursos de suporte serão criados.
  • Um objeto vazio properties . Você vai chegar a isso em breve.

São necessários dois deploymentScriptsvalores específicos:

  • kind: O tipo de script a ser executado (ou AzurePowerShell 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: A identidade gerenciada que a instância de contêiner usará. Você pode criar a identidade gerenciada com antecedência e especificá-la como no exemplo a seguir, ou pode criá-la no modelo e fazer referência a ela lá (que é o que você fará no próximo exercício).

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

Depois de definir esses elementos, você pode mover para a properties seção do deploymentScripts recurso. A parte principal disso é o , que especifica o scriptContentscript real a ser executado:

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

Observe que o scriptContent usa uma cadeia de caracteres de várias linhas. No Bicep, você pode especificar uma cadeia de caracteres de várias linhas usando três aspas juntas (''') antes e depois da cadeia de caracteres.

É comum que um script de implantação passe as saídas de volta para a implantação. Por exemplo, se você estiver usando um script para procurar algumas informações de uma API, poderá passar as informações de volta para a implantação como uma saída. Outros recursos na implantação poderiam então usar as informações em suas próprias definições.

Para um script do PowerShell, você passa as saídas de volta criando uma variável chamada $DeploymentScriptOutputs, que precisa ser uma tabela de hash. O script de exemplo inicializa a tabela de hash e, em seguida, cria uma saída chamada text, que obtém seu valor da $output variável local:

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

Gorjeta

Você também pode escrever scripts de implantação no Bash. Para criar saídas a partir de um script Bash, você precisa criar um arquivo JSON em um local especificado pela variável de AZ_SCRIPTS_OUTPUT_PATH ambiente.

Dentro da properties seção, você também define as várias opções que deploymentScripts podem ser tomadas. Neste módulo, vamos mantê-lo simples e adicionar apenas o suficiente para que o script seja executado. No mínimo, você precisa fornecer a versão do Azure PowerShell ou da CLI do Azure a ser usada, um script a ser executado e um intervalo de retenção.

O intervalo de retenção é por quanto tempo os resultados devem ser mantidos se você quiser manter os recursos. Por padrão, os resultados são removidos depois de executar o 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'
}

Nosso modelo completo seria algo como:

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

Incluir arquivos de script

A incorporação de scripts em linha em modelos pode ser complicada, difícil de ler e entender e difícil de alterar. O Bicep usa a loadTextContent() função para incorporar um arquivo de texto externo em sua implantação. Quando o Bicep transpila seu modelo em JSON, ele incorpora o arquivo externo no modelo que ele emite.

Digamos que você tenha um arquivo do PowerShell chamado myscript.ps1 na mesma pasta do seu modelo Bicep. Você pode dizer ao Bicep para incorporar o arquivo assim:

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

Você pode encontrar todas as propriedades do deploymentScripts recurso na documentação de referência do modelo ARM.