使用 ARM 模板重新部署应用程序网关时,侦听器和 SSL 证书被删除
Listeners and SSL certs are getting deleted while redeploying Application gateway with ARM template
我正在使用以下 ARM 模板创建应用程序网关。当我第一次部署它时,一切正常。当我重新部署它时(作为同一环境中持续部署的一部分)它失败了,我看到之前存在的监听器被删除,SSL 证书也被删除。
是否有任何选项可以根据标准更新 ARM 模板中存在的子资源,例如如果 SSL 证书已经存在则不更新侦听器。我正在更新一些属性,例如在创建应用程序网关后创建规则和探测,而不是使用 ARM 模板。
ARM模板供参考-
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationgateway_platform": {
"defaultValue": "",
"type": "String",
"maxLength": 6
},
"applicationgateway_location_shortname": {
"defaultValue": "",
"type": "String",
"maxLength": 3
},
"applicationgateway_project": {
"defaultValue": "",
"type": "String",
"maxLength": 6
},
"applicationgateway_environment": {
"defaultValue": "",
"type": "String",
"maxLength": 7
},
"applicationgateway_uniqueid": {
"defaultValue": "1",
"type": "String",
"maxLength": "1"
},
"vnetName": {
"type": "string",
"metadata": {
"description": "Name of the Virtual Network"
}
},
"subnetName": {
"type": "string",
"metadata": {
"description": "Name of subnet"
}
},
"vnetResourceGroup": {
"type": "string",
"defaultValue": "[resourceGroup().name]",
"metadata": {
"description": "Name of Resource group where Vnet and subnet resides"
}
},
"applicationGatewayTier": {
"type": "string",
"allowedValues": [
"Standard_v2",
"WAF_v2"
],
"defaultValue": "WAF_v2",
"metadata": {
"description": "application gateway tier"
}
},
"frontendPort": {
"type": "int",
"defaultValue": 80,
"metadata": {
"description": "application gateway front end port"
}
},
"secureFrontendPort": {
"type": "int",
"defaultValue": 443,
"metadata": {
"description": "application gateway secure front end port"
}
},
"backendPort": {
"type": "int",
"defaultValue": 80,
"metadata": {
"description": "application gateway back end port"
}
},
"applicationGatewayAutoScaleMinimumCapacity": {
"type": "int",
"defaultValue": 1,
"metadata": {
"description": "Minimum appgateway instance to be running always"
}
},
"applicationGatewayAutoScaleMaximumCapacity": {
"type": "int",
"defaultValue": 10,
"metadata": {
"description": "Maximum appgateway instance that it can scale up."
}
}
},
"variables": {
"basename": "[concat(parameters('applicationgateway_platform'), '-', parameters('applicationgateway_project'), '-', parameters('applicationgateway_location_shortname'), '-', parameters('applicationgateway_environment'))]",
"applicationGatewayName": "[concat(variables('basename'), '-ag-', parameters('applicationgateway_uniqueid'))]",
"publicIPAddressName": "[concat(variables('basename'),'-agip-',parameters('applicationgateway_uniqueid'))]",
"subnetRef": "[concat(resourceId(parameters('vnetResourceGroup'), 'Microsoft.Network/virtualNetworks', parameters('vnetName')), '/subnets/', parameters('subnetName'))]",
"publicIPRef": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]",
"webApplicationFirewallConfigurationProperties": {
"enabled": true,
"firewallMode": "Detection",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
},
"apiVersion": "2019-09-01"
},
"resources": [
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[variables('publicIPAddressName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard"
},
"zones": [],
"properties": {
"publicIPAllocationMethod": "Static",
"dnsSettings": {
"domainNameLabel": "[variables('applicationGatewayName')]"
}
}
},
{
"apiVersion": "[variables('apiVersion')]",
"name": "[variables('applicationGatewayName')]",
"type": "Microsoft.Network/applicationGateways",
"location": "[resourceGroup().location]",
"dependsOn": [
"[variables('publicIPRef')]"
],
"properties": {
"sku": {
"name": "[parameters('applicationGatewayTier')]",
"tier": "[parameters('applicationGatewayTier')]"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGatewayFrontendIP",
"properties": {
"PublicIPAddress": {
"id": "[variables('publicIPRef')]"
}
}
}
],
"frontendPorts": [
{
"name": "appGatewayFrontendPort",
"properties": {
"Port": "[parameters('frontendPort')]"
}
},
{
"name": "appGatewaySecurePort",
"properties": {
"Port": "[parameters('secureFrontendPort')]"
}
}
],
"backendAddressPools": [
{
"name": "appGatewayBackendPool",
"properties": {
"BackendAddresses": []
}
}
],
"backendHttpSettingsCollection": [
{
"name": "appGatewayBackendHttpSettings",
"properties": {
"Port": "[parameters('backendPort')]",
"Protocol": "Http",
"CookieBasedAffinity": "disabled",
"requestTimeout": 20
}
}
],
"httpListeners": [
{
"name": "appGatewayHttpListener",
"properties": {
"FrontendIpConfiguration": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/frontendPorts/appGatewayFrontendPort')]"
},
"Protocol": "Http",
"SslCertificate": null
}
}
],
"requestRoutingRules": [
{
"Name": "basicRule",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/httpListeners/appGatewayHttpListener')]"
},
"backendAddressPool": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/backendAddressPools/appGatewayBackendPool')]"
},
"backendHttpSettings": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
}
],
"enableHttp2": false,
"sslCertificates": [],
"probes": [],
"autoscaleConfiguration": {
"minCapacity": "[parameters('applicationGatewayAutoScaleMinimumCapacity')]",
"maxCapacity": "[parameters('applicationGatewayAutoScaleMaximumCapacity')]"
},
"webApplicationFirewallConfiguration": "[if(equals(toUpper(parameters('applicationGatewayTier')), 'WAF_V2'), variables('webApplicationFirewallConfigurationProperties'), json('null'))]"
}
}
]
}
默认情况下,资源管理器部署使用 incremental mode。在增量模式下,资源管理器保持不变 存在于资源组中但未在模板中指定的资源。
However, when redeploying an existing resource in incremental mode,
the outcome is different. Specify all properties for the resource,
not just the ones you're updating. A common misunderstanding is to
think properties that aren't specified are left unchanged. If you
don't specify certain properties, Resource Manager interprets the
update as overwriting those values.
因此,如果您希望在重新部署模板时保留某些属性不变,您可以在模板中指定某些属性(HTTPS 侦听器、HTTPS 规则、SSL 证书)。 Here 是一个带有应用程序网关的端到端 SSL 快速入门模板,您可以参考。
至update a resource in an Azure Resource Manager template,您可以关注link了解更多详情。
First, you must reference the resource once in the template to create
it and then reference the resource by the same name to update it
later. However, if two resources have the same name in a template,
Resource Manager throws an exception. To avoid this error, specify the
updated resource in a second template that's either linked or included
as a subtemplate using the Microsoft.Resources/deployments resource
type.
Second, you must either specify the name of the existing property to
change or a new name for a property to add in the nested template. You
must also specify the original properties and their original values.
If you fail to provide the original properties and values, Resource
Manager assumes you want to create a new resource and deletes the
original resource.
我正在使用以下 ARM 模板创建应用程序网关。当我第一次部署它时,一切正常。当我重新部署它时(作为同一环境中持续部署的一部分)它失败了,我看到之前存在的监听器被删除,SSL 证书也被删除。
是否有任何选项可以根据标准更新 ARM 模板中存在的子资源,例如如果 SSL 证书已经存在则不更新侦听器。我正在更新一些属性,例如在创建应用程序网关后创建规则和探测,而不是使用 ARM 模板。
ARM模板供参考-
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationgateway_platform": {
"defaultValue": "",
"type": "String",
"maxLength": 6
},
"applicationgateway_location_shortname": {
"defaultValue": "",
"type": "String",
"maxLength": 3
},
"applicationgateway_project": {
"defaultValue": "",
"type": "String",
"maxLength": 6
},
"applicationgateway_environment": {
"defaultValue": "",
"type": "String",
"maxLength": 7
},
"applicationgateway_uniqueid": {
"defaultValue": "1",
"type": "String",
"maxLength": "1"
},
"vnetName": {
"type": "string",
"metadata": {
"description": "Name of the Virtual Network"
}
},
"subnetName": {
"type": "string",
"metadata": {
"description": "Name of subnet"
}
},
"vnetResourceGroup": {
"type": "string",
"defaultValue": "[resourceGroup().name]",
"metadata": {
"description": "Name of Resource group where Vnet and subnet resides"
}
},
"applicationGatewayTier": {
"type": "string",
"allowedValues": [
"Standard_v2",
"WAF_v2"
],
"defaultValue": "WAF_v2",
"metadata": {
"description": "application gateway tier"
}
},
"frontendPort": {
"type": "int",
"defaultValue": 80,
"metadata": {
"description": "application gateway front end port"
}
},
"secureFrontendPort": {
"type": "int",
"defaultValue": 443,
"metadata": {
"description": "application gateway secure front end port"
}
},
"backendPort": {
"type": "int",
"defaultValue": 80,
"metadata": {
"description": "application gateway back end port"
}
},
"applicationGatewayAutoScaleMinimumCapacity": {
"type": "int",
"defaultValue": 1,
"metadata": {
"description": "Minimum appgateway instance to be running always"
}
},
"applicationGatewayAutoScaleMaximumCapacity": {
"type": "int",
"defaultValue": 10,
"metadata": {
"description": "Maximum appgateway instance that it can scale up."
}
}
},
"variables": {
"basename": "[concat(parameters('applicationgateway_platform'), '-', parameters('applicationgateway_project'), '-', parameters('applicationgateway_location_shortname'), '-', parameters('applicationgateway_environment'))]",
"applicationGatewayName": "[concat(variables('basename'), '-ag-', parameters('applicationgateway_uniqueid'))]",
"publicIPAddressName": "[concat(variables('basename'),'-agip-',parameters('applicationgateway_uniqueid'))]",
"subnetRef": "[concat(resourceId(parameters('vnetResourceGroup'), 'Microsoft.Network/virtualNetworks', parameters('vnetName')), '/subnets/', parameters('subnetName'))]",
"publicIPRef": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]",
"webApplicationFirewallConfigurationProperties": {
"enabled": true,
"firewallMode": "Detection",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
},
"apiVersion": "2019-09-01"
},
"resources": [
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[variables('publicIPAddressName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard"
},
"zones": [],
"properties": {
"publicIPAllocationMethod": "Static",
"dnsSettings": {
"domainNameLabel": "[variables('applicationGatewayName')]"
}
}
},
{
"apiVersion": "[variables('apiVersion')]",
"name": "[variables('applicationGatewayName')]",
"type": "Microsoft.Network/applicationGateways",
"location": "[resourceGroup().location]",
"dependsOn": [
"[variables('publicIPRef')]"
],
"properties": {
"sku": {
"name": "[parameters('applicationGatewayTier')]",
"tier": "[parameters('applicationGatewayTier')]"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGatewayFrontendIP",
"properties": {
"PublicIPAddress": {
"id": "[variables('publicIPRef')]"
}
}
}
],
"frontendPorts": [
{
"name": "appGatewayFrontendPort",
"properties": {
"Port": "[parameters('frontendPort')]"
}
},
{
"name": "appGatewaySecurePort",
"properties": {
"Port": "[parameters('secureFrontendPort')]"
}
}
],
"backendAddressPools": [
{
"name": "appGatewayBackendPool",
"properties": {
"BackendAddresses": []
}
}
],
"backendHttpSettingsCollection": [
{
"name": "appGatewayBackendHttpSettings",
"properties": {
"Port": "[parameters('backendPort')]",
"Protocol": "Http",
"CookieBasedAffinity": "disabled",
"requestTimeout": 20
}
}
],
"httpListeners": [
{
"name": "appGatewayHttpListener",
"properties": {
"FrontendIpConfiguration": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/frontendPorts/appGatewayFrontendPort')]"
},
"Protocol": "Http",
"SslCertificate": null
}
}
],
"requestRoutingRules": [
{
"Name": "basicRule",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/httpListeners/appGatewayHttpListener')]"
},
"backendAddressPool": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/backendAddressPools/appGatewayBackendPool')]"
},
"backendHttpSettings": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', variables('applicationGatewayName')), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
}
],
"enableHttp2": false,
"sslCertificates": [],
"probes": [],
"autoscaleConfiguration": {
"minCapacity": "[parameters('applicationGatewayAutoScaleMinimumCapacity')]",
"maxCapacity": "[parameters('applicationGatewayAutoScaleMaximumCapacity')]"
},
"webApplicationFirewallConfiguration": "[if(equals(toUpper(parameters('applicationGatewayTier')), 'WAF_V2'), variables('webApplicationFirewallConfigurationProperties'), json('null'))]"
}
}
]
}
默认情况下,资源管理器部署使用 incremental mode。在增量模式下,资源管理器保持不变 存在于资源组中但未在模板中指定的资源。
However, when redeploying an existing resource in incremental mode, the outcome is different. Specify all properties for the resource, not just the ones you're updating. A common misunderstanding is to think properties that aren't specified are left unchanged. If you don't specify certain properties, Resource Manager interprets the update as overwriting those values.
因此,如果您希望在重新部署模板时保留某些属性不变,您可以在模板中指定某些属性(HTTPS 侦听器、HTTPS 规则、SSL 证书)。 Here 是一个带有应用程序网关的端到端 SSL 快速入门模板,您可以参考。
至update a resource in an Azure Resource Manager template,您可以关注link了解更多详情。
First, you must reference the resource once in the template to create it and then reference the resource by the same name to update it later. However, if two resources have the same name in a template, Resource Manager throws an exception. To avoid this error, specify the updated resource in a second template that's either linked or included as a subtemplate using the Microsoft.Resources/deployments resource type.
Second, you must either specify the name of the existing property to change or a new name for a property to add in the nested template. You must also specify the original properties and their original values. If you fail to provide the original properties and values, Resource Manager assumes you want to create a new resource and deletes the original resource.