共用方式為


在 ARM 範本中使用部署指令碼

了解如何使用 Azure Resource Manager (ARM) 範本中的部署指令碼。 使用者可以使用 deploymentScripts 資源,在 ARM 部署中執行指令碼,並檢閱執行結果。

提示

我們建議使用 Bicep,因為其提供的功能與 ARM 範本相同,而且語法更易於使用。 若要深入了解,請參閱部署指令碼

這些指令碼可以用來執行自訂步驟,例如:

  • 將使用者新增到目錄。
  • 執行資料平面作業,例如複製 Blob 或植入資料庫。
  • 查詢及驗證授權金鑰。
  • 建立自我簽署憑證。
  • 在 Microsoft Entra ID 中建立物件。
  • 從自訂系統查詢 IP 位址區塊。

部署指令碼的優點:

  • 易於編寫程式碼、使用和偵錯。 您可以在慣用的開發環境中開發部署指令碼。 這些指令碼可以內嵌在範本或外部指令檔中。
  • 您可以指定指令碼語言和平台。 目前支援在 Linux 環境上的 Azure PowerShell 和 Azure CLI 部署指令碼。
  • 允許將命令列引數傳遞至指令碼。
  • 可以指定指令碼輸出,並將其傳回至部署。

部署指令碼資源僅適用於可使用 Azure 容器執行個體的區域。 請參閱 Azure 容器執行個體在 Azure 區域中的資源可用性。 目前,部署指令碼只會使用公用網路。

重要

部署指令碼服務需要兩個支援的資源才能執行和疑難排解指令碼:儲存體帳戶和容器執行個體。 您可以指定現有的儲存體帳戶,否則指令碼服務會為您建立帳戶。 當部署指令碼執行進入終端狀態時,指令碼服務通常會刪除這兩個自動建立的支援資源。 在資源刪除之前,您需針對支援的資源支付費用。 如需價格資訊,請參閱容器執行個體定價Azure 儲存體定價。 若要深入了解,請參閱清除部署指令碼資源

注意

Azure 登入的重試邏輯現在已內建至包裝函式指令碼。 如果您在與部署指令碼相同的範本中授與權限,則部署指令碼服務會以 10 秒的間隔重試登入 10 分鐘,直到受控識別角色指派已複寫為止。

訓練資源

如果您比較想要透過逐步指導來了解部署指令碼,請參閱使用部署指令碼擴充 ARM 範本

設定最低權限

針對部署指令碼 API 版本 2020-10-01 或更新版本,部署指令碼執行牽涉到兩個主體:

  • 部署主體 (用來部署範本的主體):此主體可用來建立要執行的部署指令碼資源所需的基礎資源,也就是儲存體帳戶和 Azure 容器執行個體。 若要設定最低權限,請使用下列屬性將自訂角色指派給部署主體:

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

    如果 Azure 儲存體和 Azure 容器執行個體資源提供者尚未註冊,您也需要新增 Microsoft.Storage/register/actionMicrosoft.ContainerInstance/register/action

  • 部署指令碼主體:只有在部署指令碼需要向 Azure 進行驗證並呼叫 Azure CLI/PowerShell 時,才需要此主體。 有兩種方式可以指定部署指令碼主體:

    • identity 屬性中指定使用者指派的受控識別 (請參閱範例範本)。 指定之後,指令碼服務會在叫用部署指令碼之前呼叫 Connect-AzAccount -Identity。 受控識別必須擁有必要的存取權,才能完成指令碼中的作業。 目前,identity 屬性僅支援使用者指派的受控識別。 若要使用不同的身分識別登入,請使用此清單中的第二個方法。
    • 將服務主體認證傳遞為安全的環境變數,然後便可以在部署指令碼中呼叫 Connect-AzAccountaz login

    如果使用受控識別,則部署主體需要將受控識別操作員角色 (內建角色) 指派給受控識別資源。

範例範本

下列的 JSON 是一個範例。 如需詳細資訊,請參閱最新的範本結構描述

{
  "type": "Microsoft.Resources/deploymentScripts",
  "apiVersion": "2020-10-01",
  "name": "runPowerShellInline",
  "location": "[resourceGroup().location]",
  "tags": {
    "tagName1": "tagValue1",
    "tagName2": "tagValue2"
  },
  "kind": "AzurePowerShell", // or "AzureCLI"
  "identity": {
    "type": "userAssigned",
    "userAssignedIdentities": {
      "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID": {}
    }
  },
  "properties": {
    "forceUpdateTag": "1",
    "containerSettings": {
      "containerGroupName": "mycustomaci"
    },
    "storageAccountSettings": {
      "storageAccountName": "myStorageAccount",
      "storageAccountKey": "myKey"
    },
    "azPowerShellVersion": "9.7",  // or "azCliVersion": "2.47.0",
    "arguments": "-name \\\"John Dole\\\"",
    "environmentVariables": [
      {
        "name": "UserName",
        "value": "jdole"
      },
      {
        "name": "Password",
        "secureValue": "jDolePassword"
      }
    ],
    "scriptContent": "
      param([string] $name)
      $output = 'Hello {0}. The username is {1}, the password is {2}.' -f $name,${Env:UserName},${Env:Password}
      Write-Output $output
      $DeploymentScriptOutputs = @{}
      $DeploymentScriptOutputs['text'] = $output
    ", // or "primaryScriptUri": "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/deployment-script/deploymentscript-helloworld.ps1",
    "supportingScriptUris":[],
    "timeout": "PT30M",
    "cleanupPreference": "OnSuccess",
    "retentionInterval": "P1D"
  }
}

注意

此範例僅供示範之用。 屬性 scriptContentprimaryScriptUri 不能並存於範本中。

注意

ScriptContent 會顯示包括多行的指令碼。 Azure 入口網站和 Azure DevOps 管線無法剖析具有多行的部署指令碼。 您可以 (使用分號或 \r\n 或 \n) 將 PowerShell 命令鏈結成一行,也可以對於外部指令檔使用 primaryScriptUri 屬性。 有許多 JSON 字串逸出/反逸出工具可供使用。 例如: https://www.freeformatter.com/json-escape.html

屬性值詳細資料:

  • identity:針對部署指令碼 API 2020-10-01 版或更新版本,除非您需要在指令碼中執行任何 Azure 特定的動作,否則使用者指派的受控識別是選擇性的。 而 API 版本 2019-10-01-preview 則需要受控識別,因為部署指令碼服務會用其來執行指令碼。 指定識別屬性時,指令碼服務會先呼叫 Connect-AzAccount -Identity,然後再叫用使用者指令碼。 目前僅支援使用者指派的受控識別。 若要使用不同的身分識別登入,您可以在指令碼中呼叫 Connect-AzAccount

  • tags:部署指令碼標記。 如果部署指令碼服務產生儲存體帳戶和容器執行個體,標記會傳遞至這兩個資源,可用來識別它們。 識別這些資源的另一種方式是透過其後置詞,其中包含 “azscripts”。 如需詳細資訊,請參閱監視部署指令碼並進行疑難排解

  • kind:指定指令碼的類型。 目前 Azure PowerShell 和 Azure CLI 指令碼皆受支援。 值為 AzurePowerShellAzureCLI

  • forceUpdateTag:在範本部署之間變更此值,會強制部署指令碼重新執行。 如果您使用 newGuid()utcNow() 函式,則這兩個函式只能用於參數的預設值。 若要深入了解,請參閱執行指令碼多次

  • containerSettings:指定此設定以自訂 Azure 容器執行個體。 部署指令碼需要新的 Azure 容器執行個體。 您無法指定現有的 Azure 容器執行個體。 不過,您可以使用 containerGroupName 自訂容器群組名稱。 如果未指定,系統會自動產生群組名稱。

  • storageAccountSettings:指定此設定以使用現有儲存體帳戶。 如果未指定 storageAccountName,則會自動建立儲存體帳戶。 請參閱使用現有儲存體帳戶

  • azPowerShellVersion/azCliVersion:指定要使用的模組版本。 請參閱支援的 Azure PowerShell 版本清單。 版本會決定要使用的容器映像:

    • Az 版本大於或等於 9 使用 Ubuntu 22.04。
    • Az 版本大於或等於 6 但小於 9 使用 Ubuntu 20.04。
    • Az 版本小於 6 使用 Ubuntu 18.04。

    重要

    建議您升級至最新版本的Ubuntu,因為 Ubuntu18.04 即將結束生命週期,且 2023 年 5 月 31 日後不再收到安全性更新。

    請參閱支援的 Azure CLI 版本清單。

    重要

    部署指令碼會使用 Microsoft Container Registry (MCR) 中的可用 CLI 映像。 通常需要約一個月的時間來認證適用於部署指令碼的 CLI 映像。 請勿使用在 30 天內發行的 CLI 版本。 若要尋找映像的發行日期,請參閱 Azure CLI 版本資訊。 如果使用不支援的版本,則錯誤訊息會列出支援的版本。

  • arguments:指定參數值。 多個值應以空格分隔。

    部署指令碼會叫用 CommandLineToArgvW 系統呼叫,將引數分割為字串陣列。 這是必要的步驟,因為引數會以命令屬性的形式傳遞至 Azure 容器執行個體,而命令屬性是字串的陣列。

    如果引數包含已逸出的字元,請使用 JsonEscaper 對字元進行雙逸出處理。 將原始的逸出字元串貼入工具中,然後選取 [逸出]。 此工具會輸出雙逸出字串。 例如,在先前的範例範本中,引數為 -name \"John Dole\"。 已逸出的字串為 -name \\\"John Dole\\\"

    若要將型別物件的 ARM 範本參數傳遞為引數,請使用 string() 函式將物件轉換為字串,然後使用 replace() 函式將任何 \" 取代為 \\\"。 例如:

    replace(string(parameters('tables')), '\"', '\\\"')
    

    如需詳細資訊,請參閱範例範本

  • environmentVariables:指定要傳遞至指令碼的環境變數。 如需相關資訊,請參閱開發部署指令碼

  • scriptContent:指定指令碼內容。 若要執行外部指令碼,請改用 primaryScriptUri。 如需範例,請參閱使用內嵌指令碼使用外部指令碼

  • primaryScriptUri:使用支援的副檔名,為主要部署指令碼指定可公開存取的 URL。 如需詳細資訊,請參閱使用外部指令碼

  • supportingScriptUris:以 scriptContentprimaryScriptUri 中呼叫的支援檔案指定可公開存取的 URL 陣列。 如需詳細資訊,請參閱使用外部指令碼

  • timeout:以 ISO 8601 格式指定指令碼執行時間允許上限。 預設值為 P1D

  • cleanupPreference. 指定在指令碼執行進入終端狀態時,清除兩個支援的部署資源、儲存體帳戶和容器執行個體的喜好設定。 預設設定為 [一律],這表示不論終端狀態 (成功、失敗、已取消) 皆刪除支援的資源。 若要深入了解,請參閱清除部署指令碼資源

  • retentionInterval:指定在部署指令碼執行達終端狀態後,服務會保留部署指令碼資源的時間間隔。 此持續時間到期後,即會刪除部署指令碼資源。 持續時間以 ISO 8601 模式為基礎。 保留間隔介於 1 到 26 小時 (PT26H)。 當 cleanupPreference 設為 OnExpiration 時,就會使用此屬性。 若要深入了解,請參閱清除部署指令碼資源

更多樣本

  • 範例 1:建立金鑰保存庫,並使用部署指令碼將憑證指派給金鑰保存庫。
  • 範例 2:在訂閱層級建立資源群組、在資源群組中建立金鑰保存庫,然後使用部署指令碼將憑證指派給金鑰保存庫。
  • 範例 3:建立使用者指派的受控識別、將參與者角色指派給資源群組層級的身分識別、建立金鑰保存庫,然後使用部署指令碼將憑證指派給金鑰保存庫。
  • 範例 4:這與此清單中的範例 1 情節相同。 建立新的資源群組,藉以執行部署指令碼。 此範本是訂閱層級範本。
  • 範例 5:這與範例 4 的情節相同。 此範本是資源群組層級範本。
  • 範例 6:手動建立使用者指派的受控識別,並將授權指派給使用 Microsoft Graph API 建立 Microsoft Entra 應用程式;在 ARM 範本中,使用部署指令碼建立 Microsoft Entra 應用程式和服務主體,並輸出物件識別碼和用戶端識別碼。

使用內嵌指令碼

下列範本有一個以 Microsoft.Resources/deploymentScripts 類型定義的資源。 反白顯示的部分是內嵌指令碼。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "name": {
      "type": "string",
      "defaultValue": "\\\"John Dole\\\""
    },
    "utcValue": {
      "type": "string",
      "defaultValue": "[utcNow()]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "runPowerShellInlineWithOutput",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "properties": {
        "forceUpdateTag": "[parameters('utcValue')]",
        "azPowerShellVersion": "8.3",
        "scriptContent": "
          param([string] $name)
          $output = \"Hello {0}\" -f $name
          Write-Output $output
          $DeploymentScriptOutputs = @{}
          $DeploymentScriptOutputs['text'] = $output
        ",
        "arguments": "[concat('-name', ' ', parameters('name'))]",
        "timeout": "PT1H",
        "cleanupPreference": "OnSuccess",
        "retentionInterval": "P1D"
      }
    }
  ],
  "outputs": {
    "result": {
      "value": "[reference('runPowerShellInlineWithOutput').outputs.text]",
      "type": "string"
    }
  }
}

注意

因為內嵌部署指令碼會以雙引號括住,所以部署指令碼內的字串必須使用反斜線 (\) 逸出或以單引號括住。 您也可以考慮使用字串替代,如先前的 JSON 範例中所示。

指令碼接受一個參數,並輸出參數值。 DeploymentScriptOutputs 用於儲存輸出。 在 [輸出] 區段中,value 行會顯示如何存取儲存的值。 Write-Output 是用來偵錯。 若要了解如何存取輸出檔,請參閱監視部署指令碼並進行疑難排解。 如需屬性描述,請參閱範例範本

若要執行指令碼,請選取 [試試看] 以開啟 Cloud Shell,然後將下列程式碼貼到 Shell 窗格中。

$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 -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/deployment-script/deploymentscript-helloworld.json"

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

輸出如下所示:

Resource Manager 範本部署腳本你好世界輸出的螢幕快照。

使用外部指令碼

除了內嵌指令碼之外,您也可以使用外部指令檔。 僅支援具有 ps1 副檔名的主要 PowerShell 指令碼。 針對 CLI 指令碼,只要指令碼是有效的 bash 指令碼,主要指令碼就可以有任何延伸模組 (或不含延伸模組)。 若要使用外部指令檔,請將 scriptContent 取代為 primaryScriptUri。 例如:

"primaryScriptUri": "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/deployment-script/deploymentscript-helloworld.ps1",

如需詳細資訊,請參閱範例範本

外部指令檔必須可供存取。 若要保護儲存在 Azure 儲存體帳戶中的指令檔,請產生一個 SAS 權杖,並將其包含在範本的 URI 中。 設定到期時間,以允許足夠的時間來完成部署。 如需詳細資訊,請參閱部署具備 SAS 權杖的私人 ARM 範本

您必須負責確保部署指令碼 primaryScriptUrisupportingScriptUris 所參照的指令碼完整性。 只參考您信任的指令碼。

使用支援的指令碼

您可以將複雜的邏輯分隔成一個或多個支援的指令檔。 supportingScriptUris 屬性可讓您視需要將 URI 陣列提供給支援的指令檔:

"scriptContent": "
    ...
    ./Create-Cert.ps1
    ...
"

"supportingScriptUris": [
  "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/deployment-script/create-cert.ps1"
],

您可以從內嵌指令碼和主要指令檔呼叫支援的指令檔。 支援的指令檔對副檔名沒有任何限制。

支援的檔案會在執行階段複製到 azscripts/azscriptinput。 使用相對路徑來參考內嵌指令碼和主要指令檔中的支援檔案。

使用 PowerShell 指令碼的輸出

下列範本示範如何在兩個 deploymentScripts 資源之間傳遞值:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "name": {
      "type": "string",
      "defaultValue": "John Dole"
    },
    "utcValue": {
      "type": "string",
      "defaultValue": "[utcNow()]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "scriptInTemplate1",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "properties": {
        "forceUpdateTag": "[parameters('utcValue')]",
        "azPowerShellVersion": "8.3",
        "timeout": "PT1H",
        "arguments": "[concat('-name', ' ', concat('\\\"', parameters('name'), '\\\"'))]",
        "scriptContent": "
          param([string] $name)
          $output = 'Hello {0}' -f $name
          Write-Output $output
          $DeploymentScriptOutputs = @{}
          $DeploymentScriptOutputs['text'] = $output
        ",
        "cleanupPreference": "Always",
        "retentionInterval": "P1D"
      }
    },
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "scriptInTemplate2",
      "location": "[resourceGroup().location]",
      "kind": "AzurePowerShell",
      "dependsOn": [
        "scriptInTemplate1"
      ],
      "properties": {
        "forceUpdateTag": "[parameters('utcValue')]",
        "azPowerShellVersion": "8.3",
        "timeout": "PT1H",
        "arguments": "[concat('-textToEcho', ' ', concat('\\\"', reference('scriptInTemplate1').outputs.text, '\\\"'))]",
        "scriptContent": "
          param([string] $textToEcho)
          Write-Output $textToEcho
          $DeploymentScriptOutputs = @{}
          $DeploymentScriptOutputs['text'] = $textToEcho
        ",
        "cleanupPreference": "Always",
        "retentionInterval": "P1D"
      }
    }
  ],
  "outputs": {
    "result": {
      "value": "[reference('scriptInTemplate2').outputs.text]",
      "type": "string"
    }
  }
}

在第一個資源中,您會定義名為 $DeploymentScriptOutputs 的變數,並使用其來儲存輸出值。 若要從範本內的另一個資源存取輸出值,請使用:

reference('<ResourceName>').outputs.text

使用 CLI 指令碼的輸出

相較於 Azure PowerShell 部署指令碼,CLI/bash 不會公開用來儲存指令碼輸出的常用變數。 相反地,它會使用名為 AZ_SCRIPTS_OUTPUT_PATH 的環境變數來指出指令碼輸出檔案的位置。 在 ARM 範本內執行部署指令碼時,Bash 殼層會自動為您設定此環境變數。 其預先定義的值會設定為 /mnt/azscripts/azscriptoutput/scriptoutputs.json。 輸出必須符合有效的 JSON 字串物件結構。 檔案的內容應該格式化為機碼值組。 例如,字串陣列應該儲存為 { "MyResult": [ "foo", "bar"] }。 只儲存陣列結果 (例如 [foo“、”bar“ ]) 會被視為無效。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "identity": {
      "type": "string"
    },
    "utcValue": {
      "type": "string",
      "defaultValue": "[utcNow()]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2020-10-01",
      "name": "runBashWithOutputs",
      "location": "[resourceGroup().location]",
      "kind": "AzureCLI",
      "identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
          "[parameters('identity')]": {
          }
        }
      },
      "properties": {
        "forceUpdateTag": "[parameters('utcValue')]",
        "AzCliVersion": "2.40.0",
        "timeout": "PT30M",
        "arguments": "'foo' 'bar'",
        "environmentVariables": [
          {
            "name": "UserName",
            "value": "jdole"
          },
          {
            "name": "Password",
            "secureValue": "jDolePassword"
          }
        ],
        "scriptContent": "result=$(az keyvault list); echo \"arg1 is: $1\"; echo \"arg2 is: $2\"; echo \"Username is: $UserName\"; echo \"password is: $Password\"; echo $result | jq -c '{Result: map({id: .id})}' > $AZ_SCRIPTS_OUTPUT_PATH",
        "cleanupPreference": "OnExpiration",
        "retentionInterval": "P1D"

先前的範例會使用 jq。 其隨附於容器映像。 請參閱設定開發環境

使用現有的儲存體帳戶

執行執行個體及疑難排解時,需要儲存體帳戶和容器執行個體。 您可以選擇指定現有的儲存體帳戶,否則指令碼服務會自動建立儲存體帳戶和容器執行個體。 使用現有儲存體帳戶的需求:

  • 支援的儲存體帳戶類型為:

    SKU 支援的類型
    Premium_LRS FileStorage
    Premium_ZRS FileStorage
    Standard_GRS Storage、StorageV2
    Standard_GZRS StorageV2
    Standard_LRS Storage、StorageV2
    Standard_RAGRS Storage、StorageV2
    Standard_RAGZRS StorageV2
    Standard_ZRS StorageV2

    這些組合支援檔案共用。 如需詳細資訊,請參閱建立 Azure 檔案共用儲存體帳戶類型

  • 尚未支援儲存體帳戶防火牆規則。 如需詳細資訊,請參閱設定 Azure 儲存體防火牆和虛擬網路

  • 部署主體必須擁有管理儲存體帳戶的權限,包括讀取、建立、刪除檔案共用。

  • 儲存器 allowSharedKeyAccess 帳戶的 屬性必須設定為 true。 在 Azure 容器實例中掛接記憶體帳戶的唯一方式是透過存取密鑰。

若要指定現有的儲存體帳戶,請將下列 JSON 新增至 Microsoft.Resources/deploymentScripts 的屬性元素:

"storageAccountSettings": {
  "storageAccountName": "myStorageAccount",
  "storageAccountKey": "myKey"
},
  • storageAccountName:指定儲存體帳戶的名稱。

  • storageAccountKey:指定其中一個儲存體帳戶金鑰。 您可以使用 listKeys() 函式來擷取金鑰。 例如:

    "storageAccountSettings": {
        "storageAccountName": "[variables('storageAccountName')]",
        "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').keys[0].value]"
    }
    

如需完整的 Microsoft.Resources/deploymentScripts 定義範例,請參閱範例範本

使用現有的儲存體帳戶時,指令碼服務會建立具有唯一名稱的檔案共用。 如需了解指令碼服務如何清理檔案共用,請參閱清除部署指令碼資源

開發部署指令碼

處理非終止錯誤

您可以使用部署指令碼中的 $ErrorActionPreference 變數,藉此控制 PowerShell 回應非終止錯誤的方式。 如果您的部署指令碼中未設定變數,指令碼服務會使用預設值 Continue

當指令碼在設定 $ErrorActionPreference 時遇到錯誤時,指令碼服務會將資源佈建狀態設定為 失敗

使用環境變數

部署指令碼會使用下列環境變數:

環境變數 預設值 系統保留
AZ_SCRIPTS_AZURE_ENVIRONMENT AzureCloud
AZ_SCRIPTS_CLEANUP_PREFERENCE OnExpiration
AZ_SCRIPTS_OUTPUT_PATH <AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY>/<AZ_SCRIPTS_PATH_SCRIPT_OUTPUT_FILE_NAME> Y
AZ_SCRIPTS_PATH_INPUT_DIRECTORY /mnt/azscripts/azscriptinput Y
AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY /mnt/azscripts/azscriptoutput Y
AZ_SCRIPTS_PATH_USER_SCRIPT_FILE_NAME Azure PowerShell:userscript.ps1;Azure CLI:userscript.sh Y
AZ_SCRIPTS_PATH_PRIMARY_SCRIPT_URI_FILE_NAME primaryscripturi.config Y
AZ_SCRIPTS_PATH_SUPPORTING_SCRIPT_URI_FILE_NAME supportingscripturi.config Y
AZ_SCRIPTS_PATH_SCRIPT_OUTPUT_FILE_NAME scriptoutputs.json Y
AZ_SCRIPTS_PATH_EXECUTION_RESULTS_FILE_NAME executionresult.json Y
AZ_SCRIPTS_USER_ASSIGNED_IDENTITY /subscriptions/

如需使用 AZ_SCRIPTS_OUTPUT_PATH 的詳細資訊,請參閱使用 CLI 指令碼的輸出

將安全的字串傳遞至部署指令碼

在您的容器執行個體中設定環境變數 (EnvironmentVariable),可讓您提供由容器執行之應用程式或指令碼的動態設定。 部署指令碼會以與 Azure 容器執行個體相同的方式來處理不安全及安全的環境變數。 如需詳細資訊,請參閱設定容器執行個體中的環境變數。 如需範例,請參閱範例範本

環境變數的允許大小上限為 64 KB。

監視部署指令碼並進行疑難排解

指令碼服務會建立儲存體帳戶 (除非您指定現有的儲存體帳戶) 和容器執行個體以執行指令碼。 如果這些資源是由指令碼服務自動建立,則這兩個資源在資源名稱中都會有 azscripts 尾碼。

Resource Manager 範本部署腳本資源名稱的螢幕快照。

使用者指令碼、執行結果和 stdout 檔案會儲存在儲存體帳戶的檔案共用中。 有個名為 azscripts 的資料夾。 在此資料夾中,還有兩個供輸入和輸出檔案的資料夾:azscriptinputazscriptoutput

輸出檔案夾包含 executionresult.json 和指令碼輸出檔案。 您可以在 executionresult.json 中查看指令碼執行錯誤訊息。 只有在指令碼執行成功時,才會建立輸出檔案。 輸入資料夾包含系統 PowerShell 指令檔和使用者部署指令檔。 您可以使用已修改的檔案來取代使用者部署指令檔,然後從 Azure 容器執行個體重新執行部署指令碼。

使用 Azure 入口網站

在部署指令碼資源部署完成後,資源會列在 Azure 入口網站中的資源群組下。 下列螢幕擷取畫面顯示部署指令碼資源的 [概觀] 頁面:

Resource Manager 範本部署腳本入口網站概觀的螢幕快照。

概觀頁面會顯示資源的一些重要資訊,例如 [佈建狀態]、[儲存體帳戶]、[容器執行個體] 和 [記錄]

從左側功能表中,您可以檢視部署指令碼內容、傳遞給指令碼的引數,並且進行輸出。 您也可以匯出包含部署指令碼的部署指令碼範本。

使用 PowerShell

您可以使用 Azure PowerShell,在訂閱或資源群組範圍管理部署指令碼:

Get-AzDeploymentScript 輸出類似於:

Name                : runPowerShellInlineWithOutput
Id                  : /subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myds0618rg/providers/Microsoft.Resources/deploymentScripts/runPowerShellInlineWithOutput
ResourceGroupName   : myds0618rg
Location            : centralus
SubscriptionId      : aaaabbbb-0000-cccc-1111-dddd2222eeee
ProvisioningState   : Succeeded
Identity            : /subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/mydentity1008rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myuami
ScriptKind          : AzurePowerShell
AzPowerShellVersion : 9.7
StartTime           : 5/11/2023 7:46:45 PM
EndTime             : 5/11/2023 7:49:45 PM
ExpirationDate      : 5/12/2023 7:49:45 PM
CleanupPreference   : OnSuccess
StorageAccountId    : /subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myds0618rg/providers/Microsoft.Storage/storageAccounts/ftnlvo6rlrvo2azscripts
ContainerInstanceId : /subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myds0618rg/providers/Microsoft.ContainerInstance/containerGroups/ftnlvo6rlrvo2azscripts
Outputs             :
                      Key                 Value
                      ==================  ==================
                      text                Hello John Dole

RetentionInterval   : P1D
Timeout             : PT1H

使用 Azure CLI

您可以使用 Azure CLI,在訂閱或資源群組範圍管理部署指令碼:

清單命令輸出會類似於:

[
  {
    "arguments": "'foo' 'bar'",
    "azCliVersion": "2.40.0",
    "cleanupPreference": "OnExpiration",
    "containerSettings": {
      "containerGroupName": null
    },
    "environmentVariables": null,
    "forceUpdateTag": "20231101T163748Z",
    "id": "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myds0624rg/providers/Microsoft.Resources/deploymentScripts/runBashWithOutputs",
    "identity": {
      "tenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
      "type": "userAssigned",
      "userAssignedIdentities": {
        "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourcegroups/myidentity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myuami": {
          "clientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
          "principalId": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
        }
      }
    },
    "kind": "AzureCLI",
    "location": "centralus",
    "name": "runBashWithOutputs",
    "outputs": {
      "Result": [
        {
          "id": "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/mytest/providers/Microsoft.KeyVault/vaults/mykv1027",
          "resourceGroup": "mytest"
        }
      ]
    },
    "primaryScriptUri": null,
    "provisioningState": "Succeeded",
    "resourceGroup": "mytest",
    "retentionInterval": "1 day, 0:00:00",
    "scriptContent": "result=$(az keyvault list); echo \"arg1 is: $1\"; echo $result | jq -c '{Result: map({id: .id})}' > $AZ_SCRIPTS_OUTPUT_PATH",
    "status": {
      "containerInstanceId": "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/mytest/providers/Microsoft.ContainerInstance/containerGroups/eg6n7wvuyxn7iazscripts",
      "endTime": "2023-11-01T16:39:12.080950+00:00",
      "error": null,
      "expirationTime": "2023-11-02T16:39:12.080950+00:00",
      "startTime": "2023-11-01T16:37:53.139700+00:00",
      "storageAccountId": null
    },
    "storageAccountSettings": {
      "storageAccountKey": null,
      "storageAccountName": "dsfruro267qwb4i"
    },
    "supportingScriptUris": null,
    "systemData": {
      "createdAt": "2023-10-31T19:06:57.060909+00:00",
      "createdBy": "someone@contoso.com",
      "createdByType": "User",
      "lastModifiedAt": "2023-11-01T16:37:51.859570+00:00",
      "lastModifiedBy": "someone@contoso.com",
      "lastModifiedByType": "User"
    },
    "tags": null,
    "timeout": "0:30:00",
    "type": "Microsoft.Resources/deploymentScripts"
  }
]

使用 REST API

您可以使用 REST API,在資源群組層級和訂用帳戶層級取得部署指令碼資源部署資訊:

/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

下列範例會使用 ARMClient

armclient login
armclient get /subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourcegroups/myrg/providers/microsoft.resources/deploymentScripts/myDeployementScript?api-version=2020-10-01

輸出如下:

{
  "kind": "AzurePowerShell",
  "identity": {
    "type": "userAssigned",
    "tenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
    "userAssignedIdentities": {
      "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myidentity1008rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myuami": {
        "principalId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
        "clientId": "00001111-aaaa-2222-bbbb-3333cccc4444"
      }
    }
  },
  "location": "centralus",
  "systemData": {
    "createdBy": "someone@contoso.com",
    "createdByType": "User",
    "createdAt": "2023-05-11T02:59:04.7501955Z",
    "lastModifiedBy": "someone@contoso.com",
    "lastModifiedByType": "User",
    "lastModifiedAt": "2023-05-11T02:59:04.7501955Z"
  },
  "properties": {
    "provisioningState": "Succeeded",
    "forceUpdateTag": "20220625T025902Z",
    "azPowerShellVersion": "9.7",
    "scriptContent": "\r\n          param([string] $name)\r\n          $output = \"Hello {0}\" -f $name\r\n          Write-Output $output\r\n          $DeploymentScriptOutputs = @{}\r\n          $DeploymentScriptOutputs['text'] = $output\r\n        ",
    "arguments": "-name \\\"John Dole\\\"",
    "retentionInterval": "P1D",
    "timeout": "PT1H",
    "containerSettings": {},
    "status": {
      "containerInstanceId": "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myds0624rg/providers/Microsoft.ContainerInstance/containerGroups/64lxews2qfa5uazscripts",
      "storageAccountId": "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myds0624rg/providers/Microsoft.Storage/storageAccounts/64lxews2qfa5uazscripts",
      "startTime": "2023-05-11T02:59:07.5951401Z",
      "endTime": "2023-05-11T03:00:16.7969234Z",
      "expirationTime": "2023-05-12T03:00:16.7969234Z"
    },
    "outputs": {
      "text": "Hello John Dole"
    },
    "cleanupPreference": "OnSuccess"
  },
  "id": "/subscriptions/aaaabbbb-0000-cccc-1111-dddd2222eeee/resourceGroups/myds0624rg/providers/Microsoft.Resources/deploymentScripts/runPowerShellInlineWithOutput",
  "type": "Microsoft.Resources/deploymentScripts",
  "name": "runPowerShellInlineWithOutput"
}

下列 REST API 會傳回記錄:

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

只有在刪除部署指令碼資源之前才可運作。

若要在入口網站中查看 deploymentScripts 資源,請選取 [顯示隱藏的類型]

Resource Manager 範本部署腳本的螢幕快照,其中顯示入口網站中的隱藏類型選項。

清除部署指令碼資源

除非刪除資源失敗,否則兩個自動建立的支援資源生命週期永遠無法超過 deploymentScript。 支援資源的生命週期是由 cleanupPreference 屬性所控制, deploymentScript 資源的生命週期由 retentionInterval 屬性控制:

  • cleanupPreference當指令碼執行進入終端狀態時,清除兩個支援資源的喜好設定。 支援的值為:

    • Always:一旦指令碼執行進入終端狀態後,即刪除兩個支援的資源。 如果使用現有的儲存體帳戶,指令碼服務會刪除由服務建立的檔案共用。 由於 deploymentScripts 資源在支援資源清除後可能仍會存在,因此指令碼服務會在刪除資源之前保存指令碼執行結果,例如 StdOut、輸出、傳回值等等。

    • OnSuccess:只有在指令碼執行成功時,才刪除兩個支援的資源。 如果使用現有的儲存體帳戶,指令碼服務只會在指令碼執行成功時,才會移除檔案共用。

      如果指令碼執行不成功,指令碼服務會等到 retentionInterval 過期後才清除支援的資源,然後再清除部署指令碼資源。

    • OnExpiration:只有在 retentionInterval 設定過期時,才刪除兩個支援的資源。 如果使用現有的儲存體帳戶,指令碼服務會移除檔案共用,但會保留儲存體帳戶。

    系統會根據 cleanupPreference 來刪除容器執行個體和儲存體帳戶。 但是,如果指令碼失敗且 cleanupPreference 未設為 [Always],則部署流程會自動讓容器保持執行一小時的時間,或直到容器清除為止。 您可以使用這一小時對指令碼進行疑難排解。 如果您想在成功部署之後讓容器保持執行,請將睡眠步驟新增至指令碼。 例如,將 Start-Sleep 新增至指令碼的結尾。 如果您未新增睡眠步驟,系統會將容器設為終止狀態,即使尚未刪除也無法供存取。

  • retentionInterval:指定要保留 deploymentScript 資源的時間間隔,在其後將會過期並加以刪除。

注意

不建議針對其他目的使用由指令碼服務產生的儲存體帳戶和容器執行個體。 視指令碼生命週期而定,可能會移除這兩個資源。

如果部署指令碼部署至具有 CanNotDelete 鎖定的資源群組,則無法刪除自動建立的儲存體帳戶和容器執行個體。 若要解決此問題,您可以將部署指令碼部署到另一個沒有鎖定的資源群組。 請參閱範例範本中的範例 4 和範例 5。

執行指令碼超過一次

部署指令碼執行是等冪性作業。 如果未變更任何 deploymentScripts 資源屬性 (包括內嵌指令碼),則在您重新部署範本時,指令碼不會執行。 部署指令碼服務會比較範本中的資源名稱與相同資源群組中的現有資源。 如果您想要多次執行相同的部署指令碼,有兩個選項:

  • 變更 deploymentScripts 資源的名稱。 例如,使用 utcNow 範本函式做為資源名稱,或做為資源名稱的一部分。 變更資源名稱會建立新的 deploymentScripts 資源。 這很適合用來保存指令碼執行的歷程記錄。

    注意

    utcNow 函式只能用於參數的預設值。

  • 在 [forceUpdateTag 範本] 屬性中指定不同的值。 例如,使用 utcNow 為值。

注意

撰寫具有等冪性的部署指令碼。 這可確保如果不小心再次執行,不會造成系統變更。 例如,如果部署指令碼是用來建立 Azure 資源,在建立資源之前請先確認資源不存在,因此指令碼將會成功,或者您不會重新建立資源。

設定開發環境

您可以使用預先設定的容器映像作為部署指令碼開發環境。 如需詳細資訊,請參閱針對範本中的部署指令碼設定開發環境

成功測試指令碼之後,您可以使用其做為範本中的部署指令碼。

部署指令碼錯誤碼

錯誤碼 描述
DeploymentScriptInvalidOperation 範本中的部署指令碼資源定義包含不正確的屬性名稱。
DeploymentScriptResourceConflict 無法刪除處於非終止狀態,且執行未超過 1 小時的部署指令碼資源。 也無法同時重新執行具有相同的資源識別碼 (相同的訂閱、資源群組名稱和資源名稱),但具有不同指令碼主體內容的相同部署指令碼。
DeploymentScriptOperationFailed 部署指令碼作業內部執行失敗。 請連絡 Microsoft 支援服務。
DeploymentScriptStorageAccountAccessKeyNotSpecified 尚未指定現有儲存體帳戶的存取金鑰。
DeploymentScriptContainerGroupContainsInvalidContainers 部署指令碼服務所建立的容器群組已從外部修改,並新增不正確的容器。
DeploymentScriptContainerGroupInNonterminalState 有兩個或多個部署指令碼資源在相同的資源群組中使用相同的 Azure 容器執行個體名稱,且其中一個資源尚未完成執行。
DeploymentScriptStorageAccountInvalidKind BlobBlobStorage 或 BlobStorage 類型的現有儲存體帳戶不支援檔案共用,因此無法使用。
DeploymentScriptStorageAccountInvalidKindAndSku 現有的儲存體帳戶不支援檔案共用。 如需支援的儲存體帳戶類型清單,請參閱使用現有的儲存體帳戶
DeploymentScriptStorageAccountNotFound 儲存體帳戶不存在或已由外部流程或工具刪除。
DeploymentScriptStorageAccountWithServiceEndpointEnabled 指定的儲存體帳戶具有服務端點。 不支援具有服務端點的儲存體帳戶。
DeploymentScriptStorageAccountInvalidAccessKey 為現有的儲存體帳戶指定的存取金鑰無效。
DeploymentScriptStorageAccountInvalidAccessKeyFormat 儲存體帳戶金鑰格式不正確。 請參閱管理儲存體帳戶存取金鑰
DeploymentScriptExceededMaxAllowedTime 部署指令碼的執行時間超過部署指令碼資源定義中指定的逾時值。
DeploymentScriptInvalidOutputs 部署指令碼輸出不是有效的 JSON 物件。
DeploymentScriptContainerInstancesServiceLoginFailure 使用者指派的受控識別在 1 分鐘的間隔內嘗試了 10 次後仍無法成功登入。
DeploymentScriptContainerGroupNotFound 外部工具或流程刪除了部署指令碼服務所建立的容器群組。
DeploymentScriptDownloadFailure 無法下載支援的指令碼。 請參閱使用支援的指令碼
DeploymentScriptError 使用者指令碼擲回錯誤。
DeploymentScriptBootstrapScriptExecutionFailed 啟動程序指令碼擲回錯誤。 啟動程序指令碼是可協調部署指令碼執行的系統指令碼。
DeploymentScriptExecutionFailed 部署指令碼執行期間發生未知的錯誤。
DeploymentScriptContainerInstancesServiceUnavailable 建立 Azure 容器執行個體 (ACI) 時,ACI 擲回服務無法使用的錯誤。
DeploymentScriptContainerGroupInNonterminalState 建立 Azure 容器執行個體 (ACI) 時,另一個部署指令碼在相同範圍 (相同的訂閱、資源群組名稱和資源名稱) 內使用了相同的 ACI 名稱。
DeploymentScriptContainerGroupNameInvalid 指定的 Azure 容器執行個體 (ACI) 名稱不符合 ACI 需求。 請參閱針對 Azure 容器執行個體的常見問題進行疑難排解

在部署指令碼中使用 Microsoft Graph

部署指令碼可以使用 Microsoft Graph 在 Microsoft Entra ID 中建立和使用物件。

命令

當您使用 Azure CLI 部署指令碼時,您可以使用命令群組內的 az ad 命令來處理應用程式、服務主體、群組和使用者。 您也可以使用 az rest 命令直接叫用 Microsoft Graph API。

當您使用Azure PowerShell部署指令碼時,您可以使用 Invoke-RestMethod Cmdlet 直接叫用 Microsoft Graph API。

權限

您的部署指令碼所使用的身分識別必須經過授權,才能使用 Microsoft 圖形 API,以及其所執行作業的適當授權。 您必須授權範本部署外部的身分識別,例如預先建立使用者指派的受控識別,並將它指派為 Microsoft Graph 的應用程式角色。 如需詳細資訊,請參閱此快速入門範例

存取私人虛擬網路

使用 Microsoft.Resources/deploymentScripts 2023-08-01 版,您可以使用一些額外的設定,在私人網路中執行部署指令碼。

  • 建立使用者指派的受控識別,並在 identity 屬性中指定。 若要指派身分識別,請參閱身分識別

  • 建立設定為 true 的記憶體帳戶allowSharedKeyAccess,並指定要使用現有記憶體帳戶的部署腳本。 若要指定現有的儲存體帳戶,請參閱使用現有的儲存體帳戶。 儲存體帳戶需要一些額外的設定。

    1. Azure 入口網站中開啟儲存體帳戶。

    2. 從左側功能表中,選取 [存取控制 (IAM)],然後選取 [角色指派] 索引標籤。

    3. Storage File Data Privileged Contributor 角色新增至使用者指派受控識別。

    4. 從左側功能表的 [安全性 + 網路] 區段中,選取 [網路],然後選取 [防火牆和虛擬網路] 索引標籤。

    5. 選取 [從選取的虛擬網路和 IP 位址啟用]

      設定記憶體帳戶以存取專用網的螢幕快照。

    6. 在 [虛擬網路] 下,新增子網路。 在螢幕擷取畫面中,子網路稱為 dspvnVnet

    7. 在 [例外狀況] 底下,選取 [允許受信任服務清單上的 Azure 服務以存取此儲存體帳戶]

下列 ARM 範本示範如何設定環境以執行部署指令碼:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "prefix": {
      "type": "string",
      "maxLength": 10
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "userAssignedIdentityName": {
      "type": "string",
      "defaultValue": "[format('{0}Identity', parameters('prefix'))]"
    },
    "storageAccountName": {
      "type": "string",
      "defaultValue": "[format('{0}stg{1}', parameters('prefix'), uniqueString(resourceGroup().id))]"
    },
    "vnetName": {
      "type": "string",
      "defaultValue": "[format('{0}Vnet', parameters('prefix'))]"
    },
    "subnetName": {
      "type": "string",
      "defaultValue": "[format('{0}Subnet', parameters('prefix'))]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2023-09-01",
      "name": "[parameters('vnetName')]",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "10.0.0.0/16"
          ]
        },
        "enableDdosProtection": false,
        "subnets": [
          {
            "name": "[parameters('subnetName')]",
            "properties": {
              "addressPrefix": "10.0.0.0/24",
              "serviceEndpoints": [
                {
                  "service": "Microsoft.Storage"
                }
              ],
              "delegations": [
                {
                  "name": "Microsoft.ContainerInstance.containerGroups",
                  "properties": {
                    "serviceName": "Microsoft.ContainerInstance/containerGroups"
                  }
                }
              ]
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-01-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "StorageV2",
      "properties": {
        "networkAcls": {
          "bypass": "AzureServices",
          "virtualNetworkRules": [
            {
              "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]",
              "action": "Allow",
              "state": "Succeeded"
            }
          ],
          "defaultAction": "Deny"
        },
        "allowSharedKeyAccess": true
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
      ]
    },
    {
      "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
      "apiVersion": "2023-07-31-preview",
      "name": "[parameters('userAssignedIdentityName')]",
      "location": "[parameters('location')]"
    },
    {
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2022-04-01",
      "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('storageAccountName'))]",
      "name": "[guid(tenantResourceId('Microsoft.Authorization/roleDefinitions', '69566ab7-960f-475b-8e7c-b3118f30c6bd'), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName')), resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')))]",
      "properties": {
        "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName')), '2023-07-31-preview').principalId]",
        "roleDefinitionId": "[tenantResourceId('Microsoft.Authorization/roleDefinitions', '69566ab7-960f-475b-8e7c-b3118f30c6bd')]",
        "principalType": "ServicePrincipal"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
        "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]"
      ]
    }
  ]
}

您可以使用下列 ARM 範本來測試部署:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "prefix": {
      "type": "string"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "utcValue": {
      "type": "string",
      "defaultValue": "[utcNow()]"
    },
    "storageAccountName": {
      "type": "string"
    },
    "vnetName": {
      "type": "string"
    },
    "subnetName": {
      "type": "string"
    },
    "userAssignedIdentityName": {
      "type": "string"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deploymentScripts",
      "apiVersion": "2023-08-01",
      "name": "[format('{0}DS', parameters('prefix'))]",
      "location": "[parameters('location')]",
      "identity": {
        "type": "userAssigned",
        "userAssignedIdentities": {
          "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName')))]": {}
        }
      },
      "kind": "AzureCLI",
      "properties": {
        "forceUpdateTag": "[parameters('utcValue')]",
        "azCliVersion": "2.47.0",
        "storageAccountSettings": {
          "storageAccountName": "[parameters('storageAccountName')]"
        },
        "containerSettings": {
          "subnetIds": [
            {
              "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('subnetName'))]"
            }
          ]
        },
        "scriptContent": "echo \"Hello world!\"",
        "retentionInterval": "P1D",
        "cleanupPreference": "OnExpiration"
      }
    }
  ]
}

下一步

在本文中,您已了解如何使用部署指令碼。 逐步解說部署指令碼教學課程: