共用方式為


ARM 範本的測試案例

本文說明使用適用於 Azure Resource Manager 範本的 範本測試工具組執行的測試 (ARM 範本)。 它提供 通過失敗 測試的範例,並包含每個測試的名稱。 如需如何執行測試或如何執行特定測試的詳細資訊,請參閱 測試參數

使用正確的結構描述

測試名稱: DeploymentTemplate 架構正確

請務必在範本中指定有效的結構描述值。

下列範例 失敗 ,因為架構無效。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-01-01/deploymentTemplate.json#",
}

下列範例會顯示 警告 ,因為架構版本 2015-01-01 已被取代且不會維護。

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
}

下列範例會使用有效的架構 傳遞

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
}

範本的 schema 屬性必須設為下列其中一個架構描述:

  • https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#
  • https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#
  • https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#
  • https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json#
  • https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json

必須使用宣告參數

測試名稱:參數必須被引用

此項測試會尋找未用於範本或有效運算式中的參數。

若要減少範本中的混淆情形,請刪除已定義但未使用的參數。 由於您不需提供不必要的值,因此排除未使用的參數可簡化範本部署。

在 Bicep 中,使用 Linter 規則 - 沒有未使用的參數

下列範例 會失敗 ,因為參考參數的表達式遺漏前置方括弧 ([)。

"resources": [
  {
    "location": " parameters('location')]"
  }
]

下列範例 會傳遞 ,因為表達式有效。

"resources": [
  {
    "location": "[parameters('location')]"
  }
]

安全參數不能有硬式編碼之預設

測試名稱: 安全字串參數不能有預設值

請勿在您的範本中提供安全參數的硬式編碼預設值。 安全參數可以有空字串做為預設值,或在表達式中使用 newGuid 函式。

您可以使用類型 secureStringsecureObject 包含敏感性值(例如密碼)的參數。 當參數使用安全類型時,不會記錄參數的值,也不會儲存在部署歷程記錄中。 此動作可防止惡意使用者探索敏感性值。

當您提供預設值時,所有可存取範本或部署歷程記錄的人皆可找到該值。

在 Bicep 中,使用 Linter 規則 - 安全參數預設值

下列範例 失敗

"parameters": {
  "adminPassword": {
    "defaultValue": "HardcodedPassword",
    "type": "secureString"
  }
}

下一個範例 通過

"parameters": {
  "adminPassword": {
    "type": "secureString"
  }
}

下列範例通過,因為使用了newGuid函式。

"parameters": {
  "secureParameter": {
    "type": "secureString",
    "defaultValue": "[newGuid()]"
  }
}

環境 URL 無法進行硬式編碼

測試名稱: DeploymentTemplate 不得包含硬式編碼 URI

請勿在範本中硬式編碼環境 URL。 請改用 環境 函式,在部署期間動態取得這些 URL。 如需封鎖的 URL 主機清單,請參閱 測試案例

在 Bicep 中,使用 Linter 規則 - 避免使用硬式編碼的環境 URL

下列範例 會失敗 ,因為 URL 是硬式編碼的。

"variables":{
  "AzureURL":"https://management.azure.com"
}

搭配 concaturi 使用時,測試也會失敗

"variables":{
  "AzureSchemaURL1": "[concat('https://','gallery.azure.com')]",
  "AzureSchemaURL2": "[uri('gallery.azure.com','test')]"
}

下列範例 會通過

"variables": {
  "AzureSchemaURL": "[environment().gallery]"
}

使用參數的位置

測試名稱:位置不應該硬編碼

若要設定資源的位置,您的範本應該要有一個名稱為 location 之參數,且類型需設定為 string。 在主要範本中, azuredeploy.jsonmainTemplate.json,此參數預設為資源群組位置。 在連結或巢狀範本中,位置參數不應該有預設位置。

針對可建立資源的區域,範本使用者的存取權可能有限。 硬式編碼的資源位置可能會禁止使用者建立資源。 如果資源群組是在使用者無法存取的區域中建立,則 "[resourceGroup().location]" 運算式可能會封鎖使用者。 遭封鎖之使用者無法使用此範本。

藉由提供預設為資源群組位置的 location 參數,使用者可以視所需來使用預設值,但也可以指定不同的位置。

在 Bicep 中,使用 Linter 規則 - 禁止在參數預設值之外使用位置表達式

下列範例 失敗 ,因為資源的 location 設定為 resourceGroup().location

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-02-01",
      "name": "storageaccount1",
      "location": "[resourceGroup().location]",
      "kind": "StorageV2",
      "sku": {
        "name": "Premium_LRS",
        "tier": "Premium"
      }
    }
  ]
}

下一個範例使用location參數,失敗是因為參數預設為硬編位置。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "westus"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-02-01",
      "name": "storageaccount1",
      "location": "[parameters('location')]",
      "kind": "StorageV2",
      "sku": {
        "name": "Premium_LRS",
        "tier": "Premium"
      }
    }
  ],
  "outputs": {}
}

當範本用作主要範本時,下列範例會順利運行。 建立預設為資源群組位置之參數,但允許使用者提供不同的值。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for the resources."
      }
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-02-01",
      "name": "storageaccount1",
      "location": "[parameters('location')]",
      "kind": "StorageV2",
      "sku": {
        "name": "Premium_LRS",
        "tier": "Premium"
      }
    }
  ],
  "outputs": {}
}

注意

如果上述範例作為連結的範本使用,則測試 會失敗。 作為連結範本使用時,請移除預設值。

資源應具備位置

測試名稱: 資源必須具備位置

資源的位置應該設定為 樣本表示式global。 範本運算式通常會使用在location中描述的參數。

在 Bicep 中,使用 Linter 規則 - 沒有硬式編碼的位置

下列範例 失敗 ,因為 location 不表示式或 global

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "functions": [],
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-02-01",
      "name": "storageaccount1",
      "location": "westus",
      "kind": "StorageV2",
      "sku": {
        "name": "Premium_LRS",
        "tier": "Premium"
      }
    }
  ],
  "outputs": {}
}

下列範例 會通過,因為資源 location 設定為 global

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "functions": [],
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-02-01",
      "name": "storageaccount1",
      "location": "global",
      "kind": "StorageV2",
      "sku": {
        "name": "Premium_LRS",
        "tier": "Premium"
      }
    }
  ],
  "outputs": {}
}

下一個範例也會 傳遞 ,因為 location 參數會使用表達式。 資源 location 使用運算式的值。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for the resources."
      }
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-02-01",
      "name": "storageaccount1",
      "location": "[parameters('location')]",
      "kind": "StorageV2",
      "sku": {
        "name": "Premium_LRS",
        "tier": "Premium"
      }
    }
  ],
  "outputs": {}
}

VM 大小使用參數

測試名稱: VM 大小應該是參數

不要對hardwareProfile物件之vmSize進行硬式編碼。 當hardwareProfile遭到省略或包含硬式編碼值時,測試就會失敗。 為您的範本使用者提供參數,以便其可修改已部署虛擬機器的大小。 如需詳細資訊,請參閱 Microsoft.Compute virtualMachines

下列範例 會失敗hardwareProfile 因為物件的 vmSize 是硬式編碼值。

"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2020-12-01",
    "name": "demoVM",
    "location": "[parameters('location')]",
    "properties": {
      "hardwareProfile": {
        "vmSize": "Standard_D2_v3"
      }
    }
  }
]

當參數指定一個值給時,此範例vmSize

"parameters": {
  "vmSizeParameter": {
    "type": "string",
    "defaultValue": "Standard_D2_v3",
    "metadata": {
      "description": "Size for the virtual machine."
    }
  }
}

接著,hardwareProfile會針對vmSize使用運算式,以參考參數的值:

"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2020-12-01",
    "name": "demoVM",
    "location": "[parameters('location')]",
    "properties": {
      "hardwareProfile": {
        "vmSize": "[parameters('vmSizeParameter')]"
      }
    }
  }
]

最小值和最大值為數字

測試名稱: 最小值和最大值為數位

當您使用minValuemaxValue來定義參數時,請將其指定為數字。 您必須使用 minValuemaxValue 作為配對,否則測試會失敗。

下列範例 失敗 ,因為 minValuemaxValue 是字串。

"exampleParameter": {
  "type": "int",
  "minValue": "0",
  "maxValue": "10"
}

下列範例 會失敗 ,因為只會 minValue 使用 。

"exampleParameter": {
  "type": "int",
  "minValue": 0
}

下列範例 符合 ,因為 minValuemaxValue 是數字。

"exampleParameter": {
  "type": "int",
  "minValue": 0,
  "maxValue": 10
}

正確定義的成品參數

測試名稱: artifacts 參數

當您列入_artifactsLocation_artifactsLocationSasToken之參數時,請使用正確的預設值與型別。 此測試必須符合下列條件,才會成功:

  • 如果您提供一個參數,就必須提供另一個參數。
  • _artifactsLocation 必須是 string
  • _artifactsLocation 必須在主要範本中有預設值。
  • _artifactsLocation 在巢狀範本中不可有預設值。
  • _artifactsLocation 的預設值必須是 "[deployment().properties.templateLink.uri]" 或原始存放庫 URL。
  • _artifactsLocationSasToken 必須是 secureString
  • _artifactsLocationSasToken 的預設值只能有空字串。
  • _artifactsLocationSasToken 在巢狀範本中不可有預設值。

在 Bicep 中,使用 Linter 規則 - 工件參數

必要的宣告變數

測試名稱: 變數必須被引用

這項測試會尋找未用於範本或有效運算式的變數。 若要減少範本中的混淆,請刪除已定義但未使用的變數。

必須參考使用copy元素的變數 (可逐一查看值)。 如需詳細資訊,請參閱 ARM 範本中的變數迭代

在 Bicep 中,使用 Linter 規則 - 沒有未使用的變數

下列範例 會失敗 ,因為未參考使用 項目的 copy 變數。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "itemCount": {
      "type": "int",
      "defaultValue": 5
    }
  },
  "variables": {
    "copy": [
      {
        "name": "stringArray",
        "count": "[parameters('itemCount')]",
        "input": "[concat('item', copyIndex('stringArray', 1))]"
      }
    ]
  },
  "resources": [],
  "outputs": {}
}

下列範例 會失敗 ,因為參考變數的表達式遺漏前置方括弧 ([)。

"outputs": {
  "outputVariable": {
    "type": "string",
    "value": " variables('varExample')]"
  }
}

下列範例 通過,因為變數在 outputs 中被參考。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "itemCount": {
      "type": "int",
      "defaultValue": 5
    }
  },
  "variables": {
    "copy": [
      {
        "name": "stringArray",
        "count": "[parameters('itemCount')]",
        "input": "[concat('item', copyIndex('stringArray', 1))]"
      }
    ]
  },
  "resources": [],
  "outputs": {
    "arrayResult": {
      "type": "array",
      "value": "[variables('stringArray')]"
    }
  }
}

下列範例 會傳遞 ,因為表達式有效。

"outputs": {
  "outputVariable": {
    "type": "string",
    "value": "[variables('varExample')]"
  }
}

動態變數不應使用 concat

測試名稱: 動態變數參考不應使用 Concat

有時您需根據另一個變數或參數的值,以動態方式建構變數。 設定值時,請勿使用 concat 函式。 相反地,請使用包含可用選項之物件,並在部署期間以動態方式取得物件之其中一個屬性。

下列範例 會通過currentImage變數會在部署期間進行動態設定。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "osType": {
      "type": "string",
      "allowedValues": [
        "Windows",
        "Linux"
      ]
    }
  },
  "variables": {
    "imageOS": {
      "Windows": {
        "image": "Windows Image"
      },
      "Linux": {
        "image": "Linux Image"
      }
    },
    "currentImage": "[variables('imageOS')[parameters('osType')].image]"
  },
  "resources": [],
  "outputs": {
    "result": {
      "type": "string",
      "value": "[variables('currentImage')]"
    }
  }
}

使用最新的 API 版本

測試名稱:apiVersions應為最新

每個資源都應使用已硬式編碼為字串的最新 API 版本。 測試會針對工具組快取中的資源提供者版本,來評估您範本中的 API 版本。 測試執行日期起兩年內的 API 版本會視為最新版本。 如果有較新版本可供使用,請勿使用預覽版本。

如果找不到 API 版本之警告,僅代表版本不在工具組的快取中。 使用最新版本的 API (建議使用) 會產生警告。

深入瞭解 工具組快取

在 Bicep 中,使用 Linter 規則 - 使用最近的 API 版本

下列範例 失敗 ,因為 API 版本超過兩年。

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2019-06-01",
    "name": "storageaccount1",
    "location": "[parameters('location')]"
  }
]

下列範例 失敗 ,因為有較新版本可用時會使用預覽版本。

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2020-08-01-preview",
    "name": "storageaccount1",
    "location": "[parameters('location')]"
  }
]

以下範例 符合 ,因為它是近期版本,而非預覽版本。

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2021-02-01",
    "name": "storageaccount1",
    "location": "[parameters('location')]"
  }
]

使用硬式編碼的 API 版本

測試名稱: 提供者的 apiVersions 不被允許

資源類型的 API 版本會決定可用屬性。 在範本中提供硬式編碼的 API 版本。 由於您無法得知可用屬性為何,因此請勿擷取在部署期間決定的 API 版本。

下列範例 失敗

"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "[providers('Microsoft.Compute', 'virtualMachines').apiVersions[0]]",
    ...
  }
]

下列範例 會通過

"resources": [
  {
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2020-12-01",
    ...
  }
]

屬性不可為空白

測試名稱: 範本不應包含空白

請勿將屬性硬式編碼為空白值。 空白值包含 Null、空字串、物件或陣列。 如果屬性設定為空白值,請從您的範本中移除該屬性。 您可以在部署期間將屬性設為空白值 (例如透過參數)。

template 巢狀範本中的 屬性可以包含空白屬性。 如需巢狀範本的詳細資訊,請參閱 Microsoft.Resources 部署

下列範例 失敗 ,因為有空的屬性。

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2021-01-01",
    "name": "storageaccount1",
    "location": "[parameters('location')]",
    "sku": {},
    "kind": ""
  }
]

下列範例 會傳遞 ,因為屬性包含值。

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2021-01-01",
    "name": "storageaccount1",
    "location": "[parameters('location')]",
    "sku": {
      "name": "Standard_LRS",
      "tier": "Standard"
    },
    "kind": "Storage"
  }
]

使用資源識別碼函式

測試名稱:標識碼 應衍生自 ResourceID

指定資源識別碼時,請使用其中一個資源識別碼函式。 允許的功能為:

請勿使用 concat 函式建立資源識別碼。

在 Bicep 中,使用 Linter 規則 - 使用資源識別碼函式

下列範例 失敗

"networkSecurityGroup": {
    "id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]"
}

下一個範例 通過

"networkSecurityGroup": {
    "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
}

ResourceId 函式有正確參數

測試名稱: ResourceIds 不應包含

當產生資源識別碼時,請勿針對選擇性參數使用不必要的函數。 根據預設, resourceId 函式會使用目前的訂用帳戶和資源群組。 您不需要提供這些值。

下列範例 失敗 ,因為您不需要提供目前的訂用帳戶標識碼和資源組名。

"networkSecurityGroup": {
    "id": "[resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
}

下一個範例 通過

"networkSecurityGroup": {
    "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
}

此測試適用於:

針對 referencelist*,當您使用 來建構資源標識符時,測試concat

dependsOn 最佳作法

測試名稱: DependsOn 最佳實踐

設定部署相依性時,請勿使用 if 函式來測試條件。 如果一個資源相依於有條件地部署的資源,請設定相依關係就如同設定任何其他資源的相依關係。 如果未部署條件式資源,Azure Resource Manager 會自動將其從必要的相依性中移除。

元素 dependsOn 不能以 concat 函式開頭。

在 Bicep 中,使用 Linter 規則 - 移除不必要的 dependsOn 條目

下列範例 會失敗 ,因為它包含函 if 式。

"dependsOn": [
  "[if(equals(parameters('newOrExisting'),'new'), variables('storageAccountName'), '')]"
]

下列範例失敗,因為它以concat開頭。

"dependsOn": [
  "[concat(variables('storageAccountName'))]"
]

下列範例 會通過

"dependsOn": [
  "[variables('storageAccountName')]"
]

巢狀或連結部署無法使用偵錯

測試名稱: 部署資源不得偵錯

當您使用資源類型定義 巢狀或連結Microsoft.Resources/deployments 範本時,您可以啟用 偵錯。 您可在需要測試範本,並可公開敏感性資訊的情況下進行偵錯。 在生產中使用此範本之前,請先關閉偵錯。 您可以移除debugSetting物件,或將detailLevel屬性變更為none

下列範例 失敗

"debugSetting": {
  "detailLevel": "requestContent"
}

下列範例 會通過

"debugSetting": {
  "detailLevel": "none"
}

管理使用者的名稱不可為常值

測試名稱: adminUsername 不應該是字面值

請勿在設定 adminUserName 時使用常值。 建立使用者名稱的參數,並使用運算式來參考參數的值。

在 Bicep 中,使用 Linter 規則 - 管理員使用者名稱不應當是固定值

下列範例 會因為文字值而失敗

"osProfile":  {
  "adminUserName": "myAdmin"
}

下列 範例會 傳遞表達式。

"osProfile": {
  "adminUsername": "[parameters('adminUsername')]"
}

使用最新的 VM 映像

測試名稱: VM 映像應使用最新版本

已停用此測試,但輸出顯示其已成功。 最佳做法是依照下列準則檢查您的範本:

如果您的範本包含具有映像之虛擬機器,請務必使用最新的映像版本。

在 Bicep 中,使用 Linter 規則 - 使用穩定的 VM 映射

使用穩定的 VM 映像

測試名稱: 虛擬機不應為預覽

虛擬機器不應使用預覽版的映像。 測試會檢查 storageProfile ,以確認 imageReference 不會使用包含 預覽的字串。 而且該 預覽 不會用於 imageReference 屬性 offerskuversion

如需屬性的詳細資訊 imageReference ,請參閱 Microsoft.Compute virtualMachinesMicrosoft.Compute virtualMachineScaleSets

在 Bicep 中,使用 Linter 規則 - 使用穩定的 VM 映射

下列範例 失敗 ,因為 imageReference 是包含 預覽的字串。

"properties": {
  "storageProfile": {
    "imageReference": "latest-preview"
  }
}

offer中使用sku時,下列範例version

"properties": {
  "storageProfile": {
    "imageReference": {
      "publisher": "Canonical",
      "offer": "UbuntuServer_preview",
      "sku": "16.04-LTS-preview",
      "version": "preview"
    }
  }
}

下列範例 會通過

"storageProfile": {
  "imageReference": {
    "publisher": "Canonical",
    "offer": "UbuntuServer",
    "sku": "16.04-LTS",
    "version": "latest"
  }
}

不要使用 ManagedIdentity 延伸模組

測試名稱: 不得使用ManagedIdentityExtension

請勿將 ManagedIdentity 延伸模組套用至虛擬機器。 擴充功能已在 2019 年遭取代,並不得再使用。

輸出不能包含祕密

測試名稱: 輸出不得包含秘密

請勿在可能公開祕密之outputs區段中包含任何值。 例如,類型為secureStringsecureObject的安全參數,或函式清單*,例如listKeys

範本的輸出作業會儲存在部署歷程記錄中,因此惡意使用者可以找到該資訊。

在 Bicep 中,使用 Linter 規則 - 輸出不應包含秘密

下列範例 失敗 ,因為它在輸出值中包含安全參數。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "secureParam": {
      "type": "secureString"
    }
  },
  "functions": [],
  "variables": {},
  "resources": [],
  "outputs": {
    "badResult": {
      "type": "string",
      "value": "[concat('this is the value ', parameters('secureParam'))]"
    }
  }
}

下列範例 失敗 ,因為它會在輸出中使用 list* 函式。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageName": {
      "type": "string"
    }
  },
  "functions": [],
  "variables": {},
  "resources": [],
  "outputs": {
    "badResult": {
      "type": "object",
      "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2021-02-01')]"
    }
  }
}

針對 commandToExecute 祕密使用 protectedSettings

測試名稱:CommandToExecute 必須使用 ProtectedSettings 來處理機密資訊

針對類型為 CustomScript 之資源,請在 protectedSettings 包含祕密資料 (例如密碼) 時,使用加密的 commandToExecute。 例如,秘密數據可用於 類型 secureStringsecureObjectlist* 函式等安全參數,例如 listKeys、 或自定義腳本。

請勿在settings物件中使用祕密資料,因其會使用純文字。 如需詳細資訊,請參閱 Microsoft.Compute virtualMachines/extensionsWindowsLinux

在 Bicep 中,使用 Linter 規則 - 利用 protectedSettings 來保護 commandToExecute 的機密資訊

下列範例 會失敗 ,因為 settings 使用 commandToExecute 搭配安全參數。

"parameters": {
  "adminPassword": {
    "type": "secureString"
  }
}
...
"properties": {
  "type": "CustomScript",
  "settings": {
    "commandToExecute": "[parameters('adminPassword')]"
  }
}

下列範例會失敗,因為settingscommandToExecute函式一起使用listKeys

"properties": {
  "type": "CustomScript",
  "settings": {
    "commandToExecute": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2021-02-01')]"
  }
}

下列範例 會通過,因為 protectedSettings 會搭配安全參數使用 commandToExecute

"parameters": {
  "adminPassword": {
    "type": "secureString"
  }
}
...
"properties": {
  "type": "CustomScript",
  "protectedSettings": {
    "commandToExecute": "[parameters('adminPassword')]"
  }
}

下列範例會通過,因為protectedSettings使用commandToExecutelistKeys函式。

"properties": {
  "type": "CustomScript",
  "protectedSettings": {
    "commandToExecute": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2021-02-01')]"
  }
}

使用參考函數中最新的 API 版本

測試名稱:apiVersions 在參考函式中應保持最新

參考函式中使用的 API 版本必須是最近版本,而不是預覽版本。 測試會針對工具組快取中的資源提供者版本,來評估您範本中的 API 版本。 測試執行日期起兩年內的 API 版本會視為最新版本。

如果找不到 API 版本之警告,僅代表版本不在工具組的快取中。 使用最新版本的 API (建議使用) 會產生警告。

深入瞭解 工具組快取

下列範例 失敗 ,因為 API 版本超過兩年。

"outputs": {
  "stgAcct": {
    "type": "string",
    "value": "[reference(resourceId(parameters('storageResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01')]"
  }
}

下列範例 失敗 ,因為 API 版本是預覽版本。

"outputs": {
  "stgAcct": {
    "type": "string",
    "value": "[reference(resourceId(parameters('storageResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2020-08-01-preview')]"
  }
}

下列範例 通過 ,因為 API 版本不到兩年,而且不是預覽版本。

"outputs": {
  "stgAcct": {
    "type": "string",
    "value": "[reference(resourceId(parameters('storageResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-02-01')]"
  }
}

在 resourceId 函式中使用型別和名稱

測試名稱: 資源不應模棱兩可

已停用此測試,但輸出顯示其已成功。 最佳做法是依照下列準則檢查您的範本:

resourceId 必須包含資源類型和資源名稱。 此測試會尋找所有範本之 resourceId 函式,並使用正確的語法驗證資源是否使用於範本中。 否則會將函式視為不明確。

若當下列情況發生,resourceId 函數會視為不明確:

  • 當範本中找不到資源,且未指定資源群組。
  • 當資源包含條件,且未指定資源群組。
  • 當相關資源包含部分,但非全部的名稱區段。 例如,子資源包含一個以上的名稱區段。 如需詳細資訊,請參閱 resourceId 備註

針對巢狀部署安全參數使用內部範圍

測試名稱: 巢狀部署中的安全參數

使用巢狀範本expressionEvaluationOptions的物件與inner範圍來評估包含安全參數的運算式,這些參數類型為secureStringsecureObject清單*的函式,例如listKeys。 如果使用 outer 範圍,運算式會以純文字的方式在父代範本範圍內進行評估。 如此一來,任何可存取部署歷程記錄的人,皆能看到安全的值。 expressionEvaluationOptions 的預設值為 outer

如需有關巢狀範本的詳細資訊,請參閱 Microsoft.Resources 部署巢狀範本中的運算式評估範圍

在 Bicep 中,使用 Linter 規則 - 巢狀部署中的安全參數

下列範例 失敗 ,因為 expressionEvaluationOptions 會使用 outer 範圍來評估安全參數或 list* 函式。

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2021-04-01",
    "name": "nestedTemplate",
    "properties": {
      "expressionEvaluationOptions": {
        "scope": "outer"
      }
    }
  }
]

下列範例會通過,因為expressionEvaluationOptions使用inner範圍來評估安全參數或list*函式。

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2021-04-01",
    "name": "nestedTemplate",
    "properties": {
      "expressionEvaluationOptions": {
        "scope": "inner"
      }
    }
  }
]

下一步