Compartilhar via


Tutorial: Usar scripts de implantação para criar um certificado autoassinado

Saiba como usar scripts de implantação em modelos do ARM (modelos do Azure Resource Manager). Os scripts de implantação podem ser usados para executar etapas personalizadas que não podem ser feitas por modelos do ARM. Por exemplo, criar um certificado autoassinado. Neste tutorial, você criará um modelo para implantar um Azure Key Vault e, em seguida, usará um recurso Microsoft.Resources/deploymentScripts no mesmo modelo para criar um certificado e adicioná-lo ao cofre de chaves. Para saber mais sobre o script de implantação, confira Usar scripts de implantação em modelos do ARM.

Importante

Dois recursos de script de implantação, uma conta de armazenamento e uma instância de contêiner, são criados no mesmo grupo de recursos para execução de script e solução de problemas. Esses recursos geralmente são excluídos pelo serviço de script quando a execução de script entra em um estado terminal. Você será cobrado pelos recursos até que eles sejam excluídos. Para saber mais, confira Limpar recursos do script de implantação.

Este tutorial cobre as seguintes tarefas:

  • Abrir um modelo de início rápido
  • Editar o modelo
  • Implantar o modelo
  • Depurar o script com falha
  • Limpar os recursos

Para ver um módulo do Learn que aborde os scripts de implantação, confira Estender modelos do ARM usando scripts de implantação.

Pré-requisitos

Para concluir este artigo, você precisa do seguinte:

  • Visual Studio Code com a extensão Ferramentas do Resource Manager. Confira Início Rápido: Criar modelos do ARM com o Visual Studio Code.

  • Uma identidade gerenciada atribuída pelo usuário. Essa identidade é usada para executar ações específicas do Azure no script. Para criar uma, confira Identidade gerenciada atribuída por usuário. Você precisa da ID da identidade ao implantar o modelo. O formato da identidade é:

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

    Use o script da CLI a seguir para obter a ID fornecendo o nome do grupo de recursos e o nome da identidade.

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

Abrir um modelo de Início Rápido

Em vez de criar um modelo do zero, você pode abrir um modelo de Modelos de Início Rápido do Azure. Modelos de Início Rápido do Azure é um repositório de modelos do ARM.

O modelo usado neste início rápido é chamado de Criar um Azure Key Vault e um segredo. O modelo cria um cofre de chaves e adiciona um segredo a ele.

  1. No Visual Studio Code, escolha Arquivo>Abrir Arquivo.

  2. Em Nome do arquivo, cole a seguinte URL:

    https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.keyvault/key-vault-create/azuredeploy.json
    
  3. Escolha Abrir para abrir o arquivo.

  4. Escolha Arquivo>Salvar como para salvar o arquivo como azuredeploy.json em seu computador local.

Editar o modelo

Faça as alterações a seguir no modelo:

Limpar o modelo (opcional)

O modelo original adiciona um segredo ao cofre de chaves. Para simplificar o tutorial, remova o seguinte recurso:

  • Microsoft.KeyVault/vaults/secrets

Remova as duas seguintes definições de parâmetro:

  • secretName
  • secretValue

Se optar por não remover essas definições, você precisará especificar os valores de parâmetro durante a implantação.

Configurar as políticas de acesso do cofre de chaves

O script de implantação adiciona um certificado ao cofre de chaves. Configure as políticas de acesso do cofre de chaves para fornecer a permissão à identidade gerenciada:

  1. Adicione um parâmetro para obter a ID da identidade gerenciada:

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

    Observação

    A extensão do modelo do Resource Manager do Visual Studio Code ainda não é capaz de formatar scripts de implantação. Não use Shift+Alt+F para formatar os recursos deploymentScripts, como o descrito a seguir.

  2. Adicione um parâmetro para configurar as políticas de acesso do cofre de chaves para que a identidade gerenciada possa adicionar certificados ao cofre de chaves:

    "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. Atualize as políticas de acesso do cofre de chaves existente a:

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

    Há duas políticas definidas, uma para o usuário conectado e a outra para a identidade gerenciada. O usuário conectado precisa apenas da permissão de lista para verificar a implantação. Para simplificar o tutorial, o mesmo certificado é atribuído à identidade gerenciada e aos usuários conectados.

Adicionar o script de implantação

  1. Adicione três parâmetros usados pelo script de implantação:

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

    Observação

    Como os scripts de implantação embutidos são colocados entre aspas duplas, as cadeias de caracteres dentro dos scripts de implantação precisam ser colocadas entre aspas simples. O caractere de escape do PowerShell é o acento 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"
      }
    }
    

    O recurso deploymentScripts depende do recurso do cofre de chaves e do recurso de atribuição de função. Ele tem estas propriedades:

    • identity: o script de implantação usa uma identidade gerenciada atribuída pelo usuário para executar as operações no script.
    • kind: especifica o tipo de script. Atualmente, há suporte apenas para scripts do PowerShell.
    • forceUpdateTag: determine se o script de implantação deverá ser executado mesmo se a origem do script não tiver sido alterada. Pode ser o carimbo de data/hora atual ou um GUID. Para saber mais, confira Executar script mais de uma vez.
    • azPowerShellVersion: especifica a versão do módulo do Azure PowerShell a ser usada. No momento, o script de implantação é compatível com as versões 2.7.0, 2.8.0 e 3.0.0.
    • timeout: especifique o tempo de execução máximo permitido do script especificado no formato ISO 8601. O valor padrão é P1D.
    • arguments: Especifique os valores de parâmetro. os valores são separados por espaços.
    • scriptContent: especifique o conteúdo do script. Para executar um script externo, use primaryScriptURI. Para obter mais informações, confira Usar script externo. Declarar $DeploymentScriptOutputs só é necessário ao testar o script em um computador local. Declarar a variável permite que o script seja executado em um computador local e em um recurso deploymentScript sem precisar fazer alterações. O valor atribuído a $DeploymentScriptOutputs está disponível como saídas na implantação. Para obter mais informações, confira Trabalhar com saídas de scripts de implantação do PowerShell ou Trabalhar com saídas de scripts de implantação da CLI.
    • cleanupPreference: especifique a preferência sobre quando excluir os recursos de script de implantação. O valor padrão é Sempre, o que significa que os recursos do script de implantação são excluídos apesar do estado terminal (Com êxito, Com falha, Cancelado). Neste tutorial, OnSuccess é usado para que você tenha a oportunidade de exibir os resultados da execução do script.
    • retentionInterval: especifique o intervalo para o qual o serviço reterá os recursos de script após atingir um estado terminal. Os recursos serão excluídos quando essa duração expirar. A duração é baseada no padrão ISO 8601. Este tutorial usa P1D, que significa um dia. Essa propriedade é usada quando cleanupPreference está configurado como OnExpiration. Essa propriedade não está habilitada no momento.

    O script de implantação usa três parâmetros: keyVaultName, certificateName e subjectName. Ele cria um certificado e o adiciona ao cofre de chaves.

    $DeploymentScriptOutputs é usado para armazenar o valor de saída. Para saber mais, confira Trabalhar com saídas de scripts de implantação do PowerShell ou Trabalhar com saídas de scripts de implantação da CLI.

    O modelo completo pode ser encontrado aqui.

  3. Para ver o processo de depuração, insira um erro no código adicionando a seguinte linha ao script de implantação:

    Write-Output1 $keyVaultName
    

    O comando correto é Write-Output em vez de Write-Output1.

  4. Escolha Arquivo>Salvar para salvar o arquivo.

Implantar o modelo

  1. Entrar no Azure Cloud Shell

  2. Escolha seu ambiente preferencial selecionando PowerShell ou Bash (para a CLI) no canto superior esquerdo. Ao alternar, é necessário reiniciar o shell.

    Azure portal Cloud Shell upload file

  3. Escolha Carregar/fazer o download dos arquivos e, em seguida, escolha Carregar. Consulte a captura de tela anterior. Selecione o arquivo que você salvou na seção anterior. Depois de carregar o arquivo, use os comandos ls e cat para verificar se o arquivo foi carregado com êxito.

  4. Execute o script da CLI do Azure ou do Azure PowerShell a seguir para implantar o modelo.

    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
    

    O serviço de script de implantação precisa criar outros recursos de script de implantação para a execução do script. Pode levar até um minuto para que a preparação e o processo de limpeza sejam concluídos, além do tempo de execução do script real.

    A implantação falhou devido ao comando inválido Write-Output1 usado no script. Você receberá um erro dizendo:

    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.
    

    O resultado da execução do script de implantação é armazenado nos recursos do script de implantação para a finalidade de solução de problemas.

Depurar o script com falha

  1. Entre no portal do Azure.

  2. Abra o grupo de recursos. É o nome do projeto com rg acrescentado. Você verá dois recursos adicionais no grupo de recursos. Esses recursos são chamados de recursos de script de implantação.

    Resource Manager template deployment script resources

    Os dois arquivos têm o sufixo azscripts. Um é uma conta de armazenamento e o outro é uma instância de contêiner.

    Selecione Mostrar tipos ocultos para listar o recurso deploymentScripts.

  3. Selecione a conta de armazenamento com o sufixo azscripts.

  4. Selecione o bloco Compartilhamentos de arquivo. Você verá uma pasta azscripts que contém os arquivos de execução do script de implantação.

  5. Selecione azscripts. Você deverá ver duas pastas azscriptinput e azscriptoutput. A pasta de entrada contém um arquivo de script do PowerShell do sistema e os arquivos de script da implantação do usuário. A pasta de saída contém um executionresult.json e o arquivo de saída de script. Você pode ver a mensagem de erro em executionresult.json. O arquivo de saída não está lá porque a execução falhou.

Remova a linha de Write-Output1 e reimplante o modelo.

Quando a segunda implantação for executada com êxito, os recursos do script de implantação serão removidos pelo serviço de script, porque a propriedade cleanupPreference foi definida como OnSuccess.

Limpar os recursos

Quando os recursos do Azure já não forem necessários, limpe os recursos implantados excluindo o grupo de recursos.

  1. No portal do Azure, escolha Grupos de recursos do menu à esquerda.
  2. No campo Filtrar por nome, insira o nome do grupo de recursos.
  3. Selecione o nome do grupo de recursos.
  4. Escolha Excluir grupo de recursos no menu superior.

Próximas etapas

Neste tutorial, você aprendeu a usar o script de implantação nos modelos do ARM. Para saber como implantar recursos do Azure com base em condições, veja: