ARM テンプレートのテスト ケース

この記事では、Azure Resource Manager テンプレート (ARM テンプレート) 用の テンプレート テスト ツールキットを使用して実行されるテストについて説明します。 これには、テストに合格する、または不合格になる例と、各テストの名前が示されています。 テストを実行する方法、または特定のテストを実行する方法の詳細については、「テスト パラメーター」を参照してください。

正しいスキーマを使用する

テスト名: DeploymentTemplate Schema Is Correct (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

宣言されたパラメーターが使用されている必要がある

テスト名: Parameters Must Be Referenced (パラメーターは参照されている必要がある)

このテストでは、テンプレートで使用されていないパラメーター、または有効な式で使用されていないパラメーターを検出します。

テンプレートの混乱を軽減するには、定義されていても使用されていないパラメーターを削除します。 未使用のパラメーターを削除すると、不要な値を指定する必要がないため、テンプレートのデプロイが簡素化されます。

Bicep では、「リンター ルール - 未使用のパラメーターがない」を使用します。

次の例は、パラメーターを参照する式の先頭に角かっこ ([) がないため、不合格になります。

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

次の例は、式が有効であるため、合格します。

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

セキュリティで保護されたパラメーターの既定値をハードコーディングしてはならない

テスト名: Secure String Parameters Cannot Have Default (セキュリティで保護された文字列パラメーターに既定値を設定してはならない)

テンプレートのセキュリティで保護されたパラメーターに、ハードコーディングされた既定値を指定してはいけません。 セキュリティで保護されたパラメーターには、既定値として空の文字列を指定するか、式で newGuid 関数を使用することができます。

パスワードのような機密性の高い値を含むパラメーターでは、secureString または secureObject 型を使用します。 パラメーターでセキュリティ保護された型が使用されていると、そのパラメーターの値はログに記録されず、デプロイ履歴に格納されません。 このアクションにより、悪意のあるユーザーが機密値を検出できなくなります。

既定値を指定すると、テンプレートまたはデプロイ履歴にアクセスできるすべてのユーザーが、その値を検出できます。

Bicep では、「リンター ルール - セキュリティ保護されたパラメーターの既定値」を使用します。

次の例は不合格になります。

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

次の例は合格します。

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

次の例は、newGuid 関数が使用されているため、合格します。

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

環境 URL をハードコーディングしてはならない

テスト名: DeploymentTemplate Must Not Contain Hardcoded Uri (DeploymentTemplate にはハードコーディングされた Uri を含めることができない)

テンプレート内に環境 URL をハードコーディングしないでください。 代わりに、環境関数を使用して、デプロイ時にこれらの URL を動的に取得します。 ブロックされている URL ホストの一覧については、テスト ケースを参照してください。

Bicep では、「リンター ルール - ハードコーディングされた環境 URL がない」を使用します。

次の例は、URL がハードコーディングされているため、不合格になります。

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

concat または uri と共に使用されているときも、テストは不合格になります。

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

次の例は合格します。

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

場所にはパラメーターを使用する

テスト名: Location Should Not Be Hardcoded (場所をハードコーディングしてはいけない)

リソースの場所を設定するには、テンプレートに location という名前のパラメーターを指定し、その型を string に設定する必要があります。 メイン テンプレート (azuredeploy.json または mainTemplate.json) では、このパラメーターにリソース グループの場所を既定で設定できます。 リンクまたは入れ子になったテンプレートの場合、location パラメーターに既定の場所を設定しないでください。

テンプレート ユーザーは、リソースを作成できるリージョンへのアクセスが制限される場合があります。 リソースの場所がハードコーディングされていると、ユーザーがリソースを作成できない恐れがあります。 ユーザーがアクセスできないリージョンにリソース グループが作成された場合、"[resourceGroup().location]" 式によってユーザーがブロックされることがあります。 ブロックされたユーザーは、テンプレートを使用できません。

既定のリソース グループの場所になる location パラメーターを指定することで、ユーザーは、必要に応じて既定値を使用できますが、別の場所を指定することもできます。

Bicep では、「リンター ルール - パラメーターの既定値以外の位置表現は不可」を使用します。

次の例は、リソースの locationresourceGroup().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": {}
}

Note

前の例をリンクされたテンプレートとして使用した場合、テストは不合格になります。 リンクされたテンプレートとして使用する場合は、既定値を削除してください。

リソースには場所が必要である

テスト名: Resources Should Have Location (リソースには場所が必要である)

リソースの場所は、テンプレート式または global に設定する必要があります。 テンプレート式では、通常、「場所にはパラメーターを使用する」で説明した location パラメーターが使用されます。

Bicep では、「リンター ルール - ハードコードされた場所はなし」を使用します。

次の例は、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": {}
}

次の例は、リソースの locationglobal に設定されているため、合格します。

{
  "$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 Size Should Be A Parameter (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."
    }
  }
}

次に、パラメーターの値を参照するために、hardwareProfilevmSize に対して式を使用します。

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

最小値と最大値が数値である

テスト名: Min And Max Value Are Numbers (最小値と最大値が数値である)

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 parameter (成果物パラメーター)

_artifactsLocation_artifactsLocationSasToken のパラメーターを指定する場合は、正しい既定値と型を使用します。 このテストに合格するには、次の条件が満たされている必要があります。

  • 一方のパラメーターを指定する場合は、他方も指定する必要があります。
  • _artifactsLocationstring である必要があります。
  • _artifactsLocation の既定値は、メイン テンプレートで指定されている必要があります。
  • _artifactsLocation の既定値を、入れ子になったテンプレートで指定することはできません。
  • _artifactsLocation には、"[deployment().properties.templateLink.uri]" またはその既定値に対する生リポジトリ URL のいずれかが必要です。
  • _artifactsLocationSasTokensecureString である必要があります。
  • _artifactsLocationSasToken の既定値には空の文字列のみを指定できます。
  • _artifactsLocationSasToken の既定値を、入れ子になったテンプレートで指定することはできません。

Bicep では、「リンタールール - 成果物のパラメーター」を使用します。

宣言された変数が使用されている必要がある

テスト名: Variables Must Be Referenced (変数は参照されている必要がある)

このテストでは、テンプレートで使用されていないか、有効な式で使用されていない変数を検出します。 テンプレートの混乱を軽減するには、定義されていても使用されていない変数を削除します。

copy 要素を使用して値を反復処理する変数は、参照される必要があります。 詳細については、「ARM テンプレートでの変数の反復処理」を参照してください。

Bicep では、「リンター ルール - 未使用の変数がない」を使用します。

次の例は、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 を使用してはならない

テスト名: Dynamic Variable References Should Not Use Concat (動的変数の参照で concat を使用してはならない)

場合によっては、別の変数またはパラメーターの値に基づいて変数を動的に構築する必要があります。 値を設定するときは、concat 関数を使用しないでください。 代わりに、使用可能なオプションが含まれるオブジェクトを使用し、デプロイの間にオブジェクトからプロパティの 1 つを動的に取得します。

次の例は合格します。 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 Should Be Recent (apiVersions は最新でなければならない)

各リソースの API バージョンでは、文字列としてハードコーディングされた最新バージョンを使用する必要があります。 このテストでは、テンプレートの API バージョンが、ツールキットのキャッシュ内のリソース プロバイダーのバージョンに対して評価されます。 テストが実行されてから 2 年未満の API バージョンは、最新と見なされます。 より新しいバージョンが使用可能な場合には、プレビュー バージョンを使用しないでください。

API バージョンが検出されなかったことを示す警告は、ツールキットのキャッシュにバージョンが含まれていないことだけを示しています。 最新バージョンの API (推奨) を使用すると、警告が生成されることがあります。

ツールキットのキャッシュの詳細について確認してください。

Bicep では、「リンター ルール - API の最新バージョンを使用する」を使用します。

次の例は、API バージョンが 2 年以上経っているため、不合格になります。

"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 バージョンを使用する

テスト名: Providers apiVersions Is Not Permitted (プロバイダーの 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",
    ...
  }
]

プロパティを空にすることはできない

テスト名: Template Should Not Contain Blanks (テンプレートに空白が含まれていてはならない)

プロパティを空の値にハードコーディングしないでください。 空の値には、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"
  }
]

リソース ID 関数を使用する

テスト名: IDs Should Be Derived From ResourceIDs (ID は ResourceID から派生する必要がある)

リソース ID を指定するときは、リソース ID 関数のいずれかを使用します。 使用できる関数は次のとおりです。

concat 関数を使用してリソース ID を作成しないでください。

Bicep では、「リンター ルール - リソース ID 関数を使用する」を使用します。

次の例は不合格になります。

"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 should not contain (ResourceId に含まれていてはならない)

リソース ID を生成するときは、省略可能なパラメーターに不要な関数を使用しないでください。 既定の resourceId 関数では、現在のサブスクリプションとリソース グループが使用されます。 それらの値を指定する必要はありません。

次の例は、現在のサブスクリプション ID とリソース グループ名を指定する必要がないため、不合格になります。

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

次の例は合格します。

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

このテストは以下に適用されます。

referencelist* は、concat を使用してリソース ID を作成すると、テストで不合格になります。

dependsOn ベスト プラクティス

テスト名: DependsOn Best Practices (DependsOn ベスト プラクティス)

デプロイの依存関係を設定するときに、if 関数を使用して条件をテストしないでください。 あるリソースが条件付きでデプロイされるリソースに依存している場合は、任意のリソースと同様に依存関係を設定します。 条件付きリソースがデプロイされていない場合、Azure Resource Manager によって必要な依存関係からそれが自動的に削除されます。

dependsOn 要素は、concat 関数から始めることはできません。

Bicep では、「リンター ルール - 不要な dependsOn エントリがない」を使用します。

次の例は、if 関数が含まれているため、不合格になります。

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

次の例は、concat から始まるため、不合格になります。

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

次の例は合格します。

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

入れ子になったデプロイまたはリンクされたデプロイではデバッグを使用できない

テスト名: Deployment Resources Must Not Be Debug (デプロイ リソースをデバッグしてはならない)

リソースの種類 Microsoft.Resources/deployments を使用して入れ子になった、またはリンクされたテンプレートを定義する場合、デバッグを有効にすることができます。 デバッグは、テンプレートをテストする必要があり、機密情報を公開できる場合に使用します。 テンプレートを運用環境で使用する前に、デバッグを無効にしてください。 debugSetting オブジェクトを削除するか、detailLevel プロパティを none に変更できます。

次の例は不合格になります。

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

次の例は合格します。

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

管理者ユーザー名をリテラル値にすることはできない

テスト名: adminUsername Should Not Be A Literal (adminUsername をリテラルにしてはならない)

adminUserName を設定するときは、リテラル値を使用しないでください。 ユーザー名のパラメーターを作成し、式を使用してパラメーターの値を参照します。

Bicep では、「リンター ルール - 管理者ユーザー名をリテラルにすることはできません」を使用します。

次の例は、リテラル値を使用しているため、不合格になります。

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

次の例は、式を使用しているため、合格します。

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

最新の VM イメージを使用する

テスト名: VM Images Should Use Latest Version (VM イメージでは最新バージョンを使用しなければならない)

このテストは無効になっていますが、出力ではそれに合格したことが示されます。 次の基準についてテンプレートを確認することをお勧めします。

テンプレートにイメージを含む仮想マシンが含まれている場合は、イメージの最新バージョンが使用されていることを確認します。

Bicep では、「リンター ルール - 安定した VM イメージを使用する」を使用します。

安定した VM イメージを使用する

テスト名: Virtual Machines Should Not Be Preview (仮想マシンはプレビューにしない)

仮想マシンではプレビュー イメージを使用しないでください。 テストでは、storageProfile を確認して、imageReferencepreview を含む文字列が使用されていないことを検証します。 さらに、previewimageReference のプロパティ offersku、または version で使用されていないことを検証します。

imageReference プロパティの詳細については、「Microsoft.Compute virtualMachines」と「Microsoft.Compute virtualMachineScaleSets」を参照してください。

Bicep では、「リンター ルール - 安定した VM イメージを使用する」を使用します。

次の例は、imageReferencepreview を含む文字列であるため、不合格になります。

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

次の例は、previewoffersku、または 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 must not be used (ManagedIdentityExtension を使用してはならない)

ManagedIdentity 拡張機能を仮想マシンに適用しないでください。 この拡張機能は 2019 年に非推奨とされたため、今後は使用しないでください。

出力にシークレットを含めることはできない

テスト名: Outputs Must Not Contain Secrets (出力にシークレットが含まれていてはならない)

outputs セクションには、シークレットが公開される可能性のある値を含めないでください。 たとえば、secureString または secureObject 型のセキュリティで保護されたパラメーター、または list* 関数 (listKeys など) です。

テンプレートからの出力はデプロイ履歴に格納されるため、悪意のあるユーザーがその情報を見つける可能性があります。

Bicep では、「リンター ルール - 出力にシークレットを含めるべきではありません」を使用します。

次の例は、セキュリティで保護されたパラメーターが出力値に含まれるため、不合格になります。

{
  "$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 Must Use ProtectedSettings For Secrets (CommandToExecute ではシークレットに ProtectedSettings を使用する必要がある)

種類が CustomScript のリソースの場合、commandToExecute にパスワードなどのシークレット データが含まれるときは、暗号化された protectedSettings を使用します。 たとえば、シークレット データは、型 secureString または secureObject のセキュリティで保護されたパラメーター、list* 関数 (listKeys など)、またはカスタム スクリプトで使用できます。

settings オブジェクトではクリア テキストが使用されているため、シークレット データを使用しないでください。 詳細については、「Microsoft.Compute virtualMachines/extensions」、Windows または Linux に関する記事を参照してください。

Bicep では、「リンター ルール - commandToExecute のシークレットに protectedSettings を使用する」を使用します。

次の例は、settingscommandToExecute をセキュリティで保護されたパラメーターと共に使用しているため、不合格になります。

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

次の例は、settingscommandToExecutelistKeys 関数と共に使用しているため、不合格になります。

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

次の例は、protectedSettingscommandToExecute をセキュリティで保護されたパラメーターと共に使用しているため、合格します。

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

次の例は、protectedSettingscommandToExecutelistKeys 関数と共に使用しているため、合格します。

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

reference 関数で最新の API バージョンを使用する

テスト名: apiVersions Should Be Recent In Reference Functions (reference 関数で apiVersions は最新でなければならない)

reference 関数で使用されている API バージョンは、プレビュー バージョンではない最新である必要があります。 このテストでは、テンプレートの API バージョンが、ツールキットのキャッシュ内のリソース プロバイダーのバージョンに対して評価されます。 テストが実行されてから 2 年未満の API バージョンは、最新と見なされます。

API バージョンが検出されなかったことを示す警告は、ツールキットのキャッシュにバージョンが含まれていないことだけを示しています。 最新バージョンの API (推奨) を使用すると、警告が生成されることがあります。

ツールキットのキャッシュの詳細について確認してください。

次の例は、API バージョンが 2 年以上経っているため、不合格になります。

"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 バージョンが 2 年未満であり、プレビュー バージョンではないため、合格します。

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

resourceId 関数で種類と名前を使用する

テスト名: Resources Should Not Be Ambiguous (リソースはあいまいにしない)

このテストは無効になっていますが、出力ではそれに合格したことが示されます。 次の基準についてテンプレートを確認することをお勧めします。

resourceId には、リソースの種類とリソース名が含まれている必要があります。 このテストでは、テンプレートのすべての resourceId 関数を検出し、リソースが正しい構文でテンプレート内で使用されていることを確認します。 そうでない場合、この関数はあいまいであると見なされます。

たとえば、次の場合に、resourceId 関数はあいまいであると見なされます。

  • テンプレート内にリソースが見つからず、リソース グループが指定されていない場合。
  • リソースに条件が含まれていて、リソース グループが指定されていない場合。
  • 関連リソースに、名前セグメントのすべてではなく、一部が含まれている場合。 たとえば、子リソースに複数の名前セグメントが含まれている場合などです。 詳細については、resourceId の解説に関する記事を参照してください。

入れ子になったデプロイのセキュリティで保護されたパラメーターに inner スコープを使用する

テスト名: Secure Params In Nested Deployments (入れ子になったデプロイのセキュリティで保護されたパラメーター)

入れ子になったテンプレートの expressionEvaluationOptions オブジェクトを inner スコープと共に使用して、型 secureString または secureObject のセキュリティで保護されたパラメーター、または list* 関数 (listKeys など) を含む式を評価します。 outer スコープが使用されている場合、式は親テンプレートのスコープ内でクリア テキストで評価されます。 そうすると、セキュリティで保護された値は、デプロイ履歴にアクセスできるすべてのユーザーに表示されます。 expressionEvaluationOptions の既定値は outerです。

入れ子になったテンプレートの詳細については、「Microsoft.Resources のデプロイ」と「入れ子になったテンプレートでの式の評価のスコープ」を参照してください。

Bicep では、「リンター ルール - 入れ子になったデプロイのセキュリティで保護されたパラメーター」を使用します。

次の例は、セキュリティで保護されたパラメーターまたは list* 関数を評価するために expressionEvaluationOptionsouter スコープが使用されているため、不合格になります。

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

次の例は、セキュリティで保護されたパラメーターまたは list* 関数を評価するために expressionEvaluationOptionsinner スコープが使用されているため、合格します。

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

次のステップ