本文介绍了使用幂等 ARM 模板将两个 Azure 应用服务部署到同一个应用服务计划的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

在使用 VSTS 幂等持续集成/持续部署流程时,如何将两个不同的 Azure 应用服务部署到同一个应用服务计划.

How to deploy two different Azure App Services to the same App Service plan when using VSTS idempotent continuous integration / continuous deployment processes.

环境

  • 我编写了两个 ARM 模板,每个模板都将 Web 应用程序部署到 Azure 应用服务.

  • I have written two ARM TEMPLATES each of which deploy a web application to Azure App Service.

为了部署应用服务,必须首先创建服务计划.

In order to deploy an App Service an Service Plan must be created first.

ARM TEMPLATES 目前为每个 Web 应用程序创建一个独特的服务计划.

The ARM TEMPLATES currently create a unique Service Plan each for each Web App.

我正在使用 VSTS 发布定义在每个成功的 VSTS 构建上进行部署.即发布被设计为幂等的.

I am using VSTS Release Definitions to deploy on each successful VSTS build. i.e releases are designed to be idempotent.

目前,每个网络应用都有自己的资源组,其中包括自己的应用服务计划.理想情况下,每个网络应用都有自己的资源组,但应用服务计划可以在自己的资源组中(如果可能的话).

Currently each web app has its own Resource Group which includes it own App Service Plan. Ideally each web app has its own Resource Group, App Service Plan can be in its own Resource Group however (if this is possible).

以下模板是用于将 Web 应用服务部署到应用服务计划的模板之一的示例.

The template below is an example of one of the templates used to deploy the Web App service to an App Service Plan.

它显示了使用命名转换创建应用服务计划:

It shows the creation of the App Service Plan using the naming conversion:

appname-Plan-q2dkkaaaaaaa

这是使用以下方法创建的:

This is created using:

  • ARM 参数文件中定义的七个字符标识符appname".
  • 资源标识符计划".
  • 资源组名称,它来自创建时随机命名的存储帐户名称q2dkkaaaaaaaa".

"hostingPlanName": "[concat(parameters('appName'),'-Plan-', uniqueString(resourceGroup().id))]",

示例

{
"parameters": {
    "appName": {
        "type": "string",
        "maxLength": 7,
        "metadata": {
            "description": "The name of the app that you wish to create."
        }
    },
    "appServicePlanSku": {
        "type": "string",
        "defaultValue": "Standard",
        "metadata": {
            "description": "The Service Plan SKU"
        }
    },
    "appServicePlanWorkerSize": {
        "type": "string",
        "defaultValue": "0",
        "metadata": {
            "description": "The App Service Plan Worker Size (?)"
        }
    },
    "appServicePlanSkuCode": {
        "type": "string",
        "defaultValue": "S1",
        "metadata": {
            "description": "The App Service Plan SKU Code"
        }
    },
    "appServicePlanNumWorkers": {
        "type": "string",
        "defaultValue": "2",
        "metadata": {
            "description": "The Number of App Service Workers."
        }

},
"variables": {
    "webAppName": "[concat(parameters('appName'),'-wa-', uniqueString(resourceGroup().id))]",
    "hostingPlanName": "[concat(parameters('appName'),'-Plan-', uniqueString(resourceGroup().id))]",
    "stageSlotName": "stageSlot",
    "devSlotName": "devSlot"
    }
},
"resources": [
    {
        "apiVersion": "2016-09-01",
        "name": "[variables('hostingPlanName')]",
        "type": "Microsoft.Web/serverfarms",
        "location": "[resourceGroup().location]",
        "properties": {
            "name": "[variables('hostingPlanName')]",
            "workerSizeId": "[parameters('appServicePlanWorkerSize')]",
            "numberOfWorkers": "[parameters('appServicePlanNumWorkers')]"
        },
        "sku": {
            "Tier": "[parameters('appServicePlanSku')]",
            "Name": "[parameters('appServicePlanSkuCode')]"
        },
        "dependsOn": []
    },
    {
        "apiVersion": "2015-08-01",
        "type": "Microsoft.Web/sites",
        "name": "[variables('webAppName')]",
        "location": "[resourceGroup().location]",
        "kind": "webapp",
        "tags": {
            "Environment": "production",
            "displayName": "WebAppService"
        },
        "dependsOn": [
            "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
        ],
        "properties": {
            "name": "[variables('webAppName')]",
            "serverFarmId": "[resourceId('Microsoft.Web/serverfarms',variables('hostingPlanName'))]"
        },
        "resources": [
            {
                "name": "slotConfigNames",
                "type": "config",
                "apiVersion": "2015-08-01",
                "dependsOn": [
                    "[resourceId('Microsoft.Web/sites', variables('webAppName'))]"
                ],
                "tags": {
                    "displayName": "slotConfigNames"
                },
                "properties": {
                    "appSettingNames": []
                }
            },
            {
                "apiVersion": "2015-08-01",
                "name": "[variables('stageSlotName')]",
                "type": "slots",
                "location": "[resourceGroup().location]",
                "dependsOn": [
                    "[resourceId('Microsoft.Web/sites', variables('webAppName'))]"],
                "properties": {},
                "resources": []
            },
            {
                "apiVersion": "2015-08-01",
                "name": "[variables('devSlotName')]",
                "type": "slots",
                "location": "[resourceGroup().location]",
                "dependsOn": [
                    "[resourceId('Microsoft.Web/sites', variables('webAppName'))]"],
                "properties": {},
                "resources": []
            }
        ]
    }
]
}

问题

我正在尝试执行两个 ARM 模板(类似于上面的示例)以将两个不同的 Web 应用程序部署到同一个服务计划.

I am attempting to execute two ARM TEMPLATES (similar to the above example) to deploy two different Web Apps to the same Service Plan.

很明显,这两个 Web 应用必须调用相同的中央资源,以确保它们都部署到相同的应用服务资源名称并执行任何更改.

Its clear that both of these Web Apps must call the same central resource to ensure they both deploy to same App Service resource name and execute any changes.

  • 如果应用服务计划存在 = 部署网络应用.
  • 如果应用服务计划不存在 = 创建服务计划,然后部署网络应用.
  • 如果更改应用服务计划 = 部署服务计划更改(例如层级更改),然后部署网络应用.

考虑到上面的环境描述,我有什么选择才能让它工作?

Taking the environmental description above into consideration , what options do I have to get this working?

  • 可能是发布定义中的 VSTS 全局参数?
  • ARM TEMPLATES 调用创建应用服务计划的 PowerShell 脚本?

热衷于遵循最佳实践.

我希望上面的描述足够详细.抱歉,如果遗漏了什么.谢谢.

I hope the above is described in enough detail. Sorry if something has been missed. Thank you.

推荐答案

解决方案

我的解决方案是创建三个模板:

The solution in my case was to create three templates:

  • 用于创建应用服务计划的模板 1.此 ARM 模板存储在 BLOB 容器中,发布管道可通过 SAS URI 访问.
  • 用于创建网络应用 A 的模板 2.此模板使用链接模板功能来调用和执行共享模板.
  • 用于创建网络应用 B 的模板 3.此模板使用链接模板功能来调用和执行共享模板.

结果

  • 然后,两个 Web 应用程序都发布到同一个服务器场,共享实例.
  • 保持部署的幂等性.
  • 任何应用服务计划部署和任何修订的单一事实.
  • 节省了所需服务器群数量.

示例

共享服务计划 - 共享服务计划的 ARM 模板示例:

Shared Service Plan - ARM Template example of a shared service plan:

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
    "planLabel": {
        "defaultValue": "shared-service-plan",
        "type": "string"
    }
},
"variables": {
    "servicePlanName": "[concat(parameters('planLabel'),'-Plan-', uniqueString(resourceGroup().id))]"
},
"resources": [
    {
        "comments": "Creates an App Service Plan on the Standard (S1) SKU.",
        "type": "Microsoft.Web/serverfarms",
        "sku": {
            "name": "S1",
            "tier": "Standard",
            "size": "S1",
            "family": "S",
            "capacity": 2
        },
        "kind": "app",
        "name": "[variables('servicePlanName')]",
        "apiVersion": "2016-09-01",
        "location": "[resourceGroup().location]",
        "properties": {
            "name": "[variables('servicePlanName')]"
        },
        "dependsOn": []
    }
],
"outputs": {
    "servicePlanResourceId": {
        "type": "string",
        "value": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]"
    },
    "servicePlanName":{
        "type": "string",
        "value": "[variables('servicePlanName')]"
    },
    "resourceGroupName":{
        "type": "string",
        "value": "[resourceGroup().name]"
    }
}
}

Web 应用程序 A - 包含链接模板的 ARM 模板示例:

Web App A - ARM Template Example containing LINKED TEMPLATE:

{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
    "servicePlanLabel": {
        "type": "string",
        "metadata": {
            "description": "The base name for the App Service Plan to be used in the linked template."
        },
        "defaultValue": "plan"
    },
    "appServicePlanResourceGroup": {
        "type": "string",
        "metadata": {
            "Description": "The name of the Resource Group the shared App Service Plan will be deployed to."
        },
        "defaultValue": "group"
    },
    "appServicePlanTemplateUri": {
        "type": "string",
        "metadata": {
            "description": "The URI to the App Service Plan linked template in BLOB"
        }
    }
},
"variables": {},
"resources": [
    {
        "apiVersion": "2017-05-10",
        "name": "appServicePlanTemplate",
        "type": "Microsoft.Resources/deployments",
        "resourceGroup": "[parameters('appServicePlanResourceGroup')]",
        "properties": {
            "mode": "Incremental",
            "templateLink": {
                "uri": "[parameters('appServicePlanTemplateUri')]",
                "contentVersion": "1.0.0.0"
            },
            "parameters": {
                "planLabel": {
                    "value": "[parameters('servicePlanLabel')]"
                }
            }
        }
    },
    {
        "apiVersion": "2015-08-01",
        "type": "Microsoft.Web/sites",
        "name": "[variables('webAppName')]",
        "location": "[resourceGroup().location]",
        "kind": "webapp",
        "tags": {
            "Environment": "production",
            "displayName": "App"
        },
        "dependsOn": [
            "[resourceId(parameters('appServicePlanResourceGroup'), 'Microsoft.Resources/deployments', 'appServicePlanTemplate')]"
        ],
        "properties": {}
    }
}
}

希望这对某人有用.

谢谢斯科特

参考https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/azure-resource-manager/resource-group-linked-templates.md

这篇关于使用幂等 ARM 模板将两个 Azure 应用服务部署到同一个应用服务计划的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 20:24