Azure VPN Gateway Connection with custom IPSEC Policy

I was recently setting up a VPN tunnel between an Azure VPN Gateay and an on-premise location, and ran into issues with the tunnel connecting.

The connection in Azure kept saying “connecting”. I was trying to use the VPN troubleshooter to log diagnostics to a storage account for parsing, however the diags didn’t contain the actual errors, and the wizard in the Portal wouldn’t refresh from subsequent runs, so it was stuck on an error with the pre-shared key which I had already corrected.

The on-premise device is a Cisco, and so there were accessible error messages from it:

crypo map policy not found for remote traffic selector

This led me down a path of searching resulting in the Cisco example configuration from Microsoft. The key part of this is that a Cisco ASA cannot make a connection to a native RouteBased VPN Gateway in Azure.

The fix is to apply a custom IPSec policy to your connection, particularly with this flag: -UsePolicyBasedTrafficSelectors $True

I used a small bit of PowerShell in order to try this out:

$rg          = "default-rg"
$ConnectionHEN = "vpngw"
$connection = Get-AzVirtualNetworkGatewayConnection -Name $ConnectionHEN -ResourceGroupName $rg
$newpolicy   = New-AzIpsecPolicy -IkeEncryption AES256 -ikeintegrity SHA256 -DhGroup DHGroup2 -IpsecEncryption AES256 -IpsecIntegrity SHA256 -PfsGroup none -SALifeTimeSeconds 28800
Set-AzVirtualNetworkGatewayConnection -VirtualNetworkGatewayConnection $connection -IpsecPolicies $newpolicy -UsePolicyBasedTrafficSelectors $true

However, this returned the following error:

A virtual network gateway SKU of Standard or higher is required for Ipsec Policies support on virtual network gateway

My VPN Gateway is of SKU “Basic”, so it does not support IPSec policies, according to this documentation page.

Because it’s Basic, I can’t simply upgrade to a “VpnGW1” – I have to destroy and re-create my gateway as the new SKU, which will also generate a new public IP address.

So I did these things, but I did them using Terraform since this environment is managed with that tool.

First I ‘tainted‘ the existing resource to mark it for deletion and recreation. Then I ran “terraform apply” to make the modifications, based on the resources here below:


resource "azurerm_resource_group" "srv-rg" {
  name     = "srv-rg"
  location = "${var.location}"
resource "azurerm_public_ip" "vpngw-pip" {
  name = "vpngateway-ip"
  location = "${azurerm_resource_group.srv-rg.location}"
  resource_group_name = "${}"
  allocation_method = "Dynamic"
resource "azurerm_local_network_gateway" "localgateway" {
  name                = "localgateway"
  resource_group_name = "${}"
  location            = "${azurerm_resource_group.srv-rg.location}"
  gateway_address     = ""
  address_space       = ""
resource "azurerm_virtual_network_gateway" "vpngw" {
  name = "vpngw"
  location = "${azurerm_resource_group.srv-rg.location}"
  resource_group_name = "${}"
  type = "Vpn"
  vpn_type = "RouteBased"
  active_active = false
  enable_bgp = false
    sku = "VpnGw1"
  ip_configuration {
    name = "vpngateway_ipconfig"
    public_ip_address_id = "${}"
    private_ip_address_allocation = "Dynamic"
    subnet_id = "${}"
# Client VPN Connection
resource "azurerm_virtual_network_gateway_connection" "vpnconnection" {
  name = "vpnconnection"
  location = "${azurerm_resource_group.srv-rg.location}"
  resource_group_name = "${}"
  type = "IPsec"
  virtual_network_gateway_id = "${}"
  local_network_gateway_id = "${}"
  use_policy_based_traffic_selectors = true
  shared_key = "${var.ipsec_key}"
  ipsec_policy {
    dh_group = "DHGroup2"
    ike_encryption = "AES256"
    ike_integrity = "SHA256"
    ipsec_encryption = "AES256"
    ipsec_integrity = "SHA256"
    pfs_group = "None"
    sa_lifetime = "28800"



Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.