部署两台Azure的应用程序服务相同的应用程序服务计划
如何使用VSTS幂等持续集成/连续部署过程,当两个不同的Azure的应用服务部署到同一个应用程序服务的计划。
环境
我已经写了两
ARM TEMPLATES
其中每个部署Web应用程序到Azure的应用服务。为了部署应用程序服务,必须首先创建服务计划。
ARM TEMPLATES
当前为每个Web App创建一个独特的服务计划。我正在使用VSTS版本定义来部署每个成功的VSTS版本。即发布被设计为幂等。
当前每个网络应用都有自己的资源组,其中包含自己的应用服务计划。理想情况下,每个Web应用程序都有自己的资源组,但是应用程序服务计划可以位于其自己的资源组中(但如果可能的话)。
以下模板是用于将Web App服务部署到App Service计划的模板之一的示例。
它显示了应用程序服务计划的创建使用命名转换:
appname中-计划-q2dkkaaaaaaaa
这是通过使用创建的:
- 七字符标识符 “应用程序名称”在ARM参数文件中定义。
- 资源标识符“plan”。
- 资源组名称,它来自随机命名的存储帐户名称“q2dkkaaaaaaaa”创建时的名称。
即
例
{
"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": []
}
]
}
]
}
QUESTION
我试图执行两个ARM TEMPLATES(类似于上面的例子)部署两个不同Web Apps到同一个Servi ce计划。
显然,这两个Web Apps都必须调用相同的*资源,以确保它们都部署到相同的App Service资源名称并执行任何更改。
- 如果App Service计划存在= deploy web app。
- 如果App Service计划不存在=创建服务计划,然后部署Web应用程序。
- 如果应用程序服务计划已更改=部署服务计划更改(例如更改等级),然后部署该Web应用程序。
考虑到上面的环境描述,我有什么选择让这个工作?
- VSTS发布定义中的全局参数可能是?
- ARM TEMPLATES调用一个PowerShell脚本来创建应用服务计划?
渴望遵循最佳实践。
我希望以上内容足够详细。对不起,如果有遗漏。谢谢。
SOLUTION
在我的情况的解决方案是创建三个模板:
- 模板1创建应用程序服务计划。此ARM模板存储在BLOB容器中,可通过SAS URI访问发布管道。
- 模板2创建网络应用程序A.此模板使用LINKED TEMPLATE功能来调用和执行共享模板。
- 模板3创建Web应用程序B.此模板使用LINKED TEMPLATE功能来调用和执行共享模板。
结果
- 两个Web应用程序,然后发布到同一服务器场,共享 实例。
- 部署的幂等性保持不变。
- 任何应用程序服务计划部署和任何修改的单点事实。
- 需要在服务器场的数量上节省的钱。
例
共享服务计划 - 共享服务计划的ARM模板例如:
{
"$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模板示例模板:
{
"$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": {}
}
}
}
希望这对某人有用。
感谢 斯科特
您的需求默认支持ARM模板。基本上,如果ARM模板遇到存在的资源,它将在属性不匹配时更新资源。否则,它将使用您在ARM模板中设置的属性创建资源。
上午奥马尔,感谢您的帖子。我同意学位,但是我有ARM模板来部署2个独立的应用程序,我不想在每个应用程序中定义应用程序服务计划资源,因为任何更改都需要在模板中进行更新。任何应用程序都可以通过CI/CD过程每天部署任意次数。定义应用服务计划两次可能会导致问题。对不起,如果这在我的文章中不明确。谢谢。斯科特+1顺便说一句。 –
您可以注册一个VSTS事件来处理ARM执行作业。例如,VSTS [发布部署开始](https://www.visualstudio.com/en-us/docs/integrate/get-started/service-hooks/events#ms.vss-release.deployment-started-event)事件。 – Amor
谢谢阿莫尔,这将工作。也开始查看“LINKED TEMPLATES”https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/azure-resource-manager/resource-group-linked-templates.md。将测试此馈送和反馈结果。 –