When creating an app service I'm attempting to attach it to a virtual network using the following syntax
site_config {
        virtual_network_name = "${azurerm_virtual_network.default.name}"
    }
Terraform runs as expected with no errors. However it doesn't seem to be taking as you can see from the attached screenshot:

Full tf file is below:
  resource "azurerm_resource_group" "default" {
    name     = "vnet-test-terraform"
    location = "UK West"
  }
  resource "azurerm_virtual_network" "default" {
    name                = "vnet-test-terraform-vn"
    address_space       = ["10.1.0.0/16"]
    location            = "UK West"
    resource_group_name = "${azurerm_resource_group.default.name}"
  }
  resource "azurerm_subnet" "subnet" {
    name                 = "Default"
    resource_group_name  = "${azurerm_resource_group.default.name}"
    virtual_network_name = "${azurerm_virtual_network.default.name}"
    address_prefix       = "10.1.0.0/24"
  }
  resource "azurerm_subnet" "gateway_subnet" {
    name                 = "GatewaySubnet"
    resource_group_name  = "${azurerm_resource_group.default.name}"
    virtual_network_name = "${azurerm_virtual_network.default.name}"
    address_prefix       = "10.1.1.0/24"
  }
  resource "azurerm_public_ip" "default" {
    name                         = "vnet-test-terraform-ip"
    location                     = "UK West"
    resource_group_name  = "${azurerm_resource_group.default.name}"
    public_ip_address_allocation = "Dynamic"
  }
  resource "azurerm_virtual_network_gateway" "default" {
    name                = "vnet-test-terraform-vng"
    location            = "UK West"
    resource_group_name  = "${azurerm_resource_group.default.name}"
    type                = "Vpn"
    sku                 = "VpnGw1"
    ip_configuration {
      private_ip_address_allocation = "Dynamic"
      public_ip_address_id          = "${azurerm_public_ip.default.id}"
      subnet_id                     = "${azurerm_subnet.gateway_subnet.id}"
    }
    vpn_client_configuration {
      address_space        = ["10.0.1.0/24"]
      vpn_client_protocols = ["SSTP"]
    }
  }
  resource "azurerm_app_service_plan" "default" {
    name                = "vnet-test-terraform-asp"
    location            = "UK West"
    resource_group_name  = "${azurerm_resource_group.default.name}"
    sku {
      tier = "Standard"
      size = "S1"
    }
  }
  resource "azurerm_app_service" "default" {
    name                = "vnet-test-terraform-as"
    location            = "UK West"
    resource_group_name  = "${azurerm_resource_group.default.name}"
    app_service_plan_id = "${azurerm_app_service_plan.default.id}"
    site_config {
        virtual_network_name = "${azurerm_virtual_network.default.name}"
    }
  }
If they are of any worth here are the templates from when did it manually compared to how it looked with TF
Actual: https://gist.github.com/mat-mcloughlin/ea8b760452ffacf20d97f2e943634d9d
Expected: https://gist.github.com/mat-mcloughlin/1a618ca8eb1bf14b732492317d6bf745
I believe in order to host App Service on a vnet, you need to stand up an App Service Environment, attach plan(s) to that, then attach app services to those plans.
Unfortunately there's no official ASE resource in terraform for this, so you need to use azurerm_template_deployment (ARM template)
hey @mat-mcloughlin
Thanks for opening this issue :)
Digging into how the Portal achieves this - it appears the Azure Portal calls out to Kudu, which is the API hosted on the App Service to configure this Virtual Network Connection, rather than an API within Resource Manager. In our case that makes the following request:
URL: https://web1.appsvcux.ext.azure.com/api/Websites/AddExistingV2VirtualNetworkToSite
{
    "WebAppResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tom-devrg/providers/Microsoft.Web/sites/tomdev-appservice",
    "VnetResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tom-devrg/providers/Microsoft.Network/virtualNetworks/tom-devvn",
    "VnetGatewayResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tom-devrg/providers/Microsoft.Network/virtualNetworkGateways/tom-devvng",
    "VnetLocation": "westeurope"
}
Unfortunately at this time there's no Golang API Client for Kudu (and Kudu itself isn't overly well documented) - but I'd requested support in this issue - which I'd recommend subscribing to for updates.
Thanks!
I am seeing the same issue attached the app service to vnet...
Is this issues resolved?
Note the documentation indicates it should work.
Since it does not actually work, you end up with the App Service not in the Vnet you expect, which means it's not protected by the network security group that it is documented to have. Boom, security issue.
Hi,
I use the following workaround for this. My VPN gateway terraform module creates two resources:
VNET gateway module. 
$virtualNetwork = New-AzureRmResource -Location $Location 
                                      -Properties $propertiesObject 
                                      -ResourceName "$($GatewayName)/$($VnetName)" 
                                      -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" 
                                      -ApiVersion 2015-08-01 
                                      -ResourceGroupName $ResourceGroup -Force 
After this new certificate will be generated by azure.
Then i run this code to add app service certificate that will be used by all app service in future to vnet gateway: 
    Add-AzureRmVpnClientRootCertificate -VpnClientRootCertificateName "AppServiceCertificate.cer" 
                                        -PublicCertData $virtualNetwork.Properties.CertBlob 
                                        -VirtualNetworkGatewayName $GatewayName 
                                        -ResourceGroupName $ResourceGroup
The certificate should be added exactly with this name - AppServiceCertificate.cer
App service module.
My app service terraform module for app service include terraform code for app service creation and null_resource block that run powershell script that adding app service to vnet.
This approach was tested before terraform adding support for this property: 
site_config {
        virtual_network_name = "${azurerm_virtual_network.default.name}"
}
   ```
----------------------------------------------------------------------
Code for app service gateway certificate configuration
param (
    $AADSecret = "",
    $AADClientID = "",
    $TenantID = "",
    $ResourceGroup = "",
    $Location = "",
    $SubscriptionID = "",
    $GatewayName = "",
    $VnetName = ""
)
Import-Module AzureRM.Websites
Import-Module AzureRM.Profile
$securityString = $AADSecret | ConvertTo-SecureString -Force -AsPlainText
$credential = New-Object System.Management.Automation.PsCredential("$AADClientID",$securityString)
$session = Get-Credential -Credential $credential;
Connect-AzureRmAccount -Credential $session 
                       -TenantId $TenantID
                       -ServicePrincipal `
                       -Subscription $SubscriptionID *>$null
$vnetObj = Get-AzureRmVirtualNetwork -Name $VnetName -ResourceGroupName $ResourceGroup
Write-Host "Creating App association to VNET"
$propertiesObject = @{
  "vnetResourceId" = "$($vnetObj.Id)"
}
if (-not (Get-AzureRmWebApp -ResourceGroupName $ResourceGroup -Name $GatewayName -ErrorAction SilentlyContinue )) {
  New-AzureRmAppServicePlan -ResourceGroupName $ResourceGroup 
                            -Location $Location
                            -Tier Standard `
                            -Name "$($GatewayName)" -ErrorAction SilentlyContinue
New-AzureRmWebApp -ResourceGroupName $ResourceGroup 
                    -Name "$($GatewayName)"
                    -Location $Location 
                    -AppServicePlan "$($GatewayName)" -ErrorAction SilentlyContinue
} else {
  $virtualNetwork = New-AzureRmResource -Location $Location
                                        -Properties $propertiesObject 
                                        -ResourceName "$($GatewayName)/$($VnetName)"
                                        -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" 
                                        -ApiVersion 2015-08-01
                                        -ResourceGroupName $ResourceGroup -Force
}
$virtualNetwork = New-AzureRmResource -Location $Location 
                                      -Properties $propertiesObject
                                      -ResourceName "$($GatewayName)/$($VnetName)" 
                                      -ResourceType "Microsoft.Web/sites/virtualNetworkConnections"
                                      -ApiVersion 2015-08-01 `
                                      -ResourceGroupName $ResourceGroup -Force                           
$oldCert = Get-AzureRmVpnClientRootCertificate -VpnClientRootCertificateName "AppServiceCertificate.cer" 
                                               -VirtualNetworkGatewayName $GatewayName
                                               -ResourceGroupName $ResourceGroup 
if ($oldCert.PublicCertData -eq $virtualNetwork.Properties.CertBlob) {
    Write-host "Certificate already present on gateway"
} else {
    if ($oldCert.PublicCertData.Length -ne 0) {
        write-host "Remove AppServiceCertificate.cer from gateway and create new. "
        Remove-AzureRmVpnClientRootCertificate -VpnClientRootCertificateName "AppServiceCertificate.cer" 
                                               -PublicCertData $oldCert.PublicCertData
                                               -VirtualNetworkGatewayName $GatewayName 
                                               -ResourceGroupName $ResourceGroup 
    } 
    Add-AzureRmVpnClientRootCertificate -VpnClientRootCertificateName "AppServiceCertificate.cer"
                                        -PublicCertData $virtualNetwork.Properties.CertBlob 
                                        -VirtualNetworkGatewayName $GatewayName
                                        -ResourceGroupName $ResourceGroup
}              
**Terraform** 
resource "null_resource" "gateway_cert_for_webapp" {
  triggers {
    id                       = "${azurerm_virtual_network_gateway.gateway.id}"
    trigger_null_resource    = "${var.trigger_null_resource}"
    trigger_sync_webapp_cert = "${var.trigger_sync_webapp_cert}"
  }
provisioner "local-exec" {
    when = "create"
command = <<EOF
    powershell -file ${path.module}\Update-AppServiceGatewayCertificate.ps1 -AADSecret ${var.AADSecret}
                                                                            -AADClientID ${data.azurerm_client_config.current.client_id}
                                                                            -TenantID ${data.azurerm_client_config.current.tenant_id}
                                                                            -ResourceGroup ${var.resource_group_name}
                                                                            -Location ${var.location}
                                                                            -SubscriptionID ${data.azurerm_client_config.current.subscription_id}
                                                                            -GatewayName ${var.name}
                                                                            -VnetName ${var.vnet_name}
EOF
interpreter = ["PowerShell", "-Command"]
}
lifecycle {
    create_before_destroy = false
  }
}
**and code for app service vnet integration** 
param (
      $VnetName = "${VnetName}",
      $GatewayName = "${GatewayName}",
      $ResourceGroup = "${ResourceGroup}",
      $Location = "${Location}",
      $WebApp = "${WebApp}",
      $AADSecret = "${AADSecret}",
      $AADClientID = "${AADClientID}",
      $TenantID = "${TenantID}",
      $SubscriptionId = "${SubscriptionId}"
)
$securityString = $AADSecret | ConvertTo-SecureString -Force -AsPlainText
$credential = New-Object System.Management.Automation.PsCredential("$AADClientID",$securityString)
$session = Get-Credential -Credential $credential;
Connect-AzureRmAccount -Credential $session -TenantId $TenantID -ServicePrincipal -Subscription $SubscriptionID *>$null
$vnetName = $VnetName
$vpnRecieved = $false
do {
        $vpnClient = Get-AzureRmVpnClientPackage -ResourceGroupName $ResourceGroup -VirtualNetworkGatewayName $GatewayName -ProcessorArchitecture Amd64 -ErrorAction SilentlyContinue
    if ($vpnClient -like '"*.blob.core.windows.net*"') {
    $packageUri = $vpnClient.ToString(); 
    $packageUri = $vpnClient.Substring(1, $vpnClient.Length-2);
    $vpnPackageUri = $packageUri
    $vpnRecieved = $true
    Write-Host "Vpn package has been recieved"
    }
} while ($recieved -eq $false)
$PropertiesObject = @{
    "vnetName" = $vnetName;
    "vpnPackageUri" = $vpnPackageUri
}
New-AzureRmResource -Location $Location 
                    -Properties $PropertiesObject
                    -ResourceName "$($WebApp)/$($vnetName)/primary" 
                    -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways"
                    -ApiVersion 2015-08-01 -ResourceGroupName $ResourceGroup -Force`
**and terraform code** 
data "template_file" "New-AppServiceVnetIntegration" {
    template = "${file("${local.script_path}/New-AppServiceVnetIntegration.ps1")}"
    vars = {
      VnetName = "${var.virtual_network_name}",
      GatewayName = "${var.gateway_name}",
      ResourceGroup = "${var.resource_group_name}",
      Location = "${var.location}",
      WebApp = "${var.name}",
      AADSecret = "${var.AADSecret}",
      AADClientID = "${data.azurerm_client_config.current.client_id}",
      TenantID = "${data.azurerm_client_config.current.tenant_id}",
      SubscriptionId = "${data.azurerm_client_config.current.subscription_id}"
    }
}
resource "null_resource" "New-AppServiceVnetIntegration" {
  depends_on = ["azurerm_app_service.app_service"]
  triggers {
    id                = "${azurerm_app_service.app_service.id}"
    vnet_integration = " ${data.template_file.New-AppServiceVnetIntegration.rendered}"
  }
  provisioner "local-exec" {
    command = <
    EOF
    interpreter = ["PowerShell", "-Command"]
  }
}
```
👋
Taking a look into this - it appears the virtual_network_name field has now been repurposed to require the ResourceGUID and the Subnet name combined, such that I believe this should now be fixed via #2325 - as such I'm going to close this issue in favour of that one.
Thanks!
Using the format vnetResourceGuid_subnetName for the virtual_network_name doesn't work for me. No errors occurs but the azure portal shows no VNet integration configured (same as the OP screenshot) 
Can anyone confirm this has worked previously?
@robck attaching App Services to a Virtual Network's gone through a few iterations on the Azure end unfortunately.
After chatting with the service team a while back it appears that the virtual_network_name field exposed in the API is a previous integration attempt which was really only available through the Kudu API's, which has since been superseded by a new integration method which is being added in #4250
Thanks!
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!