Hopefully someone can help there.
I am trying to integrate Azure Application Gateway with Key Vault using ARM template and getting an issue:
SecretIdSpecifiedIsInvalid: SecretId '==' specified in '/subscriptions/xxxx-xxxx-xxxx-xxxx-xxxx/resourceGroups/rg-ProjectX-dev-infra/providers/Microsoft.Network/applicationGateways/appgw-ProjectX-dev/sslCertificates/appGwSslCert' is invalid. []
User assigned managed identity of Application Gateway has proper permissions ('Get' and 'List' under secrets and certificates) in Azure Key Vault.
Certificate is self-signed and generated in Azure Key Vault. It works as expected if I add certificate using Azure portal but it fails to add using ARM template.
The following guides were used during deployment:
TLS termination with Key Vault certificates and Pass sensitive values
Parameters.json file:
"app-gateway-httpsvaultCert": {
"reference": {
"keyVault": {
"id": "/subscriptions/xxxx-xxxx-xxxx-xxxx-xxxx/resourceGroups/rg-projeX-dev-infra/providers/Microsoft.KeyVault/vaults/kv-ProjectX-dev"
},
"secretName": "zzz-zzz-zzz-zzz"
}
},
Defined parameter as secure string in the template file:
"app-gateway-httpsvaultCert": {
"type": "securestring",
"metadata": {
"description": "Secure access string from Azure Application Gateway to Key Vault."
}
},
Template.json file:
{
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2020-11-01",
"name": "[variables('app-gateway-name')]",
"location": "[parameters('location')]",
"tags": "[parameters('resource-Tags')]",
"dependsOn": [
"[resourceId('Microsoft.Insights/components', variables('app-insights-name'))]",
"[resourceId('Microsoft.Network/publicIPAddresses', variables('public-ip-name'))]",
"[resourceId('Microsoft.Network/virtualNetworks', variables('vnet-name'))]",
"[resourceId('Microsoft.KeyVault/vaults', variables('kv-name'))]"
],
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('appgw-managed-id'))]": {
}
}
},
"properties": {
"sku": {
"name": "Standard_v2",
"tier": "Standard_v2",
"capacity": "[parameters('app-gateway-capacity')]"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vnet-name'), 'appgw-subnet')]"
}
}
}
],
"sslCertificates": [
{
"name": "appGwSslCert",
"properties": {
"keyVaultSecretId": "[parameters('app-gateway-httpsvaultCert')]"
}
}
],
"trustedRootCertificates": [],
"frontendIPConfigurations": [
{
"name": "appGwPublicFrontendIp",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('public-ip-name'))]"
}
}
}
],
"frontendPorts": [
{
"name": "port_443",
"properties": {
"port": 443
}
}
],
"backendAddressPools": [
{
"name": "gatewayBackEnd",
"properties": {
"backendAddresses": [
{
"fqdn": "[concat(variables('apim-name'), '.azure-api.net')]"
},
{
"fqdn": "[concat(variables('fr-name'), '.cognitiveservices.azure.com')]"
}
]
}
}
],
"backendHttpSettingsCollection": [
{
"name": "global-gateway-https-setting",
"properties": {
"port": 443,
"protocol": "Https",
"cookieBasedAffinity": "Disabled",
"pickHostNameFromBackendAddress": true,
"requestTimeout": 20,
"probe": {
"id": "[resourceId('Microsoft.Network/applicationGateways/probes', variables('app-gateway-name'), 'global-gateway-probe')]"
}
}
}
],
"httpListeners": [
{
"name": "global-listener-https",
"properties": {
"frontendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/applicationGateways/frontEndIPConfigurations', variables('app-gateway-name'), 'appGwPublicFrontendIp')]"
},
"frontendPort": {
"id": "[resourceId('Microsoft.Network/applicationGateways/frontEndPorts', variables('app-gateway-name'), 'port_443')]"
},
"protocol": "Https",
"sslCertificate": {
"id": "[resourceId('Microsoft.Network/applicationGateways/sslCertificates', variables('app-gateway-name'), 'appGwSslCert')]"
},
"hostNames": [],
"requireServerNameIndication": false
}
}
],
"urlPathMaps": [],
"requestRoutingRules": [
{
"name": "global-routing-rule",
"properties": {
"ruleType": "Basic",
"httpListener": {
"id": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('app-gateway-name'), 'global-listener-https')]"
},
"backendAddressPool": {
"id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('app-gateway-name'), 'gatewayBackEnd')]"
},
"backendHttpSettings": {
"id": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('app-gateway-name'), 'global-gateway-https-setting')]"
}
}
}
],
"probes": [
{
"name": "global-gateway-probe",
"properties": {
"protocol": "Https",
"port": 443,
"path": "/status-0123456789abcdef",
"interval": 30,
"timeout": 30,
"unhealthyThreshold": 3,
"pickHostNameFromBackendHttpSettings": true,
"minServers": 0
}
}
],
"rewriteRuleSets": [],
"redirectConfigurations": [],
"privateLinkConfigurations": [],
"sslPolicy": {
"policyType": "Predefined",
"policyName": "AppGwSslPolicy20170401S"
},
"enableHttp2": true
}
},
An issue has been fixed changing template.json and parameters.json files accordingly:
Template.json:
"app-gateway-httpsvaultCert": {
"type": "String",
"defaultValue": "https://[KeyVaultName].vault.azure.net/secrets/[CertName]",
"metadata": {
"description": "The base-64 encoded SSL certificate PFX data. Must be supplied via a parameters file references to a Key Vault / Secret Name."
}
}
Parameters.json:
"app-gateway-httpsvaultCert": {
"value":
"https://[KeyVaultName].vault.azure.net/secrets/[CertName]"
}
Related
Getting error while deploying App gateway waf_v2 with more then one listener. For single listner it is working fine.
Error :
{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"BadRequest","message":"{\r\n "error": {\r\n "code": "ApplicationGatewayHttpListenersUsingSameFrontendPortAndFrontendIpConfig",\r\n "message": "Two Http Listeners of Application Gateway journal-listner and attachmentmgmt-listner are using the same Frontend Port /subscriptions/77585cb5-cc1b-47a6-b60d-4c1ec4b078fc/resourceGroups/drgr001appgatewaydevtest-au/providers/Microsoft.Network/applicationGateways/bo-appgw-waf-v2-entdev1/frontendPorts/frontendPorts and FrontendIpConfiguration /subscriptions/77585cb5-cc1b-47a6-b60d-4c1ec4b078fc/resourceGroups/drgr001appgatewaydevtest-au/providers/Microsoft.Network/applicationGateways/bo-appgw-waf-v2-entdev1/frontendIPConfigurations/PrivateFrontendIp.",\r\n "details": []\r\n }\r\n}"}]}
template code :
// Application Gateway
{
"name": "[parameters('applicationGatewayName')]",
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2020-03-01",
"location": "[parameters('location')]",
"zones": "[parameters('availabilityZones')]",
"properties": {
"sku": {
"name": "WAF_v2",
"tier": "WAF_v2",
"capacity": "[parameters('capacity')]"
},
"sslCertificates": [
{
"name": "[parameters('certName')]",
"properties": {
"data": "[parameters('certData')]",
"password": "[parameters('certPassword')]"
}
}
],
"gatewayIPConfigurations": [
{
"name": "gatewayIp",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"trustedRootCertificates": "[parameters('trustedRootCertificates')]",
"frontendIPConfigurations": [
{
"name": "PublicFrontendIp",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[parameters('publicIpResourceId')]"
}
}
},
{
"name": "PrivateFrontendIp",
"properties": {
"privateIPAddress": "[parameters('privateIPAddress')]",
"privateIPAllocationMethod": "Static",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"frontendPorts": [
{
"name": "frontendPorts",
"properties": {
"Port": 443
}
}
],
"backendAddressPools": "[parameters('backendAddressPools')]",
"probes": "[parameters('probes')]",
"copy": [
{
"name": "backendHttpSettingsCollection",
"count": "[length(parameters('backendHttpSettings'))]",
"input": {
"name": "[parameters('backendHttpSettings')[copyIndex('backendHttpSettingsCollection')].name]",
"properties": {
"port": 443,
"pickHostNameFromBackendAddress": true,
"protocol": "Https",
"probeEnabled": "[parameters('backendHttpSettings')[copyIndex('backendHttpSettingsCollection')].probeEnabled]",
"probe": {
"id": "[resourceId('Microsoft.Network/applicationGateways/probes', parameters('applicationGatewayName'), parameters('backendHttpSettings')[copyIndex('backendHttpSettingsCollection')].probe)]"
}
}
}
},
{
"name": "httpListeners",
"count": "[length(parameters('httpListeners'))]",
"input": {
"name": "[parameters('httpListeners')[copyIndex('httpListeners')].name]",
"properties": {
"protocol": "Https",
// Set hostname if it exists
"hostName": "[if(contains(parameters('httpListeners')[copyIndex('httpListeners')], 'hostName'), parameters('httpListeners')[copyIndex('httpListeners')].hostName, '')]",
"sslCertificate": {
"id": "[concat(variables('applicationGatewayId'), '/sslCertificates/',parameters('httpListeners')[copyIndex('httpListeners')].sslCertificateName)]"
},
"frontendIPConfiguration": {
"id": "[concat(variables('applicationGatewayId'), '/frontendIPConfigurations/PrivateFrontendIp')]"
},
"frontendPort": {
"id": "[concat(variables('applicationGatewayId'), '/frontendPorts/frontendPorts')]"
}
}
}
},
{
"name": "requestRoutingRules",
"count": "[length(parameters('requestRoutingRules'))]",
"input": {
"name": "[parameters('requestRoutingRules')[copyIndex('requestRoutingRules')].name]",
"properties": {
"ruleType": "Basic",
"backendAddressPool": {
"id": "[concat(variables('applicationGatewayId'), '/backendAddressPools/',parameters('requestRoutingRules')[copyIndex('requestRoutingRules')].backendpoolName)]"
},
"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayId'), '/backendHttpSettingsCollection/',parameters('requestRoutingRules')[copyIndex('requestRoutingRules')].backendHttpSetting)]"
},
"httpListener": {
"id": "[concat(variables('applicationGatewayId'), '/httpListeners/',parameters('requestRoutingRules')[copyIndex('requestRoutingRules')].httpListener)]"
}
}
}
}
],
"redirectConfigurations": "[parameters('redirectConfigurations')]",
"enableHttp2": "[parameters('enableHttp2')]",
"webApplicationFirewallConfiguration": "[variables('webApplicationFirewallConfiguration')]",
"urlPathMaps": "[parameters('urlPathMaps')]",
"authenticationCertificates": "[parameters('authenticationCertificates')]",
"sslPolicy": {
"policyType": "Predefined",
"policyName": "AppGwSslPolicy20170401S"
},
"rewriteRuleSets": "[parameters('rewriteRuleSets')]"
}
}
Parameter used :
"backendHttpSettings": {
"value": [
{
"name": "https-attachment",
"probeEnabled": true,
"probe": "attachment-probe"
},
{
"name": "https-journal",
"probeEnabled": true,
"probe": "journal-probe"
}
]
},
"backendAddressPools": {
"value": [
{
"name": "AttachmentServicePool",
"properties": {
"backendAddresses": [
{
"fqdn": "attachmentmgmt-svc-api-dev-euw.aseentdev.sys.dom"
}
]
}
},
{
"name": "journalServicePool",
"properties": {
"backendAddresses": [
{
"fqdn": "journalmgmt-svc-api-dev-euw.aseentdev.sys.dom"
}
]
}
}
]
},
"availabilityZones": {
"value": [
1,
2
]
},
"probes": {
"value": [
{
"name": "attachment-probe",
"properties": {
"protocol": "Https",
"PickHostNameFromBackendHttpSettings": true,
"path": "/index.htm",
"interval": 5,
"timeout": 10,
"match": {
"statusCodes": [
200
],
"body": "SUCCESS"
}
}
},
{
"name": "journal-probe",
"properties": {
"protocol": "Https",
"PickHostNameFromBackendHttpSettings": true,
"path": "/index.htm",
"interval": 5,
"timeout": 10,
"match": {
"statusCodes": [
200
],
"body": "SUCCESS"
}
}
}
]
},
"httpListeners": {
"value": [
{
"name": "attachmentmgmt-listner",
"sslCertificateName": "abc"
},
{
"name": "journal-listner",
"sslCertificateName": "abc"
}
]
},
"urlPathMaps": {
"value": []
},
"requestRoutingRules": {
"value": [
{
"name": "attachment-routing-rule",
"backendpoolName": "AttachmentServicePool",
"backendHttpSetting": "https-attachment",
"httpListener": "attachmentmgmt-listner"
},
{
"name": "journal-routing-rule",
"backendpoolName": "journalServicePool",
"backendHttpSetting": "https-journal",
"httpListener": "journal-listner"
}
]
},
You can't create two basic listeners on the same port. Either use different ports or two different hostnames with Multi site listener.
change in parameter file with passing host name for httplistner worked fine.
"httpListeners": {
"value": [
{
"name": "listner1",
"sslCertificateName": "ABC",
"hostName": "wb.abc.dom"
},
{
"name": "listner2",
"sslCertificateName": "ABC",
"hostName": "wb1.abc.dom"
}
]
}
I am trying to configure Azure Application Gateway with Basic Rule. For my Frontend IP, I have created set DNS name to whatever.canadacentral.cloudapp.azure.com and uploaded a self-signed certificate. When I hit https:// everything works correctly however when I go to https://whatever.canadacentral.cloudapp.azure.com it returns 307 redirecting me to my backend pool https://whatever.azurewebsites.net/
Is this something to do with canadacentral.cloudapp.azure.com and I need to provide custom DNS?
Here's my template for Application Gateway:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationGateways_ExampleDev_name": {
"defaultValue": "ExampleDev",
"type": "String"
},
"virtualNetworks_Ex_DEV_externalid": {
"defaultValue": "/subscriptions/xxx/resourceGroups/Example-Ex-DEV/providers/Microsoft.Network/virtualNetworks/Ex-DEV",
"type": "String"
},
"publicIPAddresses_ExampleDevIP_externalid": {
"defaultValue": "/subscriptions/xxx/resourceGroups/Example-Ex-DEV/providers/Microsoft.Network/publicIPAddresses/ExampleDevIP",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2019-09-01",
"name": "[parameters('applicationGateways_ExampleDev_name')]",
"location": "canadacentral",
"properties": {
"sku": {
"name": "WAF_v2",
"tier": "WAF_v2"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[concat(parameters('virtualNetworks_Ex_DEV_externalid'), '/subnets/default')]"
}
}
}
],
"sslCertificates": [
{
"name": "ApplicationGateway",
"properties": {}
}
],
"trustedRootCertificates": [],
"frontendIPConfigurations": [
{
"name": "appGwPublicFrontendIp",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[parameters('publicIPAddresses_ExampleDevIP_externalid')]"
}
}
}
],
"frontendPorts": [
{
"name": "port_80",
"properties": {
"port": 80
}
},
{
"name": "port_443",
"properties": {
"port": 443
}
}
],
"backendAddressPools": [
{
"name": "ExampleApiDev",
"properties": {
"backendAddresses": [
{
"fqdn": "Exampleapi-dev.azurewebsites.net"
}
]
}
},
{
"name": "ExampleAuthDev",
"properties": {
"backendAddresses": [
{
"fqdn": "Exampleauth-dev.azurewebsites.net"
}
]
}
},
{
"name": "ExampleAppDev",
"properties": {
"backendAddresses": [
{
"fqdn": "Exampleapp-dev.azurewebsites.net"
}
]
}
}
],
"backendHttpSettingsCollection": [
{
"name": "default",
"properties": {
"port": 80,
"protocol": "Http",
"cookieBasedAffinity": "Disabled",
"pickHostNameFromBackendAddress": true,
"affinityCookieName": "ApplicationGatewayAffinity",
"requestTimeout": 20,
"probe": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateways_ExampleDev_name')), '/probes/defaultxxx')]"
}
}
}
],
"httpListeners": [
{
"name": "public-https",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateways_ExampleDev_name')), '/frontendIPConfigurations/appGwPublicFrontendIp')]"
},
"frontendPort": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateways_ExampleDev_name')), '/frontendPorts/port_443')]"
},
"protocol": "Https",
"sslCertificate": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateways_ExampleDev_name')), '/sslCertificates/ApplicationGateway')]"
},
"hostNames": [],
"requireServerNameIndication": false
}
}
],
"urlPathMaps": [],
"requestRoutingRules": [
{
"name": "basic",
"properties": {
"ruleType": "Basic",
"httpListener": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateways_ExampleDev_name')), '/httpListeners/public-https')]"
},
"backendAddressPool": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateways_ExampleDev_name')), '/backendAddressPools/ExampleApiDev')]"
},
"backendHttpSettings": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateways_ExampleDev_name')), '/backendHttpSettingsCollection/default')]"
}
}
}
],
"probes": [
{
"name": "default07a3e3ac-3c07-40f6-ad80-837f4cdd1009",
"properties": {
"protocol": "Http",
"path": "/swagger/index.html",
"interval": 30,
"timeout": 30,
"unhealthyThreshold": 3,
"pickHostNameFromBackendHttpSettings": true,
"minServers": 0,
"match": {
"statusCodes": [
"200-399"
]
}
}
}
],
"rewriteRuleSets": [],
"redirectConfigurations": [],
"webApplicationFirewallConfiguration": {
"enabled": true,
"firewallMode": "Prevention",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0",
"disabledRuleGroups": [],
"exclusions": [],
"requestBodyCheck": true,
"maxRequestBodySizeInKb": 128,
"fileUploadLimitInMb": 50
},
"enableHttp2": false,
"autoscaleConfiguration": {
"minCapacity": 0,
"maxCapacity": 2
}
}
}
]
}
In this case, for application gateway V2, you have two solutions from this document.
Rewrite the location header
Set the host name in the location header to the application gateway's
domain name. To do this, create a rewrite rule with a condition that
evaluates if the location header in the response contains
azurewebsites.net. It must also perform an action to rewrite the
location header to have the application gateway's host name.
Use a custom domain name
In this way, you must own a custom domain and add custom domain in app servvice, see Map an existing custom DNS name to Azure App Service. You could follow this process:
I have a working ARM Template to deploy an Application Gateway with WAF Enabled, this is currently always enabling the Firewall and setting the Firewall Mode based on parameters.
We want to parameterize enabling the WAF so that an AGW can be deployed without WAF
The object in the properties looks like:
"webApplicationFirewallConfiguration": {
"enabled": "[parameters('applicationGateway').firewallEnabled]",
"firewallMode": "[parameters('applicationGateway').firewallMode]",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
}
The parameter file has these set:
"firewallEnabled": false,
"Tier": "Standard",
"skuSize": "Standard_Medium",
However on deployment it errors out trying to enable the Firewall
New-AzResourceGroupDeployment : 11:28:27 AM - Error:
Code=ApplicationGatewayFirewallCannotBeEnabledForSelectedSku;
Message=Application Gateway
/subscriptions//providers/Microsoft.Network/applicationGatewa
ys/EXAMPLE-AGW does not support WebApplicationFirewall with the
selected SKU tier Standard
It looks like it's still trying to enable the firewall even though the "enabled:" property would be false, I would assume it would ignore the rest of the properties in the object but obviously not. Can anyone see what I'm doing wrong here?
Reason for Failure: As WebApplicationFirewall is not supported for Standard Tier AppGateway, the template VALIDATION will fail even if enabled is set to false as validation sees "webApplicationFirewallConfiguration" key itself as invalid for Standard Tier.
Fix: Use Nested Templates to create a child deployment of an Application Gateway template without "webApplicationFirewallConfiguration" if firewall is disabled, else the one with "webApplicationFirewallConfiguration" if firewall is enabled along with firewall mode value in the parameters file.
Working Sample: Please find below the root template for deployment along with two templates with firewall enabled and disabled as well. Then, it has two parameters file - one for firewall enabled and other for disabled one.
To try out this sample, follow the below steps:
Upload the two Child templates in a Blob Storage.
Make this Blob Container, where templates are uploaded, Public accessible or use SAS token while creating the template's url.
Update the variables "appGatewaysTemplateWaffalse" and "appGatewaysTemplateWaftrue" in root template with urls of uploaded child templates.
Go https://portal.azure.com/#create/Microsoft.Template -> "Build your own template in the editor".
Use this updated root template with urls and the parameter file (enabled or disabled) as desired.
Root Template (VNet + Child Deployment):
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationGateway": {
"type": "object",
"metadata": {
"description": "Application gateway specific information"
}
},
"virtualNetworkName": {
"type": "string",
"metadata": {
"description": "virtual network name"
}
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16",
"metadata": {
"description": "virtual network address range"
}
},
"subnetName": {
"type": "string",
"defaultValue": "subnet1",
"metadata": {
"description": "Subnet Name"
}
},
"subnetPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/24",
"metadata": {
"description": "Subnet prefix"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {
"subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]",
"appGatewaysTemplateWaffalse": "https://da2.blob.core.windows.net/templates/app-gateway-waf-false.json",
"appGatewaysTemplateWaftrue": "https://da2.blob.core.windows.net/templates/app-gateway-waf-true.json"
},
"resources": [
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"addressPrefix": "[parameters('subnetPrefix')]"
}
}
]
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"name": "azure-appGateways-non-waf-deployment",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables(concat('appGatewaysTemplateWaf',string(parameters('applicationGateway').firewallEnabled)))]"
},
"parameters": {
"applicationGateway": {
"value": "[parameters('applicationGateway')]"
},
"location": {
"value": "[parameters('location')]"
},
"subnetRef": {
"value": "[variables('subnetRef')]"
}
}
}
}
]
}
Child Template without webApplicationFirewallConfiguration:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationGateway": {
"type": "object",
"metadata": {
"description": "Application gateway specific information"
}
},
"subnetRef": {
"type": "string",
"defaultValue": "subnet id",
"metadata": {
"description": "Subnet Id"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {},
"resources": [
{
"apiVersion": "2017-06-01",
"name": "[parameters('applicationGateway').applicationGatewayName]",
"type": "Microsoft.Network/applicationGateways",
"location": "[parameters('location')]",
"dependsOn": [],
"properties": {
"sku": {
"name": "[parameters('applicationGateway').applicationGatewaySize]",
"tier": "[parameters('applicationGateway').skuTier]",
"capacity": "[parameters('applicationGateway').applicationGatewayInstanceCount]"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[parameters('subnetRef')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGatewayFrontendIP",
"properties": {
"subnet": {
"id": "[parameters('subnetRef')]"
}
}
}
],
"frontendPorts": [
{
"name": "appGatewayFrontendPort",
"properties": {
"Port": "[parameters('applicationGateway').frontendPort]"
}
}
],
"backendAddressPools": [
{
"name": "appGatewayBackendPool",
"properties": {
"BackendAddresses": "[parameters('applicationGateway').backendIPAddresses]"
}
}
],
"backendHttpSettingsCollection": [
{
"name": "appGatewayBackendHttpSettings",
"properties": {
"Port": "[parameters('applicationGateway').backendPort]",
"Protocol": "Http",
"CookieBasedAffinity": "[parameters('applicationGateway').cookieBasedAffinity]"
}
}
],
"httpListeners": [
{
"name": "appGatewayHttpListener",
"properties": {
"FrontendIpConfiguration": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/frontendPorts/appGatewayFrontendPort')]"
},
"Protocol": "Http",
"SslCertificate": null
}
}
],
"requestRoutingRules": [
{
"Name": "rule1",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/httpListeners/appGatewayHttpListener')]"
},
"backendAddressPool": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/backendAddressPools/appGatewayBackendPool')]"
},
"backendHttpSettings": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
}
]
}
}
]
}
Child Template with webApplicationFirewallConfiguration:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationGateway": {
"type": "object",
"metadata": {
"description": "Application gateway specific information"
}
},
"subnetRef": {
"type": "string",
"defaultValue": "subnet id",
"metadata": {
"description": "Subnet Id"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {},
"resources": [
{
"apiVersion": "2017-06-01",
"name": "[parameters('applicationGateway').applicationGatewayName]",
"type": "Microsoft.Network/applicationGateways",
"location": "[parameters('location')]",
"dependsOn": [],
"properties": {
"sku": {
"name": "[parameters('applicationGateway').applicationGatewaySize]",
"tier": "[parameters('applicationGateway').skuTier]",
"capacity": "[parameters('applicationGateway').applicationGatewayInstanceCount]"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[parameters('subnetRef')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGatewayFrontendIP",
"properties": {
"subnet": {
"id": "[parameters('subnetRef')]"
}
}
}
],
"frontendPorts": [
{
"name": "appGatewayFrontendPort",
"properties": {
"Port": "[parameters('applicationGateway').frontendPort]"
}
}
],
"backendAddressPools": [
{
"name": "appGatewayBackendPool",
"properties": {
"BackendAddresses": "[parameters('applicationGateway').backendIPAddresses]"
}
}
],
"backendHttpSettingsCollection": [
{
"name": "appGatewayBackendHttpSettings",
"properties": {
"Port": "[parameters('applicationGateway').backendPort]",
"Protocol": "Http",
"CookieBasedAffinity": "[parameters('applicationGateway').cookieBasedAffinity]"
}
}
],
"httpListeners": [
{
"name": "appGatewayHttpListener",
"properties": {
"FrontendIpConfiguration": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/frontendPorts/appGatewayFrontendPort')]"
},
"Protocol": "Http",
"SslCertificate": null
}
}
],
"webApplicationFirewallConfiguration": {
"enabled": "[parameters('applicationGateway').firewallEnabled]",
"firewallMode": "[parameters('applicationGateway').firewallMode]",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
},
"requestRoutingRules": [
{
"Name": "rule1",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/httpListeners/appGatewayHttpListener')]"
},
"backendAddressPool": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/backendAddressPools/appGatewayBackendPool')]"
},
"backendHttpSettings": {
"id": "[concat(resourceId('Microsoft.Network/applicationGateways', parameters('applicationGateway').applicationGatewayName), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
}
]
}
}
]
}
Parameters with firewall disabled:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationGateway": {
"value": {
"firewallEnabled": "false",
"skuTier": "Standard",
"applicationGatewayName": "yourappgateway",
"applicationGatewaySize": "Standard_Small",
"applicationGatewayInstanceCount": 1,
"frontendPort": 80,
"backendPort": 80,
"backendIPAddresses": [
{
"IpAddress": "10.0.0.7"
},
{
"IpAddress": "10.0.0.8"
},
{
"IpAddress": "10.0.0.9"
}
],
"cookieBasedAffinity": "Disabled"
}
},
"virtualNetworkName": {
"value": "yourvnetname"
},
"vnetAddressPrefix": {
"value": "10.0.0.0/16"
},
"subnetName": {
"value": "yoursubnet"
},
"subnetPrefix": {
"value": "10.0.0.0/24"
}
}
}
Parameters with firewall enabled:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"applicationGateway": {
"value": {
"firewallEnabled": "true",
"firewallMode": "Detection",
"skuTier": "WAF",
"applicationGatewayName": "yourappgateway",
"applicationGatewaySize": "WAF_Medium",
"applicationGatewayInstanceCount": 1,
"frontendPort": 80,
"backendPort": 80,
"backendIPAddresses": [
{
"IpAddress": "10.0.0.7"
},
{
"IpAddress": "10.0.0.8"
},
{
"IpAddress": "10.0.0.9"
}
],
"cookieBasedAffinity": "Disabled"
}
},
"virtualNetworkName": {
"value": "yourvnetname"
},
"vnetAddressPrefix": {
"value": "10.0.0.0/16"
},
"subnetName": {
"value": "yoursubnet"
},
"subnetPrefix": {
"value": "10.0.0.0/24"
}
}
}
Not sure why this is happening, but you can always do this:
"variables": {
"waffalse": {
"enabled": false
},
"waftrue": {
"enabled": true,
"firewallMode": "[parameters('applicationGateway').firewallMode]",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
}
}
...
"webApplicationFirewallConfiguration": "[variables(concat('waf', string(parameters('applicationGateway').firewallEnabled)))]"
so use one variable or the other depending on condition
I have created template1 which will deploy HDI cluster and template2 which will deploy Azure VM seperately.
Now I want to get the Head-node Private IP from cluster and pass it to Azure VM template for processing using ARM template.
How can I do so?
Considering this is the object you are getting from HDcluster:
{
"id": "xxx",
"name": "xxx",
"type": "Microsoft.HDInsight/clusters",
"location": "East US",
"etag": "xxx",
"tags": null,
"properties": {
"clusterVersion": "3.5.1000.0",
"osType": "Linux",
"clusterDefinition": {
"blueprint": "https://blueprints.azurehdinsight.net/spark-3.5.1000.0.9865375.json",
"kind": "SPARK",
"componentVersion": {
"Spark": "1.6"
}
},
"computeProfile": {
"roles": [
{
"name": "headnode",
"targetInstanceCount": 2,
"hardwareProfile": {
"vmSize": "ExtraLarge"
},
"osProfile": {
"linuxOperatingSystemProfile": {
"username": "sshuser"
}
}
},
{
"name": "workernode",
"targetInstanceCount": 1,
"hardwareProfile": {
"vmSize": "Large"
},
"osProfile": {
"linuxOperatingSystemProfile": {
"username": "sshuser"
}
}
},
{
"name": "zookeepernode",
"targetInstanceCount": 3,
"hardwareProfile": {
"vmSize": "Medium"
},
"osProfile": {
"linuxOperatingSystemProfile": {
"username": "sshuser"
}
}
}
]
},
"provisioningState": "Succeeded",
"clusterState": "Running",
"createdDate": "2017-04-11T09:07:44.68",
"quotaInfo": {
"coresUsed": 20
},
"connectivityEndpoints": [
{
"name": "SSH",
"protocol": "TCP",
"location": "xxx.azurehdinsight.net",
"port": 22
},
{
"name": "HTTPS",
"protocol": "TCP",
"location": "xxx.azurehdinsight.net",
"port": 443
}
],
"tier": "standard"
}
}
I'm guessing this is the best output you can get, so you can use something like:
"outputs": {
"test": {
"type": "Object",
"value": "[reference(parameters('clusterName'),'2015-03-01-preview').connectivityEndpoints[0].location]"
}
}
This will get you an output of xxx.azurehdinsight.net
And you can either create a new deployment with this data or (just like I said) add RHEL VM to the same template and make it dependOn on the HDCluster deployment and reference the same thing as an input to VMextension.
I've been trying to deploy an Azure Application Gateway to front application I have on existing VMs and use hostnames for the pool selection. I started with this template from git https://github.com/Azure/azure-quickstart-templates/tree/master/201-application-gateway-multihosting based on the article https://github.com/Azure/azure-content/blob/master/articles/application-gateway/application-gateway-multi-site-overview.md
Here is the modifed tempate I used
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16",
"metadata": {
"description": "Address prefix for the Virtual Network"
}
},
"subnetPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/28",
"metadata": {
"description": "Gateway Subnet prefix"
}
},
"skuName": {
"type": "string",
"allowedValues": [
"Standard_Small",
"Standard_Medium",
"Standard_Large"
],
"defaultValue": "Standard_Small",
"metadata": {
"description": "Sku Name"
}
},
"capacity": {
"type": "int",
"defaultValue": 4,
"metadata": {
"description": "Number of instances"
}
},
"backendIpAddress1": {
"type": "string",
"metadata": {
"description": "IP Address for Backend Server 1"
}
},
"backendIpAddress2": {
"type": "string",
"metadata": {
"description": "IP Address for Backend Server 2"
}
},
"backendIpAddress3": {
"type": "string",
"metadata": {
"description": "IP Address for Backend Server 3"
}
},
"backendIpAddress4": {
"type": "string",
"metadata": {
"description": "IP Address for Backend Server 4"
}
},
"backendIpAddress5": {
"type": "string",
"metadata": {
"description": "IP Address for Backend Server 5"
}
},
"backendIpAddress6": {
"type": "string",
"metadata": {
"description": "IP Address for Backend Server 6"
}
},
"hostName1": {
"type": "string",
"metadata": {
"description": "HostName for listener 1"
}
},
"hostName2": {
"type": "string",
"metadata": {
"description": "HostName for listener 2"
}
},
"certData1": {
"type": "securestring",
"metadata": {
"description": "Base-64 encoded form of the .pfx file"
}
},
"certPassword1": {
"type": "securestring",
"metadata": {
"description": "Password for .pfx certificate"
}
}
},
"variables": {
"applicationGatewayName": "PortalGateway",
"publicIPAddressName": "PortalGatewayFrontendIP",
"virtualNetworkName": "PalitonNetworks-East-VirtualNetwork",
"subnetName": "GWSubnet1",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
"publicIPRef": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]",
"applicationGatewayID": "[resourceId('Microsoft.Network/applicationGateways',variables('applicationGatewayName'))]",
"apiVersion": "2015-06-15"
},
"resources": [
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[variables('publicIPAddressName')]",
"location": "[resourceGroup().location]",
"properties": {
"publicIPAllocationMethod": "Dynamic"
}
},
{
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Network/virtualNetworks",
"name": "[variables('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "[parameters('subnetPrefix')]"
}
}
]
}
},
{
"apiVersion": "[variables('apiVersion')]",
"name": "[variables('applicationGatewayName')]",
"type": "Microsoft.Network/applicationGateways",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
"[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]"
],
"properties": {
"sku": {
"name": "[parameters('skuName')]",
"tier": "Standard",
"capacity": "[parameters('capacity')]"
},
"sslCertificates": [
{
"name": "appGatewaySslCert1",
"properties": {
"data": "[parameters('certData1')]",
"password": "[parameters('certPassword1')]"
}
}
],
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGatewayFrontendIP",
"properties": {
"PublicIPAddress": {
"id": "[variables('publicIPRef')]"
}
}
}
],
"frontendPorts": [
{
"name": "appGatewayFrontendPort1",
"properties": {
"Port": 443
}
},
{
"name": "appGatewayFrontendPort2",
"properties": {
"Port": 80
}
}
],
"backendAddressPools": [
{
"name": "appGatewayBackendPool1",
"properties": {
"BackendAddresses": [
{
"IpAddress": "[parameters('backendIpAddress1')]"
},
{
"IpAddress": "[parameters('backendIpAddress2')]"
},
{
"IpAddress": "[parameters('backendIpAddress3')]"
}
]
}
},
{
"name": "appGatewayBackendPool2",
"properties": {
"BackendAddresses": [
{
"IpAddress": "[parameters('backendIpAddress4')]"
},
{
"IpAddress": "[parameters('backendIpAddress5')]"
},
{
"IpAddress": "[parameters('backendIpAddress6')]"
}
]
}
}
],
"backendHttpSettingsCollection": [
{
"name": "appGatewayBackendHttpSettings",
"properties": {
"Port": 80,
"Protocol": "Http",
"CookieBasedAffinity": "Disabled"
}
},
{
"name": "appGatewayBackendHttpsSettings",
"properties": {
"Port": 443,
"Protocol": "Https",
"CookieBasedAffinity": "Disabled"
}
}
],
"httpListeners": [
{
"name": "appGatewayHttpsListener-Group1",
"properties": {
"FrontendIPConfiguration": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendPorts/appGatewayFrontendPort1')]"
},
"Protocol": "Https",
"SslCertificate": {
"Id": "[concat(variables('applicationGatewayID'), '/sslCertificates/appGatewaySslCert1')]"
},
"HostName": "[parameters('hostName1')]",
"RequireServerNameIndication": "false"
}
},
{
"name": "appGatewayHttpsListener-Group2",
"properties": {
"FrontendIPConfiguration": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendPorts/appGatewayFrontendPort1')]"
},
"Protocol": "Https",
"SslCertificate": {
"Id": "[concat(variables('applicationGatewayID'), '/sslCertificates/appGatewaySslCert1')]"
},
"HostName": "[parameters('hostName2')]",
"RequireServerNameIndication": "false"
}
},
{
"name": "appGatewayHttpListener-Group1",
"properties": {
"FrontendIPConfiguration": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendPorts/appGatewayFrontendPort2')]"
},
"Protocol": "Http",
"SslCertificate": null,
"HostName": "[parameters('hostName1')]",
"RequireServerNameIndication": "false"
}
},
{
"name": "appGatewayHttpListener-Group2",
"properties": {
"FrontendIPConfiguration": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendIPConfigurations/appGatewayFrontendIP')]"
},
"FrontendPort": {
"Id": "[concat(variables('applicationGatewayID'), '/frontendPorts/appGatewayFrontendPort2')]"
},
"Protocol": "Http",
"SslCertificate": null,
"HostName": "[parameters('hostName2')]",
"RequireServerNameIndication": "false"
}
}
],
"requestRoutingRules": [
{
"Name": "Group1-SSL",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(variables('applicationGatewayID'), '/httpListeners/appGatewayHttpsListener-Group1')]"
},
"backendAddressPool": {
"id": "[concat(variables('applicationGatewayID'), '/backendAddressPools/appGatewayBackendPool1')]"
},
"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayID'), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
},
{
"Name": "Group2-SSL",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(variables('applicationGatewayID'), '/httpListeners/appGatewayHttpsListener-Group2')]"
},
"backendAddressPool": {
"id": "[concat(variables('applicationGatewayID'), '/backendAddressPools/appGatewayBackendPool2')]"
},
"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayID'), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
},
{
"Name": "Group2-www",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(variables('applicationGatewayID'), '/httpListeners/appGatewayHttpListener-Group1')]"
},
"backendAddressPool": {
"id": "[concat(variables('applicationGatewayID'), '/backendAddressPools/appGatewayBackendPool1')]"
},
"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayID'), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
},
{
"Name": "Group1-www",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(variables('applicationGatewayID'), '/httpListeners/appGatewayHttpListener-Group2')]"
},
"backendAddressPool": {
"id": "[concat(variables('applicationGatewayID'), '/backendAddressPools/appGatewayBackendPool2')]"
},
"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayID'), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]"
}
}
}
]
}
}
]
}
As you can see I specify GWSubnet1 as the App Gateway subnet. My backend IPs are in the VMnet1 subnet under the same Virtual Network. When I deploy it fails saying that it can't delete VMnet1. VMNet1 is only indirectly referenced as the backend IP so why would it be trying remove it. GWSubnet1 is an unused empty subenet as per the deployment rules from Azure.
If I use the GUI I can create the gateway and select GWSubnet1. However using the GUI the advanced feature of putting the hostname in the listner isn't an option and therefore won't let you create multiple listners using the same front end port. I tried using the GUI and and then adding listners via Poweshell (version 3.0.0) using the following
$hostname = "example1.foo.com"
$listnername = "group2-az"
$appgwname = "PortalGateway"
$rmname = "myrmg"
$feipname = "appGatewayFrontendIP"
$fepname = "appGatewayFrontendPort"
$behttpname = "appGatewayBackendHttpSettings"
$appgw = Get-AzureRmApplicationGateway -Name $appgwname -ResourceGroupName $rmname
$bepool = Get-AzureRmApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name "appGatewayBackendPool"
$behttp = Get-AzureRmApplicationGatewayBackendHttpSettings -ApplicationGateway $appgw -Name $behttpname
$fipc = Get-AzureRmApplicationGatewayFrontendIPConfig -Name $feipname -ApplicationGateway $appgw
$fep = Get-AzureRmApplicationGatewayFrontendPort -Name $fepname -ApplicationGateway $appgw
$result = Add-AzureRmApplicationGatewayHttpListener -ApplicationGateway $appgw -Name "appGatewayHttpListenerGroup1" -Protocol Http -FrontendIPConfiguration $fipc -FrontendPort $fep -HostName $hostname -RequireServerNameIndication false
However what appears to happen is that it doesn't add a listener it just modifies the existing default listener that is created when you create the appgateway via the GUI. It does this no matter what name I choose as the listener.
I know the deployment template works as I can create a new empty resource group and deploy it in there and it deploys. I just can't seem to get it to deploy where there are existing VMs. What is the correct way to do this?
ARM Templates are declarative and in your template there is only a single Subnet. If you deploy that template ARM will try to make it exactly as you have defined = it tries to remove any subnets in that subnet which arent defined withing itself.
That is the reason for your error. ARM tries to delete your VMnet1 and it cant do that as long as it has NICs associated with it.
Check the Documentation here:
Deploy resources with Resource Manager templates and Azure PowerShell
The interesting Part for you is:
Incremental and complete deployments
When deploying your resources, you specify that the deployment is either an incremental update or a complete update. By default, Resource Manager handles deployments as incremental updates to the resource group.
With incremental deployment, Resource Manager:
leaves unchanged resources that exist in the resource group but are not specified in the template
adds resources that are specified in the template but do not exist in the resource group
does not reprovision resources that exist in the resource group in the same condition defined in the template
reprovisions existing resources that have updated settings in the template
With complete deployment, Resource Manager:
deletes resources that exist in the resource group but are not specified in the template
adds resources that are specified in the template but do not exist in the resource group
does not reprovision resources that exist in the resource group in the same condition defined in the template
reprovisions existing resources that have updated settings in the template
To solve your Problem you need to either make the subnet config exactly represent your existing setup or your manually create the new subnet and dont define the vnet in your template.
If you create the subnet manually you can reference your existing vnet and subnet in the template like this:
"parameters": {
"existingVirtualNetworkName": {
"type": "string"
},
"existingVirtualNetworkResourceGroup": {
"type": "string"
},
"existingSubnet1Name": {
"type": "string"
},
"existingSubnet2Name": {
"type": "string"
},
}
"variables": {
"existingVnetID": "[resourceId(parameters('existingVirtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks', parameters('existingVirtualNetworkName'))]",
"existingSubnet1Ref": "[concat(variables('existingVnetID'),'/subnets/', parameters('existingSubnet1Name'))]",
"existingSubnet2Ref": "[concat(variables('existingVnetID'),'/subnets/', parameters('existingSubnet2Name'))]",
}
After passing the existing RessourceGroup, Vnet and Subnetnames through parameters you can just use the variables "existingSubnet1Name" to point to the correct IDs.
The magic lies withing the [resourceId()] functions optional parameters: [subscriptionId], [resourceGroupName].
resourceId ([subscriptionId], [resourceGroupName], resourceType, resourceName1, [resourceName2]...)
Documentation: Template functions