使用 ARM 模板测试工具包
Azure 资源管理器模板(ARM 模板)测试工具包检查模板是否使用建议的做法。 如果模板不符合建议的做法,它将返回包含建议的更改的警告列表。 通过使用测试工具包,可以了解如何避免模板开发中的常见问题。 本文介绍如何运行测试工具包以及如何添加或删除测试。 有关如何运行测试或如何运行特定测试的详细信息,请参阅测试参数。
工具包是一组可从 PowerShell 或 CLI 中的命令运行的 PowerShell 脚本。 这些测试是建议,而不是要求。 你可以确定哪些测试与目标相关,并自定义要运行哪些测试。
该工具包包含四组测试:
注意
测试工具包仅适用于 ARM 模板。 若要验证 Bicep 文件,请使用 Bicep linter。
在 Windows 上安装
如果还没有 PowerShell,请在 Windows 上安装 PowerShell。
下载测试工具包的最新 .zip 文件,并将其解压缩。
启动 PowerShell。
导航到在其中解压缩测试工具包的文件夹。 在该文件夹中,导航到 arm-ttk 文件夹。
如果执行策略阻止来自 Internet 的脚本,则需要取消阻止脚本文件。 请确保处于 arm-ttk 文件夹中。
Get-ChildItem *.ps1, *.psd1, *.ps1xml, *.psm1 -Recurse | Unblock-File
导入模块。
Import-Module .\arm-ttk.psd1
若要运行测试,请使用以下命令:
Test-AzTemplate -TemplatePath \path\to\template
在 Linux 上安装
如果还没有 PowerShell,请在 Linux 上安装 PowerShell。
下载测试工具包的最新 .zip 文件,并将其解压缩。
启动 PowerShell。
pwsh
导航到在其中解压缩测试工具包的文件夹。 在该文件夹中,导航到 arm-ttk 文件夹。
如果执行策略阻止来自 Internet 的脚本,则需要取消阻止脚本文件。 请确保处于 arm-ttk 文件夹中。
Get-ChildItem *.ps1, *.psd1, *.ps1xml, *.psm1 -Recurse | Unblock-File
导入模块。
Import-Module ./arm-ttk.psd1
若要运行测试,请使用以下命令:
Test-AzTemplate -TemplatePath /path/to/template
在 macOS 上安装
如果还没有 PowerShell,请在 macOS 上安装 PowerShell。
安装
coreutils
:brew install coreutils
下载测试工具包的最新 .zip 文件,并将其解压缩。
启动 PowerShell。
pwsh
导航到在其中解压缩测试工具包的文件夹。 在该文件夹中,导航到 arm-ttk 文件夹。
如果执行策略阻止来自 Internet 的脚本,则需要取消阻止脚本文件。 请确保处于 arm-ttk 文件夹中。
Get-ChildItem *.ps1, *.psd1, *.ps1xml, *.psm1 -Recurse | Unblock-File
导入模块。
Import-Module ./arm-ttk.psd1
若要运行测试,请使用以下命令:
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
若要测试该文件夹中的某个文件,请添加 -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 文件。
该工具包有四个文件夹,其中包含针对特定文件类型运行的默认测试:
- 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。
测试可以获取模板作为对象参数或字符串参数。 通常使用其中一种参数,但也可以同时使用两种。
需要获取模板的一部分并循环访问其属性时,请使用 object 参数。 使用 object 参数的测试采用以下格式:
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
获取参数的集合。
如果需要对整个模板执行字符串操作,请使用 string 参数。 使用 string 参数的测试采用以下格式:
param(
[Parameter(Mandatory)]
[string]
$TemplateText
)
# Implement test logic that performs string operations.
# Output error with: Write-Error -Message
例如,可以运行字符串参数的正则表达式,以查看是否使用了特定语法。
若要了解有关实施测试的更多信息,请查看该文件夹中的其他测试。
验证 Azure 市场的模板
若要将产品/服务发布到 Azure 市场,请使用测试工具包验证模板。 当模板通过验证测试后,Azure 市场会更快地批准该产品/服务。 如果未通过测试,产品/服务将认证失败。
重要
市场测试已于 2022 年 7 月增加。 如果为早期版本,请更新模块。
在环境中运行测试
安装工具包并导入模块后,运行以下 cmdlet 测试包:
Test-AzMarketplacePackage -TemplatePath "Path to the unzipped package folder"
解释结果
测试结果分两部分返回。 第一部分包括强制性测试。 这些测试的结果显示在总结部分。
重要
必须修复所有红色的结果,才能接受市场产品/服务。 建议修复返回的所有黄色结果。
文本结果为:
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 市场之前,请确保没有错误。
与 Azure Pipelines 集成
可以将测试工具包添加到 Azure Pipelines。 使用管道,可以在每次更新模板时运行测试,也可以在部署过程中运行测试。
将测试工具包添加到管道的最简单的方法是利用第三方扩展。 提供以下两个扩展:
或者,你可以执行自己的任务。 以下示例演示如何下载测试工具包。
对于发布管道:
{
"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
后续步骤
- 若要了解模板测试,请参阅 ARM 模板的测试用例。
- 若要测试参数文件,请参阅参数文件的测试用例。
- 有关 createUiDefinition 测试,请参阅 createUiDefinition.json 的测试用例。
- 若要了解所有文件的测试,请参阅所有文件的测试用例。
- 有关涉及到使用测试工具包的学习模块,请参阅使用 ARM 模板测试工具包验证 Azure 资源。