다음을 통해 공유


ARM 템플릿을 사용하여 Cloud Services(추가 지원) 배포

이 문서에서는 Azure Resource Manager 템플릿(ARM 템플릿)을 사용하여 Azure Cloud Services(추가 지원) 배포를 만드는 방법을 보여 줍니다.

필수 조건

ARM 템플릿을 사용하여 배포를 만들기 위한 필수 조건으로 다음 단계를 완료합니다.

  1. Cloud Services(추가 지원)에 대한 배포 필수 구성 요소를 검토하고 필요한 리소스를 만듭니다.

  2. Azure Portal 또는 Azure PowerShell을 사용하여 새 리소스 그룹을 만듭니다. 기존 리소스 그룹을 사용하는 경우 이 단계는 선택 사항입니다.

  3. Azure Portal 또는 Azure PowerShell을 사용하여 새 스토리지 계정을 만듭니다. 기존 스토리지 계정을 사용하는 경우 이 단계는 선택 사항입니다.

  4. Azure Portal 또는 Azure PowerShell을 사용하여 패키지(.cspkg 또는 .zip) 파일과 구성(.cscfg) 파일을 스토리지 계정에 업로드합니다. 두 파일의 SAS(공유 액세스 서명) URI를 저장하여 나중에 ARM 템플릿에 추가합니다.

  5. (선택 사항) 키 자격 증명 모음을 만들고 인증서를 업로드합니다.

    • 서비스와의 보안 통신을 위해 배포에 인증서를 첨부할 수 있습니다. 인증서를 사용하는 경우 인증서 지문을 구성(.cscfg) 파일에 지정하고 키 자격 증명 모음에 업로드해야 합니다. Azure Portal 또는 Azure PowerShell을 사용하여 키 자격 증명 모음을 만들 수 있습니다.
    • 연관된 키 자격 증명 모음은 Cloud Services(추가 지원) 배포와 동일한 지역 및 구독에 있어야 합니다.
    • 연관된 키 자격 증명 모음에는 Cloud Services(추가 지원) 리소스가 키 자격 증명 모음에서 인증서를 검색할 수 있도록 관련 권한이 있어야 합니다. 자세한 내용은 Cloud Services에 인증서 사용(추가 지원)을 참조하세요.
    • 키 자격 증명 모음은 이후 단계에서 표시되는 것처럼 ARM 템플릿의 osProfile 섹션에서 참조되어야 합니다.

Cloud Services(추가 지원) 배포

템플릿을 사용하여 Cloud Services(추가 지원)를 배포하려면 다음을 수행합니다.

참고 항목

ARM 템플릿과 매개 변수 파일을 생성하는 더 쉽고 빠른 방법은 Azure Portal을 사용하는 것입니다. Azure PowerShell을 통해 Cloud Services(추가 지원)를 만들려면 포털에서 생성된 ARM 템플릿을 다운로드할 수 있습니다.

  1. 가상 네트워크를 만듭니다. 가상 네트워크의 이름은 구성 파일(.cscfg)에 있는 가상 네트워크 참조와 일치해야 합니다. 기존 가상 네트워크를 사용하는 경우 ARM 템플릿에서 이 섹션을 생략합니다.

    "resources": [ 
        { 
          "apiVersion": "2019-08-01", 
          "type": "Microsoft.Network/virtualNetworks", 
          "name": "[parameters('vnetName')]", 
          "location": "[parameters('location')]", 
          "properties": { 
            "addressSpace": { 
              "addressPrefixes": [ 
                "10.0.0.0/16" 
              ] 
            }, 
            "subnets": [ 
              { 
                "name": "WebTier", 
                "properties": { 
                  "addressPrefix": "10.0.0.0/24" 
                } 
              } 
            ] 
          } 
        } 
    ] 
    

    새 가상 네트워크를 만드는 경우 플랫폼이 Cloud Services(추가 지원) 인스턴스를 만들기 전에 가상 네트워크를 만들도록 하려면 다음 줄을 dependsOn 섹션에 추가합니다.

    "dependsOn": [ 
            "[concat('Microsoft.Network/virtualNetworks/', parameters('vnetName'))]" 
     ] 
    
  2. 공용 IP 주소를 만들고, 필요에 따라 공용 IP 주소의 DNS 레이블 속성을 설정합니다. 고정 IP 주소를 사용하는 경우 구성(.cscfg) 파일에서 예약된 IP 주소로 참조해야 합니다. 기존 IP 주소를 사용하는 경우 이 단계를 건너뛰고 ARM 템플릿의 부하 분산 장치 구성 설정에 IP 주소 정보를 직접 추가합니다.

    "resources": [ 
        { 
          "apiVersion": "2019-08-01", 
          "type": "Microsoft.Network/publicIPAddresses", 
          "name": "[parameters('publicIPName')]", 
          "location": "[parameters('location')]", 
          "properties": { 
            "publicIPAllocationMethod": "Dynamic", 
            "idleTimeoutInMinutes": 10, 
            "publicIPAddressVersion": "IPv4", 
            "dnsSettings": { 
              "domainNameLabel": "[variables('dnsName')]" 
            } 
          }, 
          "sku": { 
            "name": "Basic" 
          } 
        } 
    ] 
    

    새 IP 주소를 만드는 경우 플랫폼이 Cloud Services(추가 지원) 인스턴스를 만들기 전에 IP 주소를 만들도록 하려면 다음 줄을 dependsOn 섹션에 추가합니다.

    "dependsOn": [ 
            "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPName'))]" 
          ] 
    
  3. Cloud Services(추가 지원) 개체를 만듭니다. 템플릿에 가상 네트워크나 공용 IP 주소를 배포하는 경우 관련 dependsOn 참조를 추가합니다.

    {
      "apiVersion": "2021-03-01",
      "type": "Microsoft.Compute/cloudServices",
      "name": "[variables('cloudServiceName')]",
      "location": "[parameters('location')]",
      "tags": {
        "DeploymentLabel": "[parameters('deploymentLabel')]",
        "DeployFromVisualStudio": "true"
      },
      "dependsOn": [
        "[concat('Microsoft.Network/virtualNetworks/', parameters('vnetName'))]",
        "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPName'))]"
      ],
      "properties": {
        "packageUrl": "[parameters('packageSasUri')]",
        "configurationUrl": "[parameters('configurationSasUri')]",
        "upgradeMode": "[parameters('upgradeMode')]"
      }
    }
    
  4. 배포에 대한 네트워크 프로필 개체를 만들고 공용 IP 주소를 부하 분산 장치의 프런트 엔드와 연결합니다. Azure 플랫폼은 자동으로 부하 분산 장치를 만듭니다.

    "networkProfile": { 
        "loadBalancerConfigurations": [ 
          { 
            "id": "[concat(variables('resourcePrefix'), 'Microsoft.Network/loadBalancers/', variables('lbName'))]", 
            "name": "[variables('lbName')]", 
            "properties": { 
              "frontendIPConfigurations": [ 
                { 
                  "name": "[variables('lbFEName')]", 
                  "properties": { 
                    "publicIPAddress": { 
                      "id": "[concat(variables('resourcePrefix'), 'Microsoft.Network/publicIPAddresses/', parameters('publicIPName'))]" 
                    } 
                  } 
                } 
              ] 
            } 
          } 
        ] 
      } 
    
  5. ARM 템플릿의 osProfile 섹션에 키 자격 증명 모음 참조를 추가합니다. 키 자격 증명 모음은 Cloud Services(추가 지원)와 관련된 인증서를 저장합니다. 키 자격 증명 모음에 인증서를 추가한 다음 구성(.cscfg) 파일에서 인증서 지문을 참조합니다. 또한 Azure Portal에서 배포용 Azure Virtual Machines에 대한 키 자격 증명 모음 액세스 정책을 설정하여 Cloud Services(추가 지원) 리소스가 키 자격 증명 모음에 비밀로 저장된 인증서를 검색할 수 있도록 합니다. 키 자격 증명 모음은 Cloud Services(추가 지원) 리소스와 동일한 지역 및 구독에 있어야 하며 고유한 이름을 가져야 합니다. 자세한 내용은 Cloud Services에 인증서 사용(추가 지원)을 참조하세요.

    "osProfile": { 
          "secrets": [ 
            { 
              "sourceVault": { 
                "id": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.KeyVault/vaults/{keyvault-name}" 
              }, 
              "vaultCertificates": [ 
                { 
                  "certificateUrl": "https://{keyvault-name}.vault.azure.net:443/secrets/ContosoCertificate/{secret-id}" 
                } 
              ] 
            } 
          ] 
        } 
    

    참고 항목

    sourceVaultARM 템플릿의 값은 키 자격 증명 모음에 대한 리소스 ID 값입니다. 키 자격 증명 모음의 속성 섹션에서 리소스 ID를 찾으면 이 정보를 가져올 수 있습니다.

    • 비밀 식별자라는 레이블이 지정된 키 자격 증명 모음의 인증서로 이동하여 certificateUrl의 값을 가져올 수 있습니다. 
    • certificateUrlhttps://{keyvault-endpoint}/secrets/{secret-name}/{secret-id}의 형식이어야 합니다.
  6. 역할 프로필을 만듭니다. ARM 템플릿의 구성(.cscfg) 파일, 정의(.csdef) 파일 및 roleProfile 섹션에서 역할 수, 각 역할의 인스턴스 수, 역할 이름 및 역할 크기가 동일한지 확인합니다.

    "roleProfile": {
      "roles": {
        "value": [
          {
            "name": "WebRole1",
            "sku": {
              "name": "Standard_D1_v2",
              "capacity": "1"
            }
          },
          {
            "name": "WorkerRole1",
            "sku": {
              "name": "Standard_D1_v2",
              "capacity": "1"
            } 
          } 
        ]
      }
    }   
    
  7. (선택 사항) Cloud Services(추가 지원) 배포에 확장 기능을 추가하려면 확장 프로필을 만듭니다. 다음 예에서는 RDP(원격 데스크톱 프로토콜) 확장과 Azure Diagnostics 확장을 추가합니다.

    참고 항목

    RDP의 암호는 8~123자여야 하며 다음 암호 복잡성 요구 사항 중 최소 3개를 충족해야 합니다.

    대문자를 포함합니다.
    소문자를 포함합니다.
    숫자를 포함합니다.
    특수 문자를 포함합니다.
    제어 문자를 포함할 수 없습니다.

        "extensionProfile": {
          "extensions": [
            {
              "name": "RDPExtension",
              "properties": {
                "autoUpgradeMinorVersion": true,
                "publisher": "Microsoft.Windows.Azure.Extensions",
                "type": "RDP",
                "typeHandlerVersion": "1.2.1",
                "settings": "<PublicConfig>\r\n <UserName>[Insert Username]</UserName>\r\n <Expiration>1/21/2022 12:00:00 AM</Expiration>\r\n</PublicConfig>",
                "protectedSettings": "<PrivateConfig>\r\n <Password>[Insert Password]</Password>\r\n</PrivateConfig>"
              }
            },
            {
              "name": "Microsoft.Insights.VMDiagnosticsSettings_WebRole1",
              "properties": {
                "autoUpgradeMinorVersion": true,
                "publisher": "Microsoft.Azure.Diagnostics",
                "type": "PaaSDiagnostics",
                "typeHandlerVersion": "1.5",
                "settings": "[parameters('wadPublicConfig_WebRole1')]",
                "protectedSettings": "[parameters('wadPrivateConfig_WebRole1')]",
                "rolesAppliedTo": [
                  "WebRole1"
                ]
              }
            }
          ]
        }
    
  8. 전체 템플릿을 검토합니다.

    {
      "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "cloudServiceName": {
          "type": "string",
          "metadata": {
            "description": "Name of the cloud service"
          }
        },
        "location": {
          "type": "string",
          "metadata": {
            "description": "Location of the cloud service"
          }
        },
        "deploymentLabel": {
          "type": "string",
          "metadata": {
            "description": "Label of the deployment"
          }
        },
        "packageSasUri": {
          "type": "securestring",
          "metadata": {
            "description": "SAS URI of the package (.cspkg) file to deploy"
          }
        },
        "configurationSasUri": {
          "type": "securestring",
          "metadata": {
            "description": "SAS URI of the configuration (.cscfg) file"
          }
        },
        "roles": {
          "type": "array",
          "metadata": {
            "description": "Roles created in the cloud service application"
          }
        },
        "wadPublicConfig_WebRole1": {
          "type": "string",
          "metadata": {
             "description": "Public configuration of the Azure Diagnostics extension"
          }
        },
        "wadPrivateConfig_WebRole1": {
          "type": "securestring",
          "metadata": {
            "description": "Private configuration of the Azure Diagnostics extension"
          }
        },
        "vnetName": {
          "type": "string",
          "defaultValue": "[concat(parameters('cloudServiceName'), 'VNet')]",
          "metadata": {
            "description": "Name of vitual network"
          }
        },
        "publicIPName": {
          "type": "string",
          "defaultValue": "contosocsIP",
          "metadata": {
            "description": "Name of public IP address"
          }
        },
        "upgradeMode": {
          "type": "string",
          "defaultValue": "Auto",
          "metadata": {
            "UpgradeMode": "UpgradeMode of the CloudService"
          }
        }
      },
      "variables": {
        "cloudServiceName": "[parameters('cloudServiceName')]",
        "subscriptionID": "[subscription().subscriptionId]",
        "dnsName": "[variables('cloudServiceName')]",
        "lbName": "[concat(variables('cloudServiceName'), 'LB')]",
        "lbFEName": "[concat(variables('cloudServiceName'), 'LBFE')]",
        "resourcePrefix": "[concat('/subscriptions/', variables('subscriptionID'), '/resourceGroups/', resourceGroup().name, '/providers/')]"
      },
      "resources": [
        {
          "apiVersion": "2019-08-01",
          "type": "Microsoft.Network/virtualNetworks",
          "name": "[parameters('vnetName')]",
          "location": "[parameters('location')]",
          "properties": {
            "addressSpace": {
              "addressPrefixes": [
                "10.0.0.0/16"
              ]
            },
            "subnets": [
              {
                "name": "WebTier",
                "properties": {
                  "addressPrefix": "10.0.0.0/24"
                }
              }
            ]
          }
        },
        {
          "apiVersion": "2019-08-01",
          "type": "Microsoft.Network/publicIPAddresses",
          "name": "[parameters('publicIPName')]",
          "location": "[parameters('location')]",
          "properties": {
            "publicIPAllocationMethod": "Dynamic",
            "idleTimeoutInMinutes": 10,
            "publicIPAddressVersion": "IPv4",
            "dnsSettings": {
              "domainNameLabel": "[variables('dnsName')]"
            }
          },
          "sku": {
            "name": "Basic"
          }
        },
        {
          "apiVersion": "2021-03-01",
          "type": "Microsoft.Compute/cloudServices",
          "name": "[variables('cloudServiceName')]",
          "location": "[parameters('location')]",
          "tags": {
            "DeploymentLabel": "[parameters('deploymentLabel')]",
            "DeployFromVisualStudio": "true"
          },
          "dependsOn": [
            "[concat('Microsoft.Network/virtualNetworks/', parameters('vnetName'))]",
            "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPName'))]"
          ],
          "properties": {
            "packageUrl": "[parameters('packageSasUri')]",
            "configurationUrl": "[parameters('configurationSasUri')]",
            "upgradeMode": "[parameters('upgradeMode')]",
            "roleProfile": {
              "roles": [
                {
                  "name": "WebRole1",
                  "sku": {
                    "name": "Standard_D1_v2",
                    "capacity": "1"
                  }
                },
                {
                  "name": "WorkerRole1",
                  "sku": {
                    "name": "Standard_D1_v2",
                    "capacity": "1"
                  }
                }
              ]
            },
            "networkProfile": {
              "loadBalancerConfigurations": [
                {
                  "id": "[concat(variables('resourcePrefix'), 'Microsoft.Network/loadBalancers/', variables('lbName'))]",
                  "name": "[variables('lbName')]",
                  "properties": {
                    "frontendIPConfigurations": [
                      {
                        "name": "[variables('lbFEName')]",
                        "properties": {
                          "publicIPAddress": {
                            "id": "[concat(variables('resourcePrefix'), 'Microsoft.Network/publicIPAddresses/', parameters('publicIPName'))]"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            },
            "osProfile": {
              "secrets": [
                {
                  "sourceVault": {
                    "id": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.KeyVault/vaults/{keyvault-name}"
                  },
                  "vaultCertificates": [
                    {
                      "certificateUrl": "https://{keyvault-name}.vault.azure.net:443/secrets/ContosoCertificate/{secret-id}"
                    }
                  ]
                }
              ]
            },
            "extensionProfile": {
              "extensions": [
                {
                  "name": "RDPExtension",
                  "properties": {
                    "autoUpgradeMinorVersion": true,
                    "publisher": "Microsoft.Windows.Azure.Extensions",
                    "type": "RDP",
                    "typeHandlerVersion": "1.2.1",
                    "settings": "<PublicConfig>\r\n <UserName>[Insert Username]</UserName>\r\n <Expiration>1/21/2022 12:00:00 AM</Expiration>\r\n</PublicConfig>",
                    "protectedSettings": "<PrivateConfig>\r\n <Password>[Insert Password]</Password>\r\n</PrivateConfig>"
                  }
                },
                {
                  "name": "Microsoft.Insights.VMDiagnosticsSettings_WebRole1",
                  "properties": {
                    "autoUpgradeMinorVersion": true,
                    "publisher": "Microsoft.Azure.Diagnostics",
                    "type": "PaaSDiagnostics",
                    "typeHandlerVersion": "1.5",
                    "settings": "[parameters('wadPublicConfig_WebRole1')]",
                    "protectedSettings": "[parameters('wadPrivateConfig_WebRole1')]",
                    "rolesAppliedTo": [
                      "WebRole1"
                  ]
                }
              }
            ]
          }
        }
       }
      ]
    }
    
  9. Cloud Services(추가 지원) 배포를 만들려면 템플릿과 매개 변수 파일을 배포하여 템플릿 파일에서 매개 변수를 정의합니다. 샘플 템플릿을 사용해보세요.

    New-AzResourceGroupDeployment -ResourceGroupName "ContosOrg" -TemplateFile "file path to your template file" -TemplateParameterFile "file path to your parameter file"