ARM テンプレート テスト ツールキットを使用する

Azure Resource Manager テンプレート (ARM テンプレート) テスト ツールキットでは、推奨される方法がテンプレートで使用されているかどうかが確認されます。 テンプレートが推奨されるプラクティスに準拠していない場合は、推奨される変更を含む警告の一覧が返されます。 テスト ツールキットを使用すると、テンプレートの開発での一般的な問題を回避する方法がわかります。 この記事では、テスト ツールキットを実行する方法と、テストを追加または削除する方法について説明します。 テストを実行する方法、または特定のテストを実行する方法の詳細については、「テスト パラメーター」を参照してください。

ツールキットは、PowerShell または CLI のコマンドから実行できる一連の PowerShell スクリプトです。 これらのテストは推奨されるものですが、必須ではありません。 自分の目標に関連するテストを決定し、実行するテストをカスタマイズできます。

このツールキットには、次の 4 つのテスト セットが含まれています。

Note

このテスト ツールキットを使用できるのは、ARM テンプレートに対してのみです。 Bicep ファイルを検証するには、Bicep リンターを使用します。

トレーニング リソース

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
    

結果の形式

合格になったテストは緑色で表示され、前に [+] が付きます。

不合格になったテストは赤色で表示され、前に [-] が付きます。

警告が付いたテストは黄色で表示され、前に [?] が付きます。

成功、失敗、警告を異なる色で表した、テスト結果ページのスクリーンショット。

テキストの結果は次のようになります。

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

そのフォルダー内の 1 つのファイルをテストするには、-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

カスタム テストを追加する

独自のテストを追加するには、次の名前付け規則に従ってファイルを作成します: <カスタム テスト名>.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 でより迅速にオファリングが承認されます。 テストに失敗した場合、そのオファリングは認定で不合格となります。

重要

Marketplace テストは 2022 年 7 月に追加されました。 それ以前のバージョンがある場合は、モジュールを更新してください。

環境内でテストを実行する

ツールキットをインストールしてモジュールをインポートした後、次のコマンドレットを実行してパッケージをテストします。

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

結果を解釈する

テストは 2 つのセクションで結果を返します。 最初のセクションには、必須のテストが含まれています。 これらのテストの結果が概要セクションに表示されます。

重要

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 Pipelines と統合する

テスト ツールキットを Azure パイプラインに追加できます。 パイプラインを使用すると、テンプレートが更新されるたびにテストを実行したり、デプロイ プロセスの一部として実行したりできます。

テスト ツールキットをパイプラインに追加する最も簡単な方法は、サードパーティ製の拡張機能を使用することです。 次の 2 つの拡張機能を使用できます。

または、独自のタスクを実装することもできます。 次の例では、テスト ツールキットをダウンロードする方法を示します。

リリース パイプラインの場合:

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

次のステップ