ARM テンプレートのベスト プラクティスARM template best practices

この記事では、Azure Resource Manager テンプレート (ARM テンプレート) を構築する際に推奨プラクティスを使用する方法について説明します。This article shows you how to use recommended practices when constructing your Azure Resource Manager template (ARM template). これらの推奨事項は、ARM テンプレートを使用したソリューションのデプロイに関する一般的な問題を回避するうえで役立ちます。These recommendations help you avoid common problems when using an ARM template to deploy a solution.

テンプレートの制限Template limits

テンプレートのサイズを 4 MB に、各パラメーター ファイルのサイズを 64 KB に制限します。Limit the size of your template to 4 MB, and each parameter file to 64 KB. 4 MB の制限は、反復的なリソースの定義と変数およびパラメーターの値で拡張された後のテンプレートの最終的な状態に適用されます。The 4-MB limit applies to the final state of the template after it has been expanded with iterative resource definitions, and values for variables and parameters.

また、以下のように制限されます。You're also limited to:

  • パラメーター 256 個256 parameters
  • 変数 256 個256 variables
  • リソース (コピー数を含む) 800 個800 resources (including copy count)
  • 出力値 64 個64 output values
  • テンプレート式内で 24,576 文字24,576 characters in a template expression

入れ子になったテンプレートを使用すると、一部のテンプレートの制限を超過することができます。You can exceed some template limits by using a nested template. 詳細については、「Azure リソース デプロイ時のリンクされたテンプレートおよび入れ子になったテンプレートの使用」を参照してください。For more information, see Using linked and nested templates when deploying Azure resources. パラメーター、変数、出力の数を減らすために、いくつかの値を 1 つのオブジェクトに結合することができます。To reduce the number of parameters, variables, or outputs, you can combine several values into an object. 詳しくは、パラメーターとしてのオブジェクトに関する記事をご覧ください。For more information, see Objects as parameters.

Resource groupResource group

リソース グループにリソースをデプロイすると、リソースに関するメタデータがリソース グループに格納されます。When you deploy resources to a resource group, the resource group stores metadata about the resources. メタデータは、リソース グループの場所に格納されます。The metadata is stored in the location of the resource group.

リソース グループのリージョンが一時的に使用できない場合は、メタデータが使用できないため、リソース グループ内のリソースを更新できません。If the resource group's region is temporarily unavailable, you can't update resources in the resource group because the metadata is unavailable. 他のリージョン内のリソースは通常どおり機能しますが、それらを更新することはできません。The resources in other regions will still function as expected, but you can't update them. リスクを最小限に抑えるため、リソース グループとリソースは同じリージョンに配置するようにしてください。To minimize risk, locate your resource group and resources in the same region.

パラメーターParameters

このセクションの情報は、パラメーターを使用するときに役に立ちます。The information in this section can be helpful when you work with parameters.

パラメーターに関する一般的な推奨事項General recommendations for parameters

  • パラメーターの使用を最小限に抑えます。Minimize your use of parameters. 代わりに、デプロイ時に指定する必要のないプロパティの変数またはリテラル値を使用してください。Instead, use variables or literal values for properties that don't need to be specified during deployment.

  • パラメーター名にキャメル ケースを使用します。Use camel case for parameter names.

  • SKU、サイズ、容量など、環境に応じて異なる設定のパラメーターを使用します。Use parameters for settings that vary according to the environment, like SKU, size, or capacity.

  • 特定しやすいように指定するリソース名のパラメーターを使用します。Use parameters for resource names that you want to specify for easy identification.

  • メタデータですべてのパラメーターを説明します。Provide a description of every parameter in the metadata.

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • 重要ではないパラメーターの既定値を定義します。Define default values for parameters that aren't sensitive. 既定値を指定することで、テンプレートをデプロイしやすくなり、ご自身のテンプレートのユーザーに適切な値の例が表示されます。By specifying a default value, it's easier to deploy the template, and users of your template see an example of an appropriate value. パラメーターの既定値は、既定のデプロイ構成のすべてのユーザーに対して有効である必要があります。Any default value for a parameter must be valid for all users in the default deployment configuration.

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "defaultValue": "Standard_GRS",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • オプションのパラメーターを指定するために、空の文字列を既定値として使用しないでください。To specify an optional parameter, don't use an empty string as a default value. 代わりに、リテラル値または言語式を使用して値を構成します。Instead, use a literal value or a language expression to construct a value.

    "storageAccountName": {
       "type": "string",
       "defaultValue": "[concat('storage', uniqueString(resourceGroup().id))]",
       "metadata": {
         "description": "Name of the storage account"
       }
    }
    
  • allowedValues は慎重に使用してください。Use allowedValues sparingly. 許可されているオプションに、ある値が含まれていないことを確認する必要がある場合にのみ使用します。Use it only when you must make sure some values aren't included in the permitted options. allowedValues を盛大に使用しすぎると、ご自身の一覧が最新の状態に保たれなくなり、有効なデプロイをブロックしてしまう可能性があります。If you use allowedValues too broadly, you might block valid deployments by not keeping your list up to date.

  • お使いのテンプレートのパラメーター名と PowerShell デプロイ コマンドのパラメーターが同じ場合は、Resource Manager によって、ポストフィックス FromTemplate がテンプレート パラメーターに追加され、この名前の競合が解決されます。When a parameter name in your template matches a parameter in the PowerShell deployment command, Resource Manager resolves this naming conflict by adding the postfix FromTemplate to the template parameter. たとえば、ResourceGroupName という名前のパラメーターをテンプレートに追加した場合、New-AzResourceGroupDeployment コマンドレットの ResourceGroupName パラメーターと競合します。For example, if you include a parameter named ResourceGroupName in your template, it conflicts with the ResourceGroupName parameter in the New-AzResourceGroupDeployment cmdlet. デプロイ中、ResourceGroupNameFromTemplate に値を指定するように求められます。During deployment, you're prompted to provide a value for ResourceGroupNameFromTemplate.

パラメーターに関するセキュリティの推奨事項Security recommendations for parameters

  • ユーザー名とパスワード (またはシークレット) に対して必ずパラメーターを使用します。Always use parameters for user names and passwords (or secrets).

  • すべてのパスワードおよびシークレットに securestring を使用します。Use securestring for all passwords and secrets. JSON オブジェクトに機密データを渡す場合は、secureObject 型を使用します。If you pass sensitive data in a JSON object, use the secureObject type. secure string 型または secure object 型を含むテンプレート パラメーターをリソースのデプロイ後に読み取ることはできません。Template parameters with secure string or secure object types can't be read after resource deployment.

    "parameters": {
      "secretValue": {
        "type": "securestring",
        "metadata": {
          "description": "The value of the secret to store in the vault."
        }
      }
    }
    
  • ユーザー名、パスワード、または secureString 型を必要とする任意の値には既定値を指定しないでください。Don't provide default values for user names, passwords, or any value that requires a secureString type.

  • アプリケーションの攻撃対象となる領域が増えるプロパティには既定値を指定しないでください。Don't provide default values for properties that increase the attack surface area of the application.

パラメーターに関する場所の推奨事項Location recommendations for parameters

  • パラメーターを使用して、リソースの場所を指定し、既定値を resourceGroup().location に設定します。Use a parameter to specify the location for resources, and set the default value to resourceGroup().location. 場所パラメーターを指定することにより、テンプレートのユーザーが、自身がリソースをデプロイするアクセス許可を持つ場所を指定できます。Providing a location parameter enables users of the template to specify a location where they have permission to deploy resources.

    "parameters": {
       "location": {
         "type": "string",
         "defaultValue": "[resourceGroup().location]",
         "metadata": {
           "description": "The location in which the resources should be deployed."
         }
       }
    }
    
  • 場所パラメーターに allowedValues を指定しないでください。Don't specify allowedValues for the location parameter. 指定する場所がすべてのクラウドで使用できるとは限りません。The locations you specify might not be available in all clouds.

  • 場所パラメーター値は、同じ場所に所属する可能性が高いリソースに対して使用します。Use the location parameter value for resources that are likely to be in the same location. この方法により、ユーザーが場所情報の入力を求められる回数を最小限に抑えることができます。This approach minimizes the number of times users are asked to provide location information.

  • 一部の場所で使用できないリソースについては、個別のパラメーターを使用するか、場所のリテラル値を指定します。For resources that aren't available in all locations, use a separate parameter or specify a literal location value.

変数Variables

変数を使用する場合は、次の情報を活用してください。The following information can be helpful when you work with variables:

  • 変数名にはキャメル ケースを使用します。Use camel case for variable names.

  • テンプレート内で複数回使用する必要のある値には、変数を使用してください。Use variables for values that you need to use more than once in a template. 1 回しか使用しない値は、ハードコーディングすることでテンプレートが読みやすくなります。If a value is used only once, a hard-coded value makes your template easier to read.

  • テンプレート関数を複雑に組み合わせて作成する値に対して変数を使用してください。Use variables for values that you construct from a complex arrangement of template functions. 複雑な式が変数内にのみ現れるようにすると、テンプレートが読みやすくなります。Your template is easier to read when the complex expression only appears in variables.

  • テンプレートの variables セクションでは reference 関数は使用できません。You can't use the reference function in the variables section of the template. reference 関数は、リソースのランタイム状態からその値を取得します。The reference function derives its value from the resource's runtime state. ただし、変数が解決されるのは、テンプレートの初期解析時です。However, variables are resolved during the initial parsing of the template. reference 関数を必要とする値は、テンプレートの resources セクションまたは outputs セクションに直接作成してください。Construct values that need the reference function directly in the resources or outputs section of the template.

  • リソース名を表す変数は、一意である必要があります。Include variables for resource names that must be unique.

  • 変数のコピー ループを使用して、JSON オブジェクトの繰り返しパターンを作成します。Use a copy loop in variables to create a repeated pattern of JSON objects.

  • 未使用の変数を削除します。Remove unused variables.

API バージョンAPI version

リソースの種類に対してハードコーディングされた API バージョンを apiVersion プロパティに設定します。Set the apiVersion property to a hard-coded API version for the resource type. 新しいテンプレートを作成するときは、リソースの種類に最新の API バージョンを使用することをお勧めします。When creating a new template, we recommend you use the latest API version for a resource type. 使用可能な値を確認するには、テンプレートのリファレンスに関する記事をご覧ください。To determine available values, see template reference.

テンプレートが想定どおりに動作する場合は、同じ API バージョンを使用し続けることをお勧めします。When your template works as expected, we recommend you continue using the same API version. 同じ API バージョンを使用することで、新しいバージョンで導入される可能性がある破壊的変更について気にする必要はなくなります。By using the same API version, you don't have to worry about breaking changes that might be introduced in later versions.

API バージョンにパラメーターを使用しないでください。Don't use a parameter for the API version. リソースのプロパティおよび値は、API バージョンによって異なる可能性があります。Resource properties and values can vary by API version. パラメーターに API バージョンが設定されると、コード エディターの IntelliSense が適切なスキーマを決定できなくなります。IntelliSense in a code editor can't determine the correct schema when the API version is set to a parameter. テンプレート内のプロパティと一致しない API バージョンを渡した場合、デプロイは失敗します。If you pass in an API version that doesn't match the properties in your template, the deployment will fail.

API バージョンに対しては変数を使用しないでください。Don't use variables for the API version.

リソースの依存関係Resource dependencies

どのような依存関係を設定するかを決めるときは、次のガイドラインを使用してください。When deciding what dependencies to set, use the following guidelines:

  • プロパティを共有する必要があるリソース間に暗黙的な依存関係を設定するには、reference 関数を使用して、リソース名を渡します。Use the reference function and pass in the resource name to set an implicit dependency between resources that need to share a property. 暗黙的な依存関係を既に定義してある場合は、明示的な dependsOn 要素を追加しないでください。Don't add an explicit dependsOn element when you've already defined an implicit dependency. これにより、不要な依存関係が設定されるリスクを減らすことができます。This approach reduces the risk of having unnecessary dependencies. 暗黙の依存関係を設定する例については、「reference 関数と list 関数」を参照してください。For an example of setting an implicit dependency, see reference and list functions.

  • 子リソースは、その親リソースに依存するように設定します。Set a child resource as dependent on its parent resource.

  • condition 要素が false に設定されているリソースは、依存関係の順序から自動的に削除されます。Resources with the condition element set to false are automatically removed from the dependency order. 依存関係は、リソースが常にデプロイされているかのように設定してください。Set the dependencies as if the resource is always deployed.

  • 明示的に設定しなくても連鎖的な依存関係になるようにします。Let dependencies cascade without setting them explicitly. たとえば、仮想マシンが仮想ネットワーク インターフェイスに依存し、その仮想ネットワーク インターフェイスは仮想ネットワークとパブリック IP アドレスに依存しているとします。For example, your virtual machine depends on a virtual network interface, and the virtual network interface depends on a virtual network and public IP addresses. この場合、仮想マシンは、この 3 つのリソースすべての後にデプロイされますが、この仮想マシンを 3 つのリソースすべてに依存するものとして明示的に設定しないでください。Therefore, the virtual machine is deployed after all three resources, but don't explicitly set the virtual machine as dependent on all three resources. これにより依存関係の順序が明確になり、後でテンプレートを変更するのも簡単になります。This approach clarifies the dependency order and makes it easier to change the template later.

  • デプロイの前に値を指定できる場合は、依存関係なしでリソースをデプロイしてみます。If a value can be determined before deployment, try deploying the resource without a dependency. たとえば、構成値に他のリソースの名前を必要とする場合は、依存関係が不要なことがあります。For example, if a configuration value needs the name of another resource, you might not need a dependency. ただし、これは必ずしも有効であるとは限りません。リソースによっては、他のリソースが存在するかどうかを確認することがあるためです。This guidance doesn't always work because some resources verify the existence of the other resource. エラーが発生したら、依存関係を追加してください。If you receive an error, add a dependency.

リソースResources

リソースを使用する場合は、次の情報を活用してください。The following information can be helpful when you work with resources:

  • 他の共同作業者にリソースの用途がわかるように、テンプレート内の各リソースに comments を指定してください。To help other contributors understand the purpose of the resource, specify comments for each resource in the template.

    "resources": [
      {
        "name": "[variables('storageAccountName')]",
        "type": "Microsoft.Storage/storageAccounts",
        "apiVersion": "2019-06-01",
        "location": "[resourceGroup().location]",
        "comments": "This storage account is used to store the VM disks.",
          ...
      }
    ]
    
  • テンプレートで "パブリック エンドポイント" (Azure Blob Storage のパブリック エンドポイントなど) を使用する場合、名前空間は "ハードコーディングしない" でください。If you use a public endpoint in your template (such as an Azure Blob storage public endpoint), don't hard-code the namespace. 名前空間を動的に取得するには、reference 関数を使用します。Use the reference function to dynamically retrieve the namespace. そうすることで、テンプレートのエンドポイントを手作業で変更することなく、別のパブリック名前空間環境にテンプレートをデプロイできます。You can use this approach to deploy the template to different public namespace environments without manually changing the endpoint in the template. API バージョンは、テンプレートのストレージ アカウントで使用するものと同じバージョンに設定します。Set the API version to the same version that you're using for the storage account in your template.

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').primaryEndpoints.blob]"
      }
    }
    

    ストレージ アカウントが、作成しているものと同じテンプレートにデプロイされ、そのストレージ アカウントの名前がテンプレート内の別のリソースと共有されない場合、リソースを参照するときにプロバイダーの名前空間または apiVersion を指定する必要はありません。If the storage account is deployed in the same template that you're creating and the name of the storage account isn't shared with another resource in the template, you don't need to specify the provider namespace or the apiVersion when you reference the resource. 簡単な構文の例を次に示します。The following example shows the simplified syntax.

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(variables('storageAccountName')).primaryEndpoints.blob]"
      }
    }
    

    また、別のリソース グループにある既存のストレージ アカウントを参照することもできます。You also can reference an existing storage account that's in a different resource group.

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(resourceId(parameters('existingResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('existingStorageAccountName')), '2019-06-01').primaryEndpoints.blob]"
      }
    }
    
  • 仮想マシンにパブリック IP アドレスを割り当てるのは、アプリケーションで必要な場合のみにしてください。Assign public IP addresses to a virtual machine only when an application requires it. デバッグや各種管理のために仮想マシン (VM) に接続するには、受信 NAT 規則、仮想ネットワーク ゲートウェイ、またはジャンプボックスを使用してください。To connect to a virtual machine (VM) for debugging, or for management or administrative purposes, use inbound NAT rules, a virtual network gateway, or a jumpbox.

    仮想マシンへの接続の詳細については、以下の記事を参照してください。For more information about connecting to virtual machines, see:

  • パブリック IP アドレスの domainNameLabel プロパティは一意である必要があります。The domainNameLabel property for public IP addresses must be unique. domainNameLabel の値は、3 文字以上 63 文字以下で、正規表現 ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ で指定された規則に従う必要があります。The domainNameLabel value must be between 3 and 63 characters long, and follow the rules specified by this regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. uniqueString 関数は 13 文字の文字列を生成するため、dnsPrefixString パラメーターは 50 文字に制限されます。Because the uniqueString function generates a string that is 13 characters long, the dnsPrefixString parameter is limited to 50 characters.

    "parameters": {
      "dnsPrefixString": {
        "type": "string",
        "maxLength": 50,
        "metadata": {
          "description": "The DNS label for the public IP address. It must be lowercase. It should match the following regular expression, or it will raise an error: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$"
        }
      }
    },
    "variables": {
      "dnsPrefix": "[concat(parameters('dnsPrefixString'),uniquestring(resourceGroup().id))]"
    }
    
  • カスタム スクリプト拡張機能にパスワードを追加する場合は、protectedSettings プロパティで commandToExecute プロパティを使用してください。When you add a password to a custom script extension, use the commandToExecute property in the protectedSettings property.

    "properties": {
      "publisher": "Microsoft.Azure.Extensions",
      "type": "CustomScript",
      "typeHandlerVersion": "2.0",
      "autoUpgradeMinorVersion": true,
      "settings": {
        "fileUris": [
          "[concat(variables('template').assets, '/lamp-app/install_lamp.sh')]"
        ]
      },
      "protectedSettings": {
        "commandToExecute": "[concat('sh install_lamp.sh ', parameters('mySqlPassword'))]"
      }
    }
    

    注意

    シークレット情報を VM と拡張機能にパラメーターとして渡すときに暗号化されるように、関連する拡張機能の protectedSettings プロパティを使用する必要があります。To ensure that secrets are encrypted when they are passed as parameters to VMs and extensions, use the protectedSettings property of the relevant extensions.

  • 時間の経過と共に変わる可能性のある既定値を持つプロパティに対して明示的な値を指定します。Specify explicit values for properties that have default values that could change over time. たとえば、AKS クラスターをデプロイする場合、kubernetesVersion プロパティは指定することも省略することもできます。For example, if you are deploying an AKS cluster, you can either specify or omit the kubernetesVersion property. これを指定しない場合、クラスターは既定では N-1 マイナー バージョンと最新のパッチに設定されます。If you don't specify it, then the cluster is defaulted to the N-1 minor version and latest patch. ARM テンプレートを使用してクラスターをデプロイする場合、この既定の動作は想定どおりにならないことがあります。When you deploy the cluster using an ARM template, this default behavior might not be what you expect. ご利用のテンプレートを再デプロイすると、クラスターが予期せずに新しい Kubernetes バージョンにアップグレードされる可能性があります。Redeploying your template may result in the cluster being upgraded to a new Kubernetes version unexpectedly. このため、ご利用のクラスターをアップグレードする準備ができたら、明示的なバージョン番号を指定して、手動で変更することを検討してください。Instead, consider specifying an explicit version number and then manually changing it when you are ready to upgrade your cluster.

テスト ツールキットの使用Use test toolkit

ARM テンプレート テスト ツールキットは、推奨される方法がテンプレートで使用されているかどうかを確認するスクリプトです。The ARM template test toolkit is a script that checks whether your template uses recommended practices. テンプレートが推奨されるプラクティスに準拠していない場合は、推奨される変更を含む警告の一覧が返されます。When your template isn't compliant with recommended practices, it returns a list of warnings with suggested changes. テスト ツールキットは、テンプレートにベストプラクティスを実装する方法を理解するのに役立ちます。The test toolkit can help you learn how to implement best practices in your template.

テンプレートが完成したら、テスト ツールキットを実行して、その実装を改善する方法があるかどうかを確認します。After you've completed your template, run the test toolkit to see if there are ways you can improve its implementation. 詳細については、「ARM テンプレート テスト ツールキットを使用する」を参照してください。For more information, see Use ARM template test toolkit.

次のステップNext steps