Can someone help in deploying App service environment using ARM template.
data "azurerm_resource_group" "rg" {
name = "${var.rg_name}"
}
resource "azurerm_template_deployment" "deploy" {
name = "${var.deployment_name}"
resource_group_name = "${data.azurerm_resource_group.rg.name}"
template_body = <<DEPLOY
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"aseName": {
"type": "string"
},
"subscriptionId": {
"type": "string"
},
"location": {
"type": "string"
},
"vnetName": {
"type": "string"
},
"subnetName": {
"type": "string"
},
"vnetId": {
"type": "string"
},
"VNetResourceGroupName": {
"type": "string"
},
"vnetAddress": {
"type": "string"
},
"subnetAddress": {
"type": "string"
},
"subnetRouteTableName": {
"type": "string"
},
"subnetNSGName": {
"type": "string"
},
"ilbMode": {
"type": "int"
},
"subnetId": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2017-05-10",
"name": "existingVnetTemplate",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('VNetResourceGroupName')]",
"subscriptionId": "[parameters('subscriptionId')]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"apiVersion": "2016-06-01",
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('vnetName'), '/', parameters('subnetName'))]",
"properties": {
"addressPrefix": "[parameters('subnetAddress')]",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('subnetNSGName'))]"
},
"routeTable": {
"id": "[resourceId('Microsoft.Network/routeTables', parameters('subnetRouteTableName'))]"
}
}
}
]
},
"parameters": {}
},
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups/', parameters('subnetNSGName'))]",
"[resourceId('Microsoft.Network/routeTables/', parameters('subnetRouteTableName'))]"
]
},
{
"apiVersion": "2019-02-01",
"type": "Microsoft.Web/hostingEnvironments",
"name": "[parameters('aseName')]",
"kind": "ASEV2",
"location": "[parameters('location')]",
"properties": {
"name": "[parameters('aseName')]",
"location": "[parameters('location')]",
"InternalLoadBalancingMode": "[parameters('ilbMode')]",
"virtualNetwork": {
"Id": "[parameters('subnetId')]"
}
},
"tags": {},
"dependsOn": [
"['existingVnetTemplate']"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/routeTables",
"name": "[parameters('subnetRouteTableName')]",
"location": "[parameters('location')]",
"tags": {
"displayName": "UDR - Subnet"
},
"properties": {
"routes": [
{
"name": "abdc-route",
"properties": {
"addressPrefix": "0.0.0.0/0",
"nextHopType": "Internet"
}
}
]
}
},
{
"apiVersion": "2017-06-01",
"type": "Microsoft.Network/networkSecurityGroups",
"name": "[parameters('subnetNSGName')]",
"location": "[parameters('location')]",
"tags": {
"displayName": "NSG - Subnet"
},
"properties": {
"securityRules": [
{
"name": "Inbound-management",
"properties": {
"description": "Used to manage ASE from public VIP",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "454-455",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Inbound"
}
},
{
"name": "Inbound-load-balancer-keep-alive",
"properties": {
"description": "Allow communication to ASE from Load Balancer",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "16001",
"sourceAddressPrefix": "AzureLoadBalancer",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 105,
"direction": "Inbound"
}
},
{
"name": "ASE-internal-inbound",
"properties": {
"description": "ASE-internal-inbound",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "[parameters('subnetAddress')]",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 110,
"direction": "Inbound"
}
},
{
"name": "Inbound-HTTP",
"properties": {
"description": "Allow HTTP",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "80",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 120,
"direction": "Inbound"
}
},
{
"name": "Inbound-HTTPS",
"properties": {
"description": "Allow HTTPS",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 130,
"direction": "Inbound"
}
},
{
"name": "Inbound-FTP",
"properties": {
"description": "Allow FTP over port 21",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "21",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 140,
"direction": "Inbound"
}
},
{
"name": "Inbound-FTPS",
"properties": {
"description": "Allow FTPS",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "990",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 150,
"direction": "Inbound"
}
},
{
"name": "Inbound-FTP-Data",
"properties": {
"description": "RDP",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "10001-10020",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 160,
"direction": "Inbound"
}
},
{
"name": "Inbound-Remote-Debugging",
"properties": {
"description": "Visual Studio remote debugging",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "4016-4022",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 170,
"direction": "Inbound"
}
},
{
"name": "Outbound-443",
"properties": {
"description": "Azure Storage blob",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Outbound"
}
},
{
"name": "Outbound-DB",
"properties": {
"description": "Database",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "1433",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "Sql",
"access": "Allow",
"priority": 110,
"direction": "Outbound"
}
},
{
"name": "Outbound-DNS",
"properties": {
"description": "DNS",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "53",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 120,
"direction": "Outbound"
}
},
{
"name": "ASE-internal-outbound",
"properties": {
"description": "Azure Storage queue",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "[parameters('subnetAddress')]",
"access": "Allow",
"priority": 130,
"direction": "Outbound"
}
},
{
"name": "Outbound-80",
"properties": {
"description": "Outbound 80",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "80",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 140,
"direction": "Outbound"
}
},
{
"name": "ASE-to-VNET",
"properties": {
"description": "ASE to VNET",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "[parameters('vnetAddress')]",
"access": "Allow",
"priority": 150,
"direction": "Outbound"
}
},
{
"name": "Outbound-NTP",
"properties": {
"description": "Clock",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "123",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 160,
"direction": "Outbound"
}
}
]
}
}
]
}
DEPLOY
parameters = {
"location" = "${var.location}"
"aseName" = "${var.aseName}"
"subscriptionId" = "${var.subscriptionId}"
"vnetName" = "${var.vnetName}"
"subnetName" = "${var.subnetName}"
"vnetId" = "${var.vnetId}"
"VNetResourceGroupName" = "${var.VNetResourceGroupName}"
"vnetAddress" = "${var.vnetAddress}"
"subnetAddress" = "${var.subnetAddress}"
"subnetRouteTableName" = "${var.subnetRouteTableName}"
"subnetNSGName" = "${var.subnetNSGName}"
"ilbMode" = "3"
"subnetId" = "${var.subnetId}"
}
deployment_mode = "Incremental"
}
"outputs": {
"app_service_evironment_id": {
"type": "string",
"value": "[resourceId('Microsoft.Web/hostingEnvironments', parameters('aseName'))]",
}
}
How do i get the ID of App service environment(Hostingenvironment) in this template so that i am able to output it in terraform and use it in App service plan parameter (app_service_environment_id). This is to deploy the app service in a private network.
https://www.terraform.io/docs/providers/azurerm/r/app_service_plan.html#app_service_environment_id
I tried deploying App service environment from azure portal and mentioning its ID in the format "/subscription/xxxx-xxx-xx-xxxx-xxx/Microsoft.web/Hostingenvironment/" which returned a 404.
eg: app_service_environment_id = "/subscription/xxxx-xxx-xx-xxxx-xxx/Microsoft.web/Hostingenvironment/xxxxxxx"
Any help
The mistake you made is that you need to put the output inside the template code, not the Terraform code. So your Terraform code should like this:
data "azurerm_resource_group" "rg" {
name = "${var.rg_name}"
}
resource "azurerm_template_deployment" "deploy" {
name = "${var.deployment_name}"
resource_group_name = "${data.azurerm_resource_group.rg.name}"
template_body = <<DEPLOY
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"aseName": {
"type": "string"
},
"subscriptionId": {
"type": "string"
},
"location": {
"type": "string"
},
"vnetName": {
"type": "string"
},
"subnetName": {
"type": "string"
},
"vnetId": {
"type": "string"
},
"VNetResourceGroupName": {
"type": "string"
},
"vnetAddress": {
"type": "string"
},
"subnetAddress": {
"type": "string"
},
"subnetRouteTableName": {
"type": "string"
},
"subnetNSGName": {
"type": "string"
},
"ilbMode": {
"type": "int"
},
"subnetId": {
"type": "string"
}
},
"resources": [
{
"apiVersion": "2017-05-10",
"name": "existingVnetTemplate",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('VNetResourceGroupName')]",
"subscriptionId": "[parameters('subscriptionId')]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"apiVersion": "2016-06-01",
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('vnetName'), '/', parameters('subnetName'))]",
"properties": {
"addressPrefix": "[parameters('subnetAddress')]",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('subnetNSGName'))]"
},
"routeTable": {
"id": "[resourceId('Microsoft.Network/routeTables', parameters('subnetRouteTableName'))]"
}
}
}
]
},
"parameters": {}
},
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups/', parameters('subnetNSGName'))]",
"[resourceId('Microsoft.Network/routeTables/', parameters('subnetRouteTableName'))]"
]
},
{
"apiVersion": "2019-02-01",
"type": "Microsoft.Web/hostingEnvironments",
"name": "[parameters('aseName')]",
"kind": "ASEV2",
"location": "[parameters('location')]",
"properties": {
"name": "[parameters('aseName')]",
"location": "[parameters('location')]",
"InternalLoadBalancingMode": "[parameters('ilbMode')]",
"virtualNetwork": {
"Id": "[parameters('subnetId')]"
}
},
"tags": {},
"dependsOn": [
"['existingVnetTemplate']"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/routeTables",
"name": "[parameters('subnetRouteTableName')]",
"location": "[parameters('location')]",
"tags": {
"displayName": "UDR - Subnet"
},
"properties": {
"routes": [
{
"name": "abdc-route",
"properties": {
"addressPrefix": "0.0.0.0/0",
"nextHopType": "Internet"
}
}
]
}
},
{
"apiVersion": "2017-06-01",
"type": "Microsoft.Network/networkSecurityGroups",
"name": "[parameters('subnetNSGName')]",
"location": "[parameters('location')]",
"tags": {
"displayName": "NSG - Subnet"
},
"properties": {
"securityRules": [
{
"name": "Inbound-management",
"properties": {
"description": "Used to manage ASE from public VIP",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "454-455",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Inbound"
}
},
{
"name": "Inbound-load-balancer-keep-alive",
"properties": {
"description": "Allow communication to ASE from Load Balancer",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "16001",
"sourceAddressPrefix": "AzureLoadBalancer",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 105,
"direction": "Inbound"
}
},
{
"name": "ASE-internal-inbound",
"properties": {
"description": "ASE-internal-inbound",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "[parameters('subnetAddress')]",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 110,
"direction": "Inbound"
}
},
{
"name": "Inbound-HTTP",
"properties": {
"description": "Allow HTTP",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "80",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 120,
"direction": "Inbound"
}
},
{
"name": "Inbound-HTTPS",
"properties": {
"description": "Allow HTTPS",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 130,
"direction": "Inbound"
}
},
{
"name": "Inbound-FTP",
"properties": {
"description": "Allow FTP over port 21",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "21",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 140,
"direction": "Inbound"
}
},
{
"name": "Inbound-FTPS",
"properties": {
"description": "Allow FTPS",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "990",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 150,
"direction": "Inbound"
}
},
{
"name": "Inbound-FTP-Data",
"properties": {
"description": "RDP",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "10001-10020",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 160,
"direction": "Inbound"
}
},
{
"name": "Inbound-Remote-Debugging",
"properties": {
"description": "Visual Studio remote debugging",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "4016-4022",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 170,
"direction": "Inbound"
}
},
{
"name": "Outbound-443",
"properties": {
"description": "Azure Storage blob",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Outbound"
}
},
{
"name": "Outbound-DB",
"properties": {
"description": "Database",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "1433",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "Sql",
"access": "Allow",
"priority": 110,
"direction": "Outbound"
}
},
{
"name": "Outbound-DNS",
"properties": {
"description": "DNS",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "53",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 120,
"direction": "Outbound"
}
},
{
"name": "ASE-internal-outbound",
"properties": {
"description": "Azure Storage queue",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "[parameters('subnetAddress')]",
"access": "Allow",
"priority": 130,
"direction": "Outbound"
}
},
{
"name": "Outbound-80",
"properties": {
"description": "Outbound 80",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "80",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 140,
"direction": "Outbound"
}
},
{
"name": "ASE-to-VNET",
"properties": {
"description": "ASE to VNET",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "[parameters('vnetAddress')]",
"access": "Allow",
"priority": 150,
"direction": "Outbound"
}
},
{
"name": "Outbound-NTP",
"properties": {
"description": "Clock",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "123",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 160,
"direction": "Outbound"
}
}
]
}
}
],
"outputs": {
"app_service_evironment_id": {
"type": "string",
"value": "[resourceId('Microsoft.Web/hostingEnvironments', parameters('aseName'))]"
}
}
}
DEPLOY
parameters = {
"location" = "${var.location}"
"aseName" = "${var.aseName}"
"subscriptionId" = "${var.subscriptionId}"
"vnetName" = "${var.vnetName}"
"subnetName" = "${var.subnetName}"
"vnetId" = "${var.vnetId}"
"VNetResourceGroupName" = "${var.VNetResourceGroupName}"
"vnetAddress" = "${var.vnetAddress}"
"subnetAddress" = "${var.subnetAddress}"
"subnetRouteTableName" = "${var.subnetRouteTableName}"
"subnetNSGName" = "${var.subnetNSGName}"
"ilbMode" = "3"
"subnetId" = "${var.subnetId}"
}
deployment_mode = "Incremental"
}
outputs "app_service_evironment_id" {
value = "${azurerm_template_deployment.outputs["app_service_evironment_id"]}"
}
Or the outputs of the Terraform also can be in the format like this:
outputs "app_service_evironment_id" {
value = "${lookup(azurerm_template_deployment.app_service_evironment_id.outputs, "app_service_evironment_id")}"
}
The outputs of the Terraform only to show you how to use the output in template deployment. So you can also quote it in the service plan like this:
resource "azurerm_app_service_plan" "example" {
...
app_service_environment_id = "${lookup(azurerm_template_deployment.app_service_evironment_id.outputs, "app_service_evironment_id")}"
...
}