ARM 템플릿에서 배포 스크립트 사용

ARM(Azure Resource Manager) 템플릿에서 배포 스크립트를 사용하는 방법에 대해 알아봅니다. deploymentScripts 리소스를 사용하여 ARM 배포에서 스크립트를 실행하고 실행 결과를 검토할 수 있습니다.

ARM 템플릿과 동일한 기능을 제공하고 구문이 사용하기 더 쉽기 때문에 Bicep를 권장합니다. 자세한 내용은 배포 스크립트를 참조하세요.

이러한 스크립트는 다음과 같은 사용자 지정 단계를 수행하는 데 사용할 수 있습니다.

  • 디렉터리에 사용자를 추가합니다.
  • 데이터 평면 작업(예: BLOB 또는 시드 데이터베이스 복사)을 수행합니다.
  • 라이선스 키를 조회하고 유효성을 검사합니다.
  • 자체 서명된 인증서를 만듭니다.
  • Microsoft Entra ID에서 개체를 만듭니다.
  • 사용자 지정 시스템에서 IP 주소 블록을 조회합니다.

배포 스크립트의 이점은 다음과 같습니다.

  • 쉽게 코딩하고, 사용하고, 디버그할 수 있습니다. 원하는 개발 환경에서 배포 스크립트를 개발할 수 있습니다. 스크립트는 템플릿 또는 외부 스크립트 파일에 포함될 수 있습니다.
  • 스크립트 언어 및 플랫폼을 지정할 수 있습니다. 현재 Linux 환경에서 Azure PowerShell 및 Azure CLI 배포 스크립트가 지원됩니다.
  • 스크립트에 명령줄 인수를 전달할 수 있습니다.
  • 스크립트 출력을 지정하고 이를 배포에 다시 전달할 수 있습니다.

배포 스크립트 리소스는 Azure Container Instance를 사용할 수 있는 지역에서만 사용할 수 있습니다. Azure 지역의 Azure Container Instances에 대한 리소스 가용성을 참조하세요. 현재 배포 스크립트는 공용 네트워킹만 사용합니다.

Important

배포 스크립트 서비스에는 스크립트 실행 및 문제 해결을 위한 두 가지 지원 리소스인 스토리지 계정과 컨테이너 인스턴스가 필요합니다. 기존 스토리지 계정을 지정할 수 있습니다. 그렇지 않으면 스크립트 서비스가 자동으로 계정을 만듭니다. 자동으로 생성된 두 지원 리소스는 일반적으로 배포 스크립트 실행이 터미널 상태가 되면 스크립트 서비스에 의해 삭제됩니다. 삭제될 때까지 지원 리소스에 대한 요금이 청구됩니다. 가격 정보는 Container Instances 가격 책정Azure Storage 가격 책정을 참조하세요. 자세한 내용은 배포 스크립트 리소스 정리를 참조하세요.

참고 항목

이제 Azure 로그인에 대한 다시 시도 논리가 래퍼 스크립트에 기본적으로 제공됩니다. 배포 스크립트와 동일한 템플릿에서 권한을 부여하는 경우 배포 스크립트 서비스는 관리 ID 역할 할당이 복제될 때까지 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 Storage 및 Azure Container Instance 리소스 공급자가 등록되지 않은 경우 Microsoft.Storage/register/actionMicrosoft.ContainerInstance/register/action도 추가해야 합니다.

  • 배포 스크립트 주체: 이 주체는 배포 스크립트가 Azure에 인증하고 Azure CLI/PowerShell을 호출해야 하는 경우에만 필요합니다. 배포 스크립트 주체를 지정하는 방법에는 두 가지가 있습니다.

    • identity 속성에서 사용자 할당 관리 ID를 지정합니다(샘플 템플릿 참조). 지정된 경우 스크립트 서비스는 배포 스크립트를 호출하기 전에 Connect-AzAccount -Identity을 호출합니다. 관리 ID에는 스크립트에서 작업을 완료하는 데 필요한 액세스 권한이 있어야 합니다. 현재는 identity 속성에 대해 사용자 할당 관리 ID만 지원됩니다. 다른 ID로 로그인하려면 이 목록의 두 번째 메서드를 사용합니다.
    • 서비스 주체 자격 증명을 보안 환경 변수로 전달한 다음 배포 스크립트에서 Connect-AzAccount 또는 az login을 호출할 수 있습니다.

    관리 ID가 사용되는 경우 배포 주체에는 관리 ID 리소스에 할당된 관리 ID 운영자 역할(기본 제공 역할)이 필요합니다.

샘플 템플릿

다음 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/01234567-89AB-CDEF-0123-456789ABCDEF/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 Portal 및 Azure DevOps 파이프라인은 여러 줄이 있는 배포 스크립트를 구문 분석할 수 없습니다. 세미콜론 또는 \r\n 또는 \n을 사용하여 PowerShell 명령을 한 줄로 연결하거나 외부 스크립트 파일과 함께 primaryScriptUri 속성을 사용할 수 있습니다. 다양한 자유 JSON 문자열 이스케이프/이스케이프 해제 도구를 사용할 수 있습니다. 예: https://www.freeformatter.com/json-escape.html.

속성 값 세부 정보:

  • identity: 배포 스크립트 API 버전 2020-10-01 이상에서는 스크립트에서 Azure 관련 작업을 수행해야 하는 경우가 아니라면 사용자 할당 관리 ID가 선택 사항입니다. API 버전 2019-10-01-preview의 경우 배포 스크립트 서비스가 스크립트를 실행하는 데 사용하므로 관리 ID가 필요합니다. ID 속성이 지정된 경우 스크립트 서비스는 사용자 스크립트를 호출하기 전에 Connect-AzAccount -Identity를 호출합니다. 현재 사용자가 할당한 관리 ID만 지원됩니다. 다른 ID로 로그인하려면 스크립트에서 Connect-AzAccount를 호출하면 됩니다.

  • tags: 배포 스크립트 태그. 배포 스크립트 서비스가 스토리지 계정 및 컨테이너 인스턴스를 생성하는 경우 태그는 두 리소스에 모두 전달되며 이를 식별하는 데 사용할 수 있습니다. 이러한 리소스를 식별하는 또 다른 방법은 "azscripts"를 포함하는 접미사를 사용하는 것입니다. 자세한 내용은 배포 스크립트 모니터링 및 문제 해결을 참조하세요.

  • kind: 스크립트 유형을 지정합니다. 현재는 Azure PowerShell 및 Azure CLI 스크립트가 지원됩니다. 값은 AzurePowerShellAzureCLI입니다.

  • forceUpdateTag: 템플릿 배포 간에 이 값을 변경하면 배포 스크립트가 강제로 다시 실행됩니다. newGuid() 또는 utcNow() 함수를 사용하는 경우 두 함수는 모두 매개 변수의 기본값에서만 사용할 수 있습니다. 자세한 내용은 스크립트를 두 번 이상 실행을 참조하세요.

  • containerSettings: Azure Container Instance를 사용자 지정하려면 설정을 지정합니다. 배포 스크립트에는 새 Azure Container Instance가 필요합니다. 기존 Azure Container Instance는 지정할 수 없습니다. 그러나 containerGroupName을 사용하여 컨테이너 그룹 이름을 사용자 지정할 수 있습니다. 지정하지 않으면 그룹 이름이 자동으로 생성됩니다.

  • storageAccountSettings: 기존 스토리지 계정을 사용하려면 설정을 지정합니다. storageAccountName이 지정되지 않으면 스토리지 계정이 자동으로 만들어집니다. 기존 스토리지 계정 사용을 참조하세요.

  • azPowerShellVersion/azCliVersion: 사용할 모듈 버전을 지정합니다. 지원되는 Azure PowerShell 버전 목록을 참조하세요. 버전은 사용할 컨테이너 이미지를 결정합니다.

    • 9 이상 Az 버전은 Ubuntu 22.04를 사용합니다.
    • 6이상 9 미만 Az 버전은 Ubuntu 20.04를 사용합니다.
    • 6 미만 Az 버전은 Ubuntu 18.04를 사용합니다.

    Important

    Ubuntu 18.04가 수명이 거의 끝나 2023년 5월 31일 이후에 더 이상 보안 업데이트를 받지 않으므로 최신 버전의 Ubuntu로 업그레이드하는 것이 좋습니다.

    지원되는 Azure CLI 버전 목록을 참조하세요.

    Important

    배포 스크립트는 MCR(Microsoft Container Registry)에서 사용 가능한 CLI 이미지를 사용합니다. 일반적으로 배포 스크립트의 CLI 이미지를 인증하는 데 약 한 달이 걸립니다. 30일 이내에 릴리스된 CLI 버전은 사용하지 마세요. 이미지의 릴리스 날짜를 확인하려면 Azure CLI 릴리스 정보를 참조하세요. 지원되지 않는 버전을 사용하는 경우 오류 메시지에 지원되는 버전이 나열됩니다.

  • arguments: 매개 변수 값을 지정합니다. 값은 공백으로 구분됩니다.

    배포 스크립트는 CommandLineToArgvW 시스템 호출을 호출하여 인수를 문자열 배열로 분할합니다. 인수가 Azure Container Instance에 명령 속성으로 전달되고 명령 속성이 문자열 배열이기 때문에 이 단계가 필요합니다.

    인수에 이스케이프된 문자가 포함된 경우 JsonEscaper를 사용하여 문자를 두 번 이스케이프 합니다. 원래 이스케이프된 문자열을 도구에 붙여넣은 다음, 이스케이프를 선택합니다. 이 도구는 이중 이스케이프된 문자열을 출력합니다. 예를 들어 이전 샘플 템플릿에서 인수는 -name \"John Dole\"입니다. 이스케이프된 문자열은 -name \\\"John Dole\\\"입니다.

    Object 형식의 ARM 템플릿 매개 변수를 인수로 전달하려면 string() 함수를 사용하여 개체를 문자열로 변환한 다음, replace() 함수를 사용하여 \"\\\"로 바꿉니다. 예시:

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

    자세한 내용은 샘플 템플릿을 참조하세요.

  • environmentVariables: 스크립트에 전달할 환경 변수를 지정합니다. 자세한 내용은 배포 스크립트 개발을 참조하세요.

  • scriptContent: 스크립트 콘텐츠를 지정합니다. 외부 스크립트를 실행하려면 primaryScriptUri를 대신 사용합니다. 예를 보려면 인라인 스크립트 사용외부 스크립트 사용을 참조하세요.

  • primaryScriptUri: 지원되는 파일 확장명을 사용하여 기본 배포 스크립트에 공개적으로 액세스할 수 있는 URL을 지정합니다. 자세한 내용은 외부 스크립트 사용을 참조하세요.

  • supportingScriptUris: scriptContent 또는 primaryScriptUri에서 호출되는 지원 파일에 공개적으로 액세스할 수 있는 URL 배열을 지정합니다. 자세한 내용은 외부 스크립트 사용을 참조하세요.

  • timeout: ISO 8601 형식에 지정된 최대 허용 스크립트 실행 시간을 지정합니다. 기본값은 P1D입니다.

  • cleanupPreference. 스크립트 실행이 터미널 상태에 있을 때 지원되는 두 가지 배포 리소스, 스토리지 계정 및 컨테이너 인스턴스를 정리하는 기본 설정을 지정합니다. 기본 설정은 항상이며 이는 터미널 상태(성공, 실패, 취소됨)에도 불구하고 지원 리소스를 삭제함을 의미합니다. 자세한 내용은 배포 스크립트 리소스 정리를 참조하세요.

  • retentionInterval: 배포 스크립트 실행이 터미널 상태에 도달하면 서비스에서 배포 스크립트 리소스를 유지하는 간격을 지정합니다. 이 기간이 만료되면 배포 스크립트 리소스가 삭제됩니다. 기간은 ISO 8601 패턴을 기반으로 합니다. 보존 간격은 1~26시간(PT26H)입니다. 이 속성은 cleanupPreferenceOnExpiration으로 설정된 경우 사용됩니다. 자세한 내용은 배포 스크립트 리소스 정리를 참조하세요.

추가 샘플

  • 샘플 1: 주요 자격 증명 모음을 만들고 배포 스크립트를 사용하여 키 자격 증명 모음에 인증서를 할당합니다.
  • 샘플 2: 구독 수준에서 리소스 그룹을 만들고 리소스 그룹에 키 자격 증명 모음을 만든 다음, 배포 스크립트를 사용하여 키 자격 증명 모음에 인증서를 할당합니다.
  • 샘플 3: 사용자 할당 관리 ID를 만들고, 리소스 그룹 수준에서 ID에 참가자 역할을 할당하고, 주요 자격 증명 모음을 만든 다음, 배포 스크립트를 사용하여 인증서를 주요 자격 증명 모음에 할당합니다.
  • 샘플 4: 이 목록의 샘플 1과 동일한 시나리오입니다. 배포 스크립트를 실행할 새 리소스 그룹이 만들어집니다. 이 템플릿은 구독 수준 템플릿입니다.
  • 샘플 5: 샘플 4와 동일한 시나리오입니다. 이 템플릿은 리소스 그룹 수준 템플릿입니다.
  • 샘플 6: 사용자 할당 관리 ID를 수동으로 만들고 Microsoft Graph API를 사용하여 Microsoft Entra 애플리케이션을 만들 수 있는 권한을 할당합니다. ARM 템플릿에서 배포 스크립트를 사용하여 Microsoft Entra 애플리케이션 및 서비스 주체를 만들고 개체 ID 및 클라이언트 ID를 출력합니다.

인라인 스크립트 사용

다음 템플릿에는 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을 연 후 다음 코드를 셸 창에 붙여넣습니다.

$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 템플릿 배포 스크립트 Hello World 출력의 스크린샷

외부 스크립트 사용

인라인 스크립트 외에 외부 스크립트 파일도 사용할 수 있습니다. 파일 확장명이 ps1인 기본 PowerShell 스크립트만 지원됩니다. CLI 스크립트의 경우 스크립트가 유효한 Bash 스크립트이면 기본 스크립트에 모든 확장명을 사용할 수 있으며 확장명을 사용하지 않을 수도 있습니다. 외부 스크립트 파일을 사용하려면 scriptContentprimaryScriptUri로 바꿉니다. 예시:

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

자세한 내용은예제 템플릿을 참조하세요.

외부 스크립트 파일에 액세스할 수 있어야 합니다. Azure Storage 계정에 저장된 스크립트 파일을 보호하려면 SAS 토큰을 생성하여 템플릿의 URI에 포함합니다. 배포를 완료할 만큼 충분한 여유를 두고 만료 기간을 설정합니다. 자세한 내용은 SAS 토큰을 사용하여 개인 ARM 템플릿 배포를 참조하세요.

배포 스크립트에서 참조하는 스크립트 primaryScriptUri 또는 supportingScriptUris의 무결성을 확인해야 합니다. 신뢰하는 스크립트만 참조하세요.

지원 스크립트 사용

복잡한 논리를 하나 이상의 지원 스크립트 파일로 분리할 수 있습니다. 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 Storage 방화벽 및 가상 네트워크 구성을 참조하세요.

  • 배포 주체에는 스토리지 계정을 관리할 수 있는 사용 권한이 있어야 합니다. 여기에는 파일 공유 읽기, 만들기, 삭제가 포함됩니다.

기존 스토리지 계정을 지정하려면 Microsoft.Resources/deploymentScripts의 속성 요소에 다음 JSON을 추가합니다.

"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 N
AZ_SCRIPTS_CLEANUP_PREFERENCE OnExpiration N
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/ N

AZ_SCRIPTS_OUTPUT_PATH 사용에 대한 자세한 내용은 CLI 스크립트에서 출력 작업을 참조하세요.

배포 스크립트에 보안 문자열 전달

컨테이너 인스턴스에서 환경 변수(EnvironmentVariable)를 설정하면 컨테이너가 실행하는 애플리케이션 또는 스크립트의 동적 구성을 제공할 수 있습니다. 배포 스크립트는 Azure Container Instance와 동일한 방식으로 비보안 및 보안 환경 변수를 처리합니다. 자세한 내용은 컨테이너 인스턴스에서 환경 변수 설정을 참조하세요. 예제는 샘플 템플릿을 참조하세요.

환경 변수에 대해 허용되는 최대 크기는 64KB입니다.

배포 스크립트 모니터링 및 문제 해결

스크립트 서비스는 스크립트 실행을 위한 스토리지 계정(기존 스토리지 계정을 지정하지 않는 경우) 및 컨테이너 인스턴스를 만듭니다. 이러한 리소스는 스크립트 서비스에서 자동으로 생성되는 경우 리소스 이름에 azscripts 접미사가 붙습니다.

Resource Manager 템플릿 배포 스크립트 리소스 이름의 스크린샷

사용자 스크립트, 실행 결과 및 stdout 파일은 스토리지 계정의 파일 공유에 저장됩니다. azscripts라는 폴더가 있습니다. 이 폴더에는 입력 및 출력 파일용 두 개의 폴더 azscriptinputazscriptoutput이 있습니다.

출력 폴더에는 executionresult.json 및 스크립트 출력 파일이 포함되어 있습니다. executionresult.json에서 스크립트 실행 오류 메시지를 볼 수 있습니다. 출력 파일은 스크립트가 성공적으로 실행되는 경우에만 생성됩니다. 입력 폴더에는 시스템 PowerShell 스크립트 파일과 사용자 배포 스크립트 파일이 포함되어 있습니다. 사용자 배포 스크립트 파일을 수정된 파일로 바꾸고 Azure 컨테이너 인스턴스에서 배포 스크립트를 다시 실행할 수 있습니다.

Azure Portal 사용

배포 스크립트 리소스를 배포한 후 리소스는 Azure Portal의 리소스 그룹 아래에 나열됩니다. 다음 스크린샷은 배포 스크립트 리소스의 개요 페이지를 보여 줍니다.

Resource Manager 템플릿 배포 스크립트 포털 개요의 스크린샷

개요 페이지에는 프로 비전 상태, 스토리지 계정, 컨테이너 인스턴스로그와 같은 리소스에 대한 몇 가지 중요한 정보가 표시됩니다.

왼쪽 메뉴에서 배포 스크립트 콘텐츠, 스크립트에 전달된 인수 및 출력을 볼 수 있습니다. 배포 스크립트를 포함하여 배포 스크립트에 대한 템플릿을 내보낼 수도 있습니다.

PowerShell 사용

Azure PowerShell을 사용하여 구독 또는 리소스 그룹 범위에서 배포 스크립트를 관리할 수 있습니다.

Get-AzDeploymentScript는 다음과 유사하게 출력됩니다.

Name                : runPowerShellInlineWithOutput
Id                  : /subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/myds0618rg/providers/Microsoft.Resources/deploymentScripts/runPowerShellInlineWithOutput
ResourceGroupName   : myds0618rg
Location            : centralus
SubscriptionId      : 01234567-89AB-CDEF-0123-456789ABCDEF
ProvisioningState   : Succeeded
Identity            : /subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/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/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/myds0618rg/providers/Microsoft.Storage/storageAccounts/ftnlvo6rlrvo2azscripts
ContainerInstanceId : /subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/myds0618rg/providers/Microsoft.ContainerInstance/containerGroups/ftnlvo6rlrvo2azscripts
Outputs             :
                      Key                 Value
                      ==================  ==================
                      text                Hello John Dole

RetentionInterval   : P1D
Timeout             : PT1H

Azure CLI 사용

Azure CLI를 사용하여 구독 또는 리소스 그룹 범위에서 배포 스크립트를 관리할 수 있습니다.

List 명령 출력은 다음과 유사합니다.

[
  {
    "arguments": "'foo' 'bar'",
    "azCliVersion": "2.40.0",
    "cleanupPreference": "OnExpiration",
    "containerSettings": {
      "containerGroupName": null
    },
    "environmentVariables": null,
    "forceUpdateTag": "20231101T163748Z",
    "id": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/myds0624rg/providers/Microsoft.Resources/deploymentScripts/runBashWithOutputs",
    "identity": {
      "tenantId": "01234567-89AB-CDEF-0123-456789ABCDEF",
      "type": "userAssigned",
      "userAssignedIdentities": {
        "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/myidentity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myuami": {
          "clientId": "01234567-89AB-CDEF-0123-456789ABCDEF",
          "principalId": "01234567-89AB-CDEF-0123-456789ABCDEF"
        }
      }
    },
    "kind": "AzureCLI",
    "location": "centralus",
    "name": "runBashWithOutputs",
    "outputs": {
      "Result": [
        {
          "id": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/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/01234567-89AB-CDEF-0123-456789ABCDEF/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/01234567-89AB-CDEF-0123-456789ABCDEF/resourcegroups/myrg/providers/microsoft.resources/deploymentScripts/myDeployementScript?api-version=2020-10-01

는 다음과 유사하게 출력됩니다.

{
  "kind": "AzurePowerShell",
  "identity": {
    "type": "userAssigned",
    "tenantId": "01234567-89AB-CDEF-0123-456789ABCDEF",
    "userAssignedIdentities": {
      "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/myidentity1008rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myuami": {
        "principalId": "01234567-89AB-CDEF-0123-456789ABCDEF",
        "clientId": "01234567-89AB-CDEF-0123-456789ABCDEF"
      }
    }
  },
  "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/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/myds0624rg/providers/Microsoft.ContainerInstance/containerGroups/64lxews2qfa5uazscripts",
      "storageAccountId": "/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/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/01234567-89AB-CDEF-0123-456789ABCDEF/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: 스크립트 실행이 터미널 상태가 되면 두 지원 리소스의 정리 기본 설정을 지정합니다. 지원되는 값은 다음과 같습니다.

    • 항상: 스크립트 실행이 터미널 상태가 되면 두 지원 리소스를 삭제합니다. 기존 스토리지 계정이 사용되는 경우 스크립트 서비스는 서비스에서 생성된 파일 공유를 삭제합니다. 지원 리소스 정리 후 deploymentScripts 리소스가 계속 존재할 수 있기 때문에 스크립트 서비스는 리소스를 삭제하기 전에 스크립트 실행 결과(예: stdout, 출력, 값 반환 등)를 유지합니다.

    • OnSuccess: 스크립트가 성공적으로 실행되는 경우에만 두 지원 리소스를 삭제합니다. 기존 스토리지 계정이 사용되는 경우 스크립트 서비스는 스크립트 실행에 성공한 경우에만 파일 공유를 제거합니다.

      스크립트 실행이 성공하지 못하면 스크립트 서비스는 지원 리소스를 정리한 다음, 배포 스크립트 리소스를 정리하기 전에 retentionInterval이 만료될 때까지 기다립니다.

    • OnExpiration: retentionInterval 설정이 만료된 경우에만 두 지원 리소스를 삭제합니다. 기존 스토리지 계정이 사용되는 경우 스크립트 서비스는 파일 공유를 제거하지만 스토리지 계정은 유지합니다.

    컨테이너 인스턴스 및 스토리지 계정은 cleanupPreference에 따라 삭제됩니다. 그러나 스크립트가 실패하고 cleanupPreference항상으로 설정되어 있지 않은 경우 배포 프로세스는 자동으로 컨테이너를 1시간 동안 또는 컨테이너가 정리될 때까지 계속 실행합니다. 이 시간 동안 스크립트 문제를 해결할 수 있습니다. 배포에 성공한 후에도 컨테이너를 계속 실행하려면 스크립트에 절전 단계를 추가하세요. 예를 들어 스크립트 끝에 시작-절전을 추가합니다. 절전 단계를 추가하지 않으면 컨테이너는 터미널 상태로 설정되며 아직 삭제되지 않은 경우에도 액세스할 수 없습니다.

  • retentionInterval: deploymentScript 리소스가 유지되고 만료 및 삭제되기 전까지의 시간 간격을 지정합니다.

참고 항목

스크립트 서비스에 의해 생성되는 스토리지 계정 및 컨테이너 인스턴스는 다른 용도로 사용하지 않는 것이 좋습니다. 스크립트 수명 주기에 따라 두 리소스가 제거될 수 있습니다.

CanNotDelete 잠금이 있는 리소스 그룹에 배포 스크립트를 배포하는 경우 자동으로 만든 스토리지 계정 및 컨테이너 인스턴스를 삭제할 수 없습니다. 이 문제를 해결하려면 잠금이 없는 다른 리소스 그룹에 배포 스크립트를 배포하면 됩니다. 샘플 템플릿에서 샘플 4와 샘플 5를 참조하세요.

스크립트를 두 번 이상 실행

배포 스크립트 실행은 idempotent 작업입니다. deploymentScripts 리소스 속성(인라인 스크립트 포함)이 변경되지 않은 경우 템플릿을 다시 배포할 때 스크립트가 실행되지 않습니다. 배포 스크립트 서비스는 템플릿의 리소스 이름을 같은 리소스 그룹에 있는 기존 리소스와 비교합니다. 동일한 배포 스크립트를 여러 번 실행하려는 경우 다음 두 가지 옵션이 있습니다.

  • deploymentScripts 리소스 그룹의 이름을 바꿉니다. 예를 들어 리소스 이름 또는 리소스 이름의 일부로 utcNow 템플릿 함수를 사용합니다. 리소스 이름을 변경하면 새 deploymentScripts 리소스가 생성됩니다. 스크립트 실행 기록을 보관하는 것이 좋습니다.

    참고 항목

    utcNow 함수는 매개 변수의 기본값에만 사용할 수 있습니다.

  • forceUpdateTag 템플릿 속성에 다른 값을 지정합니다. 예를 들어 값으로 utcNow를 사용합니다.

참고 항목

idempotent 배포 스크립트를 작성합니다. 이렇게 하면 실수로 다시 실행되는 경우 시스템이 변경되지 않습니다. 예를 들어 배포 스크립트를 사용하여 Azure 리소스를 만드는 경우 리소스를 만들기 전에 리소스가 존재하지 않는지 확인하므로 스크립트가 성공하거나 리소스를 다시 만들지 않습니다.

개발 환경 구성

배포 스크립트 개발 환경으로 미리 구성된 컨테이너 이미지를 사용할 수 있습니다. 자세한 내용은 템플릿에서 배포 스크립트에 대한 개발 환경 구성을 참조하세요.

스크립트를 성공적으로 테스트한 후에는 이 스크립트를 템플릿에서 배포 스크립트로 사용할 수 있습니다.

배포 스크립트 오류 코드

오류 코드 설명
DeploymentScriptInvalidOperation 템플릿의 배포 스크립트 리소스 정의에 잘못된 속성 이름이 있습니다.
DeploymentScriptResourceConflict 터미널 상태가 아닌 상태에 있는 배포 스크립트 리소스는 삭제할 수 없으며 실행이 1시간을 초과하지 않았습니다. 또는 동일한 리소스 식별자(동일한 구독, 리소스 그룹 이름 및 리소스 이름)를 사용하는 동일한 배포 스크립트를 다시 실행할 수는 없으며, 동시에 다른 스크립트 본문 콘텐츠가 있습니다.
DeploymentScriptOperationFailed 배포 스크립트 작업이 내부적으로 실패했습니다. Microsoft 지원에 문의하세요.
DeploymentScriptStorageAccountAccessKeyNotSpecified 기존 스토리지 계정에 대한 액세스 키를 지정하지 않았습니다.
DeploymentScriptContainerGroupContainsInvalidContainers 배포 스크립트 서비스에서 만든 컨테이너 그룹이 외부에서 수정되었으며 잘못된 컨테이너가 추가되었습니다.
DeploymentScriptContainerGroupInNonterminalState 둘 이상의 배포 스크립트 리소스가 동일한 리소스 그룹에서 동일한 Azure Container Instance 이름을 사용하며 그 중 하나는 아직 실행을 완료하지 않았습니다.
DeploymentScriptStorageAccountInvalidKind BlobBlobStorage 또는 BlobStorage 유형의 기존 스토리지 계정은 파일 공유를 지원하지 않으므로 사용할 수 없습니다.
DeploymentScriptStorageAccountInvalidKindAndSku 기존 스토리지 계정은 파일 공유를 지원하지 않습니다. 지원되는 스토리지 계정의 종류 목록은 기존 스토리지 계정 사용을 참조하세요.
DeploymentScriptStorageAccountNotFound 스토리지 계정이 존재하지 않거나 외부 프로세스 또는 도구에 의해 삭제되었습니다.
DeploymentScriptStorageAccountWithServiceEndpointEnabled 지정된 스토리지 계정에 서비스 엔드포인트가 있습니다. 서비스 엔드포인트가 포함된 스토리지 계정은 지원되지 않습니다.
DeploymentScriptStorageAccountInvalidAccessKey 기존 스토리지 계정에 지정된 액세스 키가 잘못되었습니다.
DeploymentScriptStorageAccountInvalidAccessKeyFormat 스토리지 계정 키 형식이 잘못되었습니다. 스토리지 계정 액세스 키 관리를 참조하세요.
DeploymentScriptExceededMaxAllowedTime 배포 스크립트 실행 시간이 배포 스크립트 리소스 정의에 지정된 시간 제한 값을 초과했습니다.
DeploymentScriptInvalidOutputs 배포 스크립트 출력이 올바른 JSON 개체가 아닙니다.
DeploymentScriptContainerInstancesServiceLoginFailure 사용자 할당 관리 ID를 1분 간격으로 10번 시도한 후에는 로그인할 수 없습니다.
DeploymentScriptContainerGroupNotFound 배포 스크립트 서비스에서 만든 컨테이너 그룹이 외부 도구나 프로세스에 의해 삭제되었습니다.
DeploymentScriptDownloadFailure 지원 스크립트를 다운로드하지 못했습니다. 지원 스크립트 사용을 참조하세요.
DeploymentScriptError 사용자 스크립트에서 예외가 발생했습니다.
DeploymentScriptBootstrapScriptExecutionFailed 부트스트랩 스크립트에서 오류가 발생했습니다. 부트스트랩 스크립트는 배포 스크립트 실행을 오케스트레이션하는 시스템 스크립트입니다.
DeploymentScriptExecutionFailed 배포 스크립트를 실행하는 동안 알 수 없는 오류가 발생했습니다.
DeploymentScriptContainerInstancesServiceUnavailable ACI(Azure Container Instance)를 만들 때 ACI에서 서비스를 사용할 수 없음 오류가 발생했습니다.
DeploymentScriptContainerGroupInNonterminalState ACI(Azure Container Instance)를 만들 때 다른 배포 스크립트는 동일한 범위(동일한 구독, 리소스 그룹 이름 및 리소스 이름)에서 동일한 ACI 이름을 사용합니다.
DeploymentScriptContainerGroupNameInvalid 지정된 ACI(Azure Container Instance)가 ACI 요구 사항을 충족하지 않습니다. Azure Container Instances에서 일반적인 문제 해결을 참조하세요.

배포 스크립트 내에서 Microsoft Graph 사용

배포 스크립트는 Microsoft Graph를 사용하여 Microsoft Entra ID에서 개체를 만들고 작업할 수 있습니다.

명령

Azure CLI 배포 스크립트를 사용하는 경우 az ad 명령 그룹 내의 명령을 사용하여 애플리케이션, 서비스 주체, 그룹 및 사용자로 작업할 수 있습니다. az rest 명령을 사용하여 Microsoft Graph API를 직접 호출할 수도 있습니다.

Azure PowerShell 배포 스크립트를 사용하는 경우 Invoke-RestMethod cmdlet을 사용하여 Microsoft Graph API를 직접 호출할 수 있습니다.

사용 권한

배포 스크립트에서 사용하는 ID는 Microsoft Graph API로 작업할 수 있는 권한을 부여하고 수행하는 작업에 적절한 권한을 부여해야 합니다. 사용자가 할당한 관리 ID를 미리 만들고 Microsoft Graph에 대한 앱 역할을 할당하는 등 템플릿 배포 외부에서 ID에 권한을 부여해야 합니다. 자세한 내용은 이 빠른 시작 예제를 참조하세요.

프라이빗 가상 네트워크에 액세스

Microsoft.Resources/deploymentScripts 버전 2023-08-01을 사용하면 몇 가지 추가 구성을 사용하여 프라이빗 네트워크에서 배포 스크립트를 실행할 수 있습니다.

  • 사용자가 할당한 관리 ID를 만들고 identity 속성에 지정합니다. ID를 할당하려면 ID를 참조하세요.

  • allowSharedKeyAccesstrue로 설정하여 스토리지 계정을 만들고 기존 스토리지 계정을 사용하도록 배포 스크립트를 지정합니다. 기존 스토리지 계정을 지정하려면 기존 스토리지 계정 사용을 참조하세요. 스토리지 계정에는 몇 가지 추가 구성이 필요합니다.

    1. Azure Portal에서 스토리지 계정을 엽니다.

    2. 왼쪽 메뉴에서 액세스 제어(IAM)를 선택하고 역할 할당 탭을 선택합니다.

    3. 사용자 할당 관리 ID에 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"
      }
    }
  ]
}

다음 단계

이 문서에서는 배포 스크립트를 사용하는 방법을 알아보았습니다. 배포 스크립트 자습서는 다음을 참조하세요.