4

I can't find a way to create an application gateway via terraform with private IP without manually inserting hard coded IP private address.

I tried:

  1. Create a private IP in the application gateway subnet - failed because Azure blocks (attached error from the UI, but terraform raises the same error) itenter image description here
  2. Create a dynamic private IP in the application gateway subnet - Failed

Only when creating an application gateway with hard coded ip address it works.

This solution is not good enough for me because we handle many environents and we don't want to relay on developers to remember adding a private IP.

Is there a good solution?

Or Gaizer
  • 93
  • 3
  • 7

2 Answers2

2

Application Gateway v2 SKU supports the static VIP type exclusively, whereas the V1 SKU can be configured to support static or dynamic internal IP address and dynamic public IP address.

Refer: Application Gateway frontend-ip-addresses

Application Gateway V2 currently does not support only private IP mode. The Azure Application Gateway V2 SKU can be configured to support either both static internal IP address and static public IP address, or only static public IP address. It cannot be configured to support only static internal IP address.

Refer: Application gateway v2 with only private-ip

While deploying using terraform, we should define two frontend_ip_configuration blocks, one is used for public IP configuration, another is used for private IP configuration.

Scenario 1: When trying to create a new application gateway with dynamic private IP and dynamic public IP using terraform it gets created for Standard or V1 SKU only.

terraform { 

  required_providers { 

    azurerm = { 

      source  = "hashicorp/azurerm" 

      version = "~> 2.65" 

    } 

  } 

 

  required_version = ">= 0.14.9" 

} 

 

provider "azurerm" { 

  features {} 

} 

resource "azurerm_resource_group" "test" { 

  name     = "Terraformtest" 

  location = "West Europe" 

} 

resource "azurerm_virtual_network" "test" { 

  name                = "terraformvnet" 

  resource_group_name = azurerm_resource_group.test.name 

  location            = azurerm_resource_group.test.location 

  address_space       = ["10.254.0.0/16"] 

} 

 

resource "azurerm_subnet" "frontend" { 

  name                 = "frontend" 

  resource_group_name  = azurerm_resource_group.test.name 

  virtual_network_name = azurerm_virtual_network.test.name 

  address_prefixes     = ["10.254.0.0/24"] 

} 

 

resource "azurerm_subnet" "backend" { 

  name                 = "backend" 

  resource_group_name  = azurerm_resource_group.test.name 

  virtual_network_name = azurerm_virtual_network.test.name 

  address_prefixes     = ["10.254.2.0/24"] 

} 

 

resource "azurerm_public_ip" "test" { 

  name                = "test-pip" 

  resource_group_name = azurerm_resource_group.test.name 

  location            = azurerm_resource_group.test.location 

  allocation_method   = "Dynamic" 

} 

locals { 

  backend_address_pool_name      = "${azurerm_virtual_network.test.name}-beap" 

  frontend_port_name             = "${azurerm_virtual_network.test.name}-feport" 

  frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" 

  http_setting_name              = "${azurerm_virtual_network.test.name}-be-htst" 

  listener_name                  = "${azurerm_virtual_network.test.name}-httplstn" 

  request_routing_rule_name      = "${azurerm_virtual_network.test.name}-rqrt" 

  redirect_configuration_name    = "${azurerm_virtual_network.test.name}-rdrcfg" 

} 

 

resource "azurerm_application_gateway" "network" { 

  name                = "test-appgateway" 

  resource_group_name = "${azurerm_resource_group.test.name}" 

  location            = "${azurerm_resource_group.test.location}" 

 

  sku { 

    name     = "Standard_Small" 

    tier     = "Standard" 

    capacity = 2 

  } 

 

  gateway_ip_configuration { 

    name      = "my-gateway-ip-configuration" 

    subnet_id = "${azurerm_subnet.frontend.id}" 

  } 

 

  frontend_port { 

    name = "${local.frontend_port_name}" 

    port = 80 

  } 

 

  frontend_ip_configuration { 

    name                 = "${local.frontend_ip_configuration_name}" 

    public_ip_address_id = "${azurerm_public_ip.test.id}" 

  } 

 

 frontend_ip_configuration { 

    name                 = "${local.frontend_ip_configuration_name}-private" 

    subnet_id = "${azurerm_subnet.frontend.id}" 

    private_ip_address_allocation = "Dynamic" 

  } 

  backend_address_pool { 

    name = "${local.backend_address_pool_name}" 

  } 

 

  backend_http_settings { 

    name                  = "${local.http_setting_name}" 

    cookie_based_affinity = "Disabled" 

    path                  = "/path1/" 

    port                  = 80 

    protocol              = "Http" 

    request_timeout       = 1 

  } 

 

  http_listener { 

    name                           = "${local.listener_name}" 

    frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}-private" 

    frontend_port_name             = "${local.frontend_port_name}" 

    protocol                       = "Http" 

  } 

 

  request_routing_rule { 

    name                       = "${local.request_routing_rule_name}" 

    rule_type                  = "Basic" 

    http_listener_name         = "${local.listener_name}" 

    backend_address_pool_name  = "${local.backend_address_pool_name}" 

    backend_http_settings_name = "${local.http_setting_name}" 

  } 

} 

Scenario 2: While creating a Standard V2 we can create a private IP but it doesn’t support dynamic allocation yet so it must be static, and you must mention the IP address you want to use. and to use that you must select standard sku for public IP and static IP address allocation for public as well.

enter image description here

enter image description here

enter image description herez

So, after updating private_ip_address_allocation = "Static" and private_ip_address = "10.254.0.10" it will get created successfully.

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 2.65"
    }
  }

  required_version = ">= 0.14.9"
}

provider "azurerm" {
  features {}
}
resource "azurerm_resource_group" "test" {
  name     = "Terraformtest"
  location = "West Europe"
}
resource "azurerm_virtual_network" "test" {
  name                = "terraformvnet"
  resource_group_name = azurerm_resource_group.test.name
  location            = azurerm_resource_group.test.location
  address_space       = ["10.254.0.0/16"]
}

resource "azurerm_subnet" "frontend" {
  name                 = "frontend"
  resource_group_name  = azurerm_resource_group.test.name
  virtual_network_name = azurerm_virtual_network.test.name
  address_prefixes     = ["10.254.0.0/24"]
}

resource "azurerm_subnet" "backend" {
  name                 = "backend"
  resource_group_name  = azurerm_resource_group.test.name
  virtual_network_name = azurerm_virtual_network.test.name
  address_prefixes     = ["10.254.2.0/24"]
}

resource "azurerm_public_ip" "test" {
  name                = "test-pip"
  resource_group_name = azurerm_resource_group.test.name
  location            = azurerm_resource_group.test.location
  allocation_method   = "Static"
  sku  = "Standard"
}
locals {
  backend_address_pool_name      = "${azurerm_virtual_network.test.name}-beap"
  frontend_port_name             = "${azurerm_virtual_network.test.name}-feport"
  frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip"
  http_setting_name              = "${azurerm_virtual_network.test.name}-be-htst"
  listener_name                  = "${azurerm_virtual_network.test.name}-httplstn"
  request_routing_rule_name      = "${azurerm_virtual_network.test.name}-rqrt"
  redirect_configuration_name    = "${azurerm_virtual_network.test.name}-rdrcfg"
}

resource "azurerm_application_gateway" "network" {
  name                = "test-appgateway"
  resource_group_name = "${azurerm_resource_group.test.name}"
  location            = "${azurerm_resource_group.test.location}"

  sku {
    name     = "Standard_v2"
    tier     = "Standard_v2"
    capacity = 2
  }

  gateway_ip_configuration {
    name      = "my-gateway-ip-configuration"
    subnet_id = "${azurerm_subnet.frontend.id}"
  }

  frontend_port {
    name = "${local.frontend_port_name}"
    port = 80
  }

  frontend_ip_configuration {
    name                 = "${local.frontend_ip_configuration_name}"
    public_ip_address_id = "${azurerm_public_ip.test.id}"
  }

 frontend_ip_configuration {
      name                 = "${local.frontend_ip_configuration_name}-private"
    subnet_id = "${azurerm_subnet.frontend.id}"
    private_ip_address_allocation = "Static"
    private_ip_address = "10.254.0.10"
  }
  backend_address_pool {
    name = "${local.backend_address_pool_name}"
  }

  backend_http_settings {
    name                  = "${local.http_setting_name}"
    cookie_based_affinity = "Disabled"
    path                  = "/path1/"
    port                  = 80
    protocol              = "Http"
    request_timeout       = 1
  }

  http_listener {
    name                           = "${local.listener_name}"
    frontend_ip_configuration_name = "${local.frontend_ip_configuration_name}"
    frontend_port_name             = "${local.frontend_port_name}"
    protocol                       = "Http"
  }

  request_routing_rule {
    name                       = "${local.request_routing_rule_name}"
    rule_type                  = "Basic"
    http_listener_name         = "${local.listener_name}"
    backend_address_pool_name  = "${local.backend_address_pool_name}"
    backend_http_settings_name = "${local.http_setting_name}"
  }
}

Note : 2 application gateway cannot use same subnet . So if you are creating a new appgw then you have to create a new subnet.

Ansuman Bal
  • 9,705
  • 2
  • 10
  • 27
1

Can you paste your terraform code?

For the latest terraform version documentation say that block frontend_ip_configuration supports private_ip_address_allocation parameter, which can hold value Dynamic.

Also remember that app gateway has to have a separate network with only application gateway in it. I am not sure, but I suppose that it is gateway per subnet, so 2 gateways in one subnet is impossible.

ValueError
  • 136
  • 3