ARM 템플릿 테스트 도구 키트 사용

Azure Resource Manager 템플릿(ARM 템플릿) 테스트 도구 키트는 템플릿에서 권장 사례를 사용하는지 여부를 확인합니다. 템플릿이 권장 사례를 준수하지 않는 경우 제안된 변경 내용과 함께 경고 목록을 반환합니다. 테스트 도구 키트를 사용하여 템플릿 개발에서 일반적인 문제를 방지하는 방법을 배울 수 있습니다. 이 문서에서는 테스트 도구 키트를 실행하는 방법 및 테스트를 추가 또는 제거하는 방법을 설명합니다. 테스트를 실행하는 방법 또는 특정 테스트를 실행하는 방법에 대한 자세한 내용은 테스트 매개 변수를 참조하세요.

도구 키트는 PowerShell 또는 CLI의 명령에서 실행할 수 있는 PowerShell 스크립트 집합입니다. 이러한 테스트는 권장 사항이며, 요구 사항이 아닙니다. 목표와 관련된 테스트를 결정하고 실행되는 테스트를 사용자 지정할 수 있습니다.

이 도구 키트에는 네 가지 테스트 집합이 포함되어 있습니다.

참고 항목

테스트 도구 모음은 ARM 템플릿에서만 사용할 수 있습니다. Bicep 파일의 유효성을 검사하려면 Bicep linter를 사용합니다.

학습 리소스

ARM 템플릿 테스트 도구에 대한 자세한 내용과 실습 지침은 ARM 템플릿 테스트 도구 키트를 사용하여 Azure 리소스 유효성 검사를 참조하세요.

Windows에 설치

  1. PowerShell이 아직 없는 경우 Windows에 PowerShell을 설치합니다.

  2. 테스트 도구 키트에 대한 최신 .zip 파일을 다운로드하고 압축을 풉니다.

  3. PowerShell을 시작합니다.

  4. 테스트 도구 키트를 추출한 폴더로 이동합니다. 해당 폴더 내에서 arm-ttk 폴더로 이동합니다.

  5. 실행 정책이 인터넷에서 스크립트를 차단하는 경우 스크립트 파일의 차단을 해제해야 합니다. arm-ttk 폴더에 있는지 확인하십시오.

    Get-ChildItem *.ps1, *.psd1, *.ps1xml, *.psm1 -Recurse | Unblock-File
    
  6. 모듈을 가져옵니다.

    Import-Module .\arm-ttk.psd1
    
  7. 테스트를 실행하려면 다음 명령을 사용합니다.

    Test-AzTemplate -TemplatePath \path\to\template
    

Linux에 설치

  1. PowerShell이 아직 없는 경우 Linux에 PowerShell을 설치합니다.

  2. 테스트 도구 키트에 대한 최신 .zip 파일을 다운로드하고 압축을 풉니다.

  3. PowerShell을 시작합니다.

    pwsh
    
  4. 테스트 도구 키트를 추출한 폴더로 이동합니다. 해당 폴더 내에서 arm-ttk 폴더로 이동합니다.

  5. 실행 정책이 인터넷에서 스크립트를 차단하는 경우 스크립트 파일의 차단을 해제해야 합니다. arm-ttk 폴더에 있는지 확인하십시오.

    Get-ChildItem *.ps1, *.psd1, *.ps1xml, *.psm1 -Recurse | Unblock-File
    
  6. 모듈을 가져옵니다.

    Import-Module ./arm-ttk.psd1
    
  7. 테스트를 실행하려면 다음 명령을 사용합니다.

    Test-AzTemplate -TemplatePath /path/to/template
    

macOS에 설치

  1. PowerShell이 아직 없는 경우 macOS에 PowerShell을 설치합니다.

  2. coreutils 설치:

    brew install coreutils
    
  3. 테스트 도구 키트에 대한 최신 .zip 파일을 다운로드하고 압축을 풉니다.

  4. PowerShell을 시작합니다.

    pwsh
    
  5. 테스트 도구 키트를 추출한 폴더로 이동합니다. 해당 폴더 내에서 arm-ttk 폴더로 이동합니다.

  6. 실행 정책이 인터넷에서 스크립트를 차단하는 경우 스크립트 파일의 차단을 해제해야 합니다. arm-ttk 폴더에 있는지 확인하십시오.

    Get-ChildItem *.ps1, *.psd1, *.ps1xml, *.psm1 -Recurse | Unblock-File
    
  7. 모듈을 가져옵니다.

    Import-Module ./arm-ttk.psd1
    
  8. 테스트를 실행하려면 다음 명령을 사용합니다.

    Test-AzTemplate -TemplatePath /path/to/template
    

결과 형식

통과한 테스트는 녹색으로 표시되고 앞에 [+]가 붙습니다.

실패한 테스트는 빨간색으로 표시되고 앞에 [-]가 붙습니다.

경고가 있는 테스트는 노란색으로 표시되고 앞에 [?]가 붙습니다.

Screenshot of test results in different colors for pass, fail, and warning.

텍스트 결과는 다음과 같습니다.

deploymentTemplate
[+] adminUsername Should Not Be A Literal (6 ms)
[+] apiVersions Should Be Recent In Reference Functions (9 ms)
[-] apiVersions Should Be Recent (6 ms)
    Api versions must be the latest or under 2 years old (730 days) - API version 2019-06-01 of
    Microsoft.Storage/storageAccounts is 760 days old
    Valid Api Versions:
    2021-04-01
    2021-02-01
    2021-01-01
    2020-08-01-preview

[+] artifacts parameter (4 ms)
[+] CommandToExecute Must Use ProtectedSettings For Secrets (9 ms)
[+] DependsOn Best Practices (5 ms)
[+] Deployment Resources Must Not Be Debug (6 ms)
[+] DeploymentTemplate Must Not Contain Hardcoded Uri (4 ms)
[?] DeploymentTemplate Schema Is Correct (6 ms)
    Template is using schema version '2015-01-01' which has been deprecated and is no longer
    maintained.

테스트 매개 변수

-TemplatePath 매개 변수를 제공하는 경우 도구 키트는 해당 폴더에서 azuredeploy.json 또는 maintemplate.json이라는 이름의 템플릿을 찾습니다. 이 템플릿을 먼저 테스트한 다음 폴더와 해당 하위 폴더에 있는 다른 모든 템플릿을 테스트합니다. 다른 템플릿은 연결된 템플릿으로 테스트됩니다. 경로에 createUiDefinition.json이라는 파일이 포함된 경우 UI 정의와 관련된 테스트를 실행합니다. 매개 변수 파일과 폴더의 모든 JSON 파일에 대해서도 테스트가 실행됩니다.

Test-AzTemplate -TemplatePath $TemplateFolder

해당 폴더의 파일 하나를 테스트하려면 -File 매개 변수를 추가합니다. 그러나 폴더에는 여전히 azuredeploy.json 또는 maintemplate.json이라는 주 템플릿이 있어야 합니다.

Test-AzTemplate -TemplatePath $TemplateFolder -File cdn.json

기본값으로 모든 테스트가 실행됩니다. 실행할 개별 테스트를 지정하려면 -Test 매개 변수를 사용하고 테스트 이름을 제공합니다. 테스트 이름은 ARM 템플릿, 매개 변수 파일, createUiDefinition.json모든 파일을 참조하세요.

Test-AzTemplate -TemplatePath $TemplateFolder -Test "Resources Should Have Location"

테스트 사용자 지정

기본 테스트를 사용자 지정하거나 고유한 테스트를 작성할 수 있습니다. 테스트를 영구적으로 제거하려면 폴더에서 .test.ps1 파일을 삭제합니다.

이 도구 키트에는 특정 파일 형식에 대해 실행되는 기본 테스트가 포함된 4개의 폴더가 있습니다.

  • ARM 템플릿: \arm-ttk\testcases\deploymentTemplate
  • 매개 변수 파일: \arm-ttk\testcases\deploymentParameters
  • createUiDefinition.json: \arm-ttk\testcases\CreateUIDefinition
  • 모든 파일: \arm-ttk\testcases\AllFiles

사용자 지정 테스트 추가

사용자 고유의 테스트를 추가하려면 Your-Custom-Test-Name.test.ps1 명명 규칙을 사용하여 파일을 만듭니다.

테스트에서 템플릿을 개체 매개 변수 또는 문자열 매개 변수로 가져올 수 있습니다. 일반적으로는 둘 중 하나를 사용하지만 둘 다 사용할 수도 있습니다.

템플릿의 섹션을 가져와 해당 속성을 반복해야 하는 경우 개체 매개 변수를 사용합니다. 개체 매개 변수를 사용하는 테스트의 형식은 다음과 같습니다.

param(
  [Parameter(Mandatory=$true,Position=0)]
  [PSObject]
  $TemplateObject
)

# Implement test logic that evaluates parts of the template.
# Output error with: Write-Error -Message

템플릿 개체의 속성은 다음과 같습니다.

  • $schema
  • contentVersion
  • parameters
  • variables
  • resources
  • outputs

예를 들어 $TemplateObject.parameters를 사용하여 매개 변수 컬렉션을 가져올 수 있습니다.

전체 템플릿에서 문자열 작업을 수행해야 하는 경우 문자열 매개 변수를 사용합니다. 문자열 매개 변수를 사용하는 테스트의 형식은 다음과 같습니다.

param(
  [Parameter(Mandatory)]
  [string]
  $TemplateText
)

# Implement test logic that performs string operations.
# Output error with: Write-Error -Message

예를 들어 문자열 매개 변수의 정규식을 실행하여 특정 구문이 사용되는지 확인할 수 있습니다.

테스트 구현에 대한 자세한 내용을 알아보려면 해당 폴더의 다른 테스트를 살펴보세요.

Azure Marketplace용 템플릿 유효성 검사

Azure Marketplace에 제품을 게시하려면 테스트 도구 키트를 사용하여 템플릿의 유효성을 검사합니다. 템플릿이 유효성 검사 테스트를 통과하면 Azure Marketplace에서 제품을 더 빠르게 승인합니다. 테스트에 실패하면 제품은 인증에 실패합니다.

Important

Marketplace 테스트는 2022년 7월에 추가되었습니다. 이전 버전이 있는 경우 모듈을 업데이트합니다.

사용자 환경에서 테스트 실행

도구 키트를 설치하고 모듈을 가져온 후 다음 cmdlet을 실행하여 패키지를 테스트합니다.

Test-AzMarketplacePackage -TemplatePath "Path to the unzipped package folder"

결과 해석

테스트는 두 섹션의 결과를 반환합니다. 첫 번째 섹션에는 필수 테스트가 포함되어 있습니다. 이러한 테스트의 결과는 요약 섹션에 표시됩니다.

Important

Marketplace 제품이 수락되기 전에 결과를 빨간색으로 수정해야 합니다. 노란색으로 반환되는 결과를 수정하는 것이 좋습니다.

텍스트 결과는 다음과 같습니다.

Validating nestedtemplates\AzDashboard.json
    [+] adminUsername Should Not Be A Literal (210 ms)
    [+] artifacts parameter (3 ms)
    [+] CommandToExecute Must Use ProtectedSettings For Secrets (201 ms)
    [+] Deployment Resources Must Not Be Debug (160 ms)
    [+] DeploymentTemplate Must Not Contain Hardcoded Url (13 ms)
    [+] Location Should Not Be Hardcoded (31 ms)
    [+] Min and Max Value Are Numbers (4 ms)
    [+] Outputs Must Not Contain Secrets (9 ms)
    [+] Password params must be secure (3 ms)
    [+] Resources Should Have Location (2 ms)
    [+] Resources Should Not Be Ambiguous (2 ms)
    [+] Secure Params In Nested Deployments (205 ms)
    [+] Secure String Parameters Cannot Have Default (3 ms)
    [+] URIs Should Be Properly Constructed (190 ms)
    [+] Variables Must Be Referenced (9 ms)
    [+] Virtual Machines Should Not Be Preview (173 ms)
    [+] VM Size Should Be A Parameter (165 ms)
Pass : 99
Fail : 3
Total: 102
Validating StartStopV2mkpl_1.0.09302021\anothertemplate.json
    [?] Parameters Must Be Referenced (86 ms)
        Unreferenced parameter: resourceGroupName
        Unreferenced parameter: location
        Unreferenced parameter: azureFunctionAppName
        Unreferenced parameter: applicationInsightsName
        Unreferenced parameter: applicationInsightsRegion

요약 섹션 아래 섹션에는 경고로 해석될 수 있는 테스트 실패가 포함되어 있습니다. 오류 수정은 선택 사항이지만 매우 권장됩니다. 오류는 종종 고객이 제품을 설치할 때 오류를 일으키는 일반적인 문제를 가리킵니다.

테스트를 수정하려면 해당하는 테스트 사례를 따릅니다.

제품 제출

필요한 수정을 수행한 후 테스트 도구 키트를 다시 실행합니다. Azure Marketplace에 제품을 제출하기 전에 오류가 없는지 확인합니다.

Azure 파이프라인과 통합

Azure 파이프라인에 테스트 도구 키트를 추가할 수 있습니다. 파이프라인을 사용하면 템플릿이 업데이트 될 때마다 테스트를 실행하거나 배포 프로세스의 일부로 실행할 수 있습니다.

테스트 도구 키트를 파이프라인에 추가하는 가장 쉬운 방법은 타사 확장을 사용하는 것입니다. 사용할 수 있는 두 가지 확장은 다음과 같습니다.

또는 사용자 공유의 작업을 구현할 수 있습니다. 다음 예제에서 테스트 도구 키트를 다운로드하는 방법을 보여 줍니다.

릴리스 파이프라인의 경우:

{
  "environment": {},
  "enabled": true,
  "continueOnError": false,
  "alwaysRun": false,
  "displayName": "Download TTK",
  "timeoutInMinutes": 0,
  "condition": "succeeded()",
  "task": {
    "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
    "versionSpec": "2.*",
    "definitionType": "task"
  },
  "inputs": {
    "targetType": "inline",
    "filePath": "",
    "arguments": "",
    "script": "New-Item '$(ttk.folder)' -ItemType Directory\nInvoke-WebRequest -uri '$(ttk.uri)' -OutFile \"$(ttk.folder)/$(ttk.asset.filename)\" -Verbose\nGet-ChildItem '$(ttk.folder)' -Recurse\n\nWrite-Host \"Expanding files...\"\nExpand-Archive -Path '$(ttk.folder)/*.zip' -DestinationPath '$(ttk.folder)' -Verbose\n\nWrite-Host \"Expanded files found:\"\nGet-ChildItem '$(ttk.folder)' -Recurse",
    "errorActionPreference": "stop",
    "failOnStderr": "false",
    "ignoreLASTEXITCODE": "false",
    "pwsh": "true",
    "workingDirectory": ""
  }
}

파이프라인 YAML 정의의 경우:

- pwsh: |
   New-Item '$(ttk.folder)' -ItemType Directory
   Invoke-WebRequest -uri '$(ttk.uri)' -OutFile "$(ttk.folder)/$(ttk.asset.filename)" -Verbose
   Get-ChildItem '$(ttk.folder)' -Recurse
   
   Write-Host "Expanding files..."
   Expand-Archive -Path '$(ttk.folder)/*.zip' -DestinationPath '$(ttk.folder)' -Verbose
   
   Write-Host "Expanded files found:"
   Get-ChildItem '$(ttk.folder)' -Recurse
  displayName: 'Download TTK'

다음 예제는 테스트를 실행하는 방법을 보여줍니다.

릴리스 파이프라인의 경우:

{
  "environment": {},
  "enabled": true,
  "continueOnError": true,
  "alwaysRun": false,
  "displayName": "Run Best Practices Tests",
  "timeoutInMinutes": 0,
  "condition": "succeeded()",
  "task": {
    "id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
    "versionSpec": "2.*",
    "definitionType": "task"
  },
  "inputs": {
    "targetType": "inline",
    "filePath": "",
    "arguments": "",
    "script": "Import-Module $(ttk.folder)/arm-ttk/arm-ttk.psd1 -Verbose\n$testOutput = @(Test-AzTemplate -TemplatePath \"$(sample.folder)\")\n$testOutput\n\nif ($testOutput | ? {$_.Errors }) {\n   exit 1 \n} else {\n    Write-Host \"##vso[task.setvariable variable=result.best.practice]$true\"\n    exit 0\n} \n",
    "errorActionPreference": "continue",
    "failOnStderr": "true",
    "ignoreLASTEXITCODE": "false",
    "pwsh": "true",
    "workingDirectory": ""
  }
}

파이프라인 YAML 정의의 경우:

- pwsh: |
   Import-Module $(ttk.folder)/arm-ttk/arm-ttk.psd1 -Verbose
   $testOutput = @(Test-AzTemplate -TemplatePath "$(sample.folder)")
   $testOutput
   
   if ($testOutput | ? {$_.Errors }) {
      exit 1 
   } else {
       Write-Host "##vso[task.setvariable variable=result.best.practice]$true"
       exit 0
   } 
  errorActionPreference: continue
  failOnStderr: true
  displayName: 'Run Best Practices Tests'
  continueOnError: true

다음 단계