Azure Resource Manager 템플릿 모범 사례Azure Resource Manager template best practices

이 문서에서는 Resource Manager 템플릿을 생성하는 방법에 대한 권장 사항을 제공합니다.This article gives recommendations about how to construct your Resource Manager template. 이러한 권장 사항은 템플릿을 사용하여 솔루션을 배포할 때 일반적인 문제를 방지하는 데 도움이 됩니다.These recommendations help you avoid common problems when using a template to deploy a solution.

Azure 구독을 관리하는 방법에 대한 권장 사항은 Azure 엔터프라이즈 스캐폴드: 규범적 구독 거버넌스를 참조하세요.For recommendations about how to govern your Azure subscriptions, see Azure enterprise scaffold: Prescriptive subscription governance.

모든 Azure 클라우드 환경에서 작동하는 템플릿을 빌드하는 방법에 대한 권장 사항은 클라우드 일관성에 대한 Azure Resource Manager 템플릿 개발을 참조하세요.For recommendations about how to build templates that work in all Azure cloud environments, see Develop Azure Resource Manager templates for cloud consistency.

템플릿 제한Template limits

템플릿의 크기를 4mb로 제한 하 고 각 매개 변수 파일을 64 KB로 제한 합니다.Limit the size of your template to 4 MB, and each parameter file to 64 KB. 4mb 제한은 반복 리소스 정의를 사용 하 여 확장 된 템플릿의 최종 상태와 변수 및 매개 변수의 값에 적용 됩니다.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 templates when deploying Azure resources. 매개 변수, 변수 또는 출력의 수를 줄이려면 개체에 여러 값을 결합할 수 있습니다.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 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"
       }
    },
    
  • 리소스 유형의 API 버전에 대해서는 매개 변수를 사용하지 마세요.Don't use a parameter for the API version for a resource type. 리소스 속성 및 값은 버전 번호에 따라 달라질 수 있습니다.Resource properties and values can vary by version number. API 버전이 매개 변수로 설정되면 코드 편집기의 IntelliSense에서 올바른 스키마를 확인할 수 없습니다.IntelliSense in a code editor can't determine the correct schema when the API version is set to a parameter. 대신, 템플릿에 API 버전을 하드 코드합니다.Instead, hard-code the API version in the template.

  • 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 cmdlet의 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 that they have permission to deploy to.

    "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 variables for values that you need to use more than once in a template. 값을 한 번만 사용할 경우에는 하드 코드된 값을 사용해야 템플릿을 더 쉽게 읽을 수 있습니다.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.

  • 리소스에서 apiVersion에 대해 변수를 사용하지 마세요.Don't use variables for apiVersion on a resource. API 버전은 리소스의 스키마를 결정합니다.The API version determines the schema of the resource. 종종 리소스에 대한 속성을 변경하지 않고 버전을 변경할 수 없습니다.Often, you can't change the version without changing the properties for the resource.

  • 템플릿의 변수 섹션에서 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. 템플릿의 resources 또는 outputs 섹션에서 직접 reference 함수에 필요한 값을 생성합니다.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.

리소스 종속성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.

  • 자식 리소스가 부모 리소스에 종속되도록 설정합니다.Set a child resource as dependent on its parent resource.

  • false로 설정된 condition 요소가 있는 리소스는 종속성 순서에서 자동으로 제거됩니다.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. 따라서 가상 머신은 세 가지 모든 리소스보다 나중에 배포되지만 가상 머신이 세 가지 모든 리소스에 종속된다고 명시적으로 설정하지 않습니다.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:

  • 다른 참가자들이 리소스의 용도를 이해하도록 하려면 템플릿에 각 리소스에 대한 설명을 지정합니다.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": "2016-01-01",
           "location": "[resourceGroup().location]",
           "comments": "This storage account is used to store the VM disks.",
           ...
       }
    ]
    
  • 템플릿에서 공용 엔드포인트(예: Azure Blob 스토리지 공용 엔드포인트)를 사용하는 경우 네임스페이스를 하드 코딩하지 마세요.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:

    "osDisk": {
         "name": "osdisk",
         "vhd": {
             "uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2016-01-01').primaryEndpoints.blob, variables('vmStorageAccountContainerName'), '/',variables('OSDiskName'),'.vhd')]"
         }
    }
    

    저장소 계정이 생성 중인 동일한 템플릿에서 배포되는 경우에는 리소스를 참조할 때 공급자 네임스페이스를 지정할 필요가 없습니다.If the storage account is deployed in the same template that you're creating, you don't need to specify the provider namespace when you reference the resource. 다음 예제에서는 간소화된 구문을 보여 줍니다.The following example shows the simplified syntax:

    "osDisk": {
         "name": "osdisk",
         "vhd": {
             "uri": "[concat(reference(variables('storageAccountName'), '2016-01-01').primaryEndpoints.blob, variables('vmStorageAccountContainerName'), '/',variables('OSDiskName'),'.vhd')]"
         }
    }
    

    템플릿의 다른 값을 공용 네임스페이스를 사용하도록 구성한 경우 동일한 reference 함수를 반영하도록 이러한 값을 변경합니다.If you have other values in your template that are configured to use a public namespace, change these values to reflect the same reference function. 가상 머신 진단 프로필의 storageUri 속성을 설정할 수 있습니다.For example, you can set the storageUri property of the virtual machine diagnostics profile:

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

    다른 리소스 그룹에서 기존 저장소 계정을 참조할 수도 있습니다.You also can reference an existing storage account that is in a different resource group:

    "osDisk": {
         "name": "osdisk", 
         "vhd": {
             "uri":"[concat(reference(resourceId(parameters('existingResourceGroup'), 'Microsoft.Storage/storageAccounts/', parameters('existingStorageAccountName')), '2016-01-01').primaryEndpoints.blob,  variables('vmStorageAccountContainerName'), '/', variables('OSDiskName'),'.vhd')]"
         }
    }
    
  • 애플리케이션에 필요한 경우에만 공용 IP 주소를 가상 머신에 할당합니다.Assign public IP addresses to a virtual machine only when an application requires it. 디버깅, 관리 또는 관리 목적으로 가상 컴퓨터(VM)에 연결하려면 인바운드 NAT 규칙, 가상 네트워크 게이트웨이 또는 Jumpbox를 사용합니다.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.

출력Outputs

템플릿을 사용하여 공용 IP 주소를 만드는 경우 IP 주소 및 FQDN(정규화된 도메인 이름)의 세부 정보를 반환하는 출력 섹션을 포함합니다.If you use a template to create public IP addresses, include an outputs section that returns details of the IP address and the fully qualified domain name (FQDN). 출력 값을 사용하여 배포 후 공용 IP 주소 및 FQDN에 대한 세부 정보를 쉽게 검색할 수 있습니다.You can use output values to easily retrieve details about public IP addresses and FQDNs after deployment.

"outputs": {
    "fqdn": {
        "value": "[reference(parameters('publicIPAddresses_name')).dnsSettings.fqdn]",
        "type": "string"
    },
    "ipaddress": {
        "value": "[reference(parameters('publicIPAddresses_name')).ipAddress]",
        "type": "string"
    }
}

다음 단계Next steps