使用幂等ARM模板将两个Azure应用服务部署到同一个应用服务计划

时间:2017-09-04 09:25:12

标签: azure azure-devops azure-web-app-service arm-template azure-app-service-plans

问题

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

环境

  • 我已经编写了两个ARM TEMPLATES,每个都将一个Web应用程序部署到Azure App Service。

  • 要部署App Service,必须先创建服务计划。

  • ARM TEMPLATES目前为每个网络应用程序创建一个唯一的服务计划。

  • 我正在使用VSTS发布定义来部署每个成功的VSTS版本。即释放被设计为幂等的。

  • 目前,每个网络应用都有自己的资源组,其中包含自己的应用服务计划。理想情况下,每个Web应用程序都有自己的资源组,但App Service Plan可以位于自己的资源组中(如果可能的话)。

下面的模板是用于将Web App服务部署到App Service Plan的模板之一的示例。

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

appname中-计划-q2dkkaaaaaaaa

这是使用:

创建的
  • 在ARM参数文件中定义的七个字符标识符“appname”。
  • 资源标识符“plan”。
  • 资源组名称,来自随机命名的存储帐户名称“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应用程序部署到同一个服务计划。

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

  • 如果App Service计划存在=部署Web应用程序。
  • 如果App Service计划不存在=创建服务计划,则部署Web应用程序。
  • 如果更改了App Service计划=部署服务计划更改(例如层更改),则部署Web应用程序。

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

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

热衷于遵循最佳做法。

我希望上面有足够详细的描述。对不起,如果遗漏了什么。谢谢。

2 个答案:

答案 0 :(得分:1)

ARM模板默认支持您的要求。基本上,如果ARM模板遇到存在的资源,如果属性不匹配,它将更新资源。否则,它将使用您在ARM模板中设置的属性创建资源。

答案 1 :(得分:1)

<强>解

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

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

<强> RESULT

  • 然后将这两个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 App A - 包含LINKED模板的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": {}
    }
}
}

希望这对某人有用。

由于 斯科特

<强> REF https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/azure-resource-manager/resource-group-linked-templates.md