i did a terraform module for manage azure app gateway. In variable.tf i set:
###### RULE apgw-01 ######
variable "rule_apgw-01" {
type = map(object({
backend_address_pool_name = string # Name of the backend address pool
http_setting_name = string # Name of the backend settings
listener_name = string # Name of the listener
request_routing_rule_name = string # Name of the rules
frontend_port_name = string # Name of the frontend port
frontend_port = number
priority = number
port = number
rule_type = string
cookie_based_affinity = string
protocol = string
host_name = string
path = string
fqdns = string
}))
default = {
"dv-apse-01" = {
### backend_address_pool
backend_address_pool_name = "dv-apse-01"
fqdns = "dv-apse-01.azurewebsites.net"
### backend_http_settings
http_setting_name = "dv-apse-01.settings.http"
protocol = "Http"
port = 80
cookie_based_affinity = "Disabled"
path = ""
### listener
listener_name = "dv-apse-01.listener.http"
host_name = "test.xyz.it"
### request_routing_rule
request_routing_rule_name = "dv-apse-01.rule.http"
rule_type = "Basic"
frontend_port_name = "port_80"
frontend_port = 80
priority = 10
}
}
}
main.tf is configured as follow :
terraform {
backend "azurerm" {}
}
module "apgw-01" {
source = "../../../../../modules/application_gateway"
for_each = var.rule_apgw-01
rg_name = data.terraform_remote_state.rg.outputs.rg-apgw
name = "dv-apgw-01"
skuName = "Standard_v2"
skuTier = "Standard_v2"
private_ip_address = "xx.xx.xx.xx"
public_ip_address_id = data.terraform_remote_state.pbip.outputs.public_ip_pbip_apgw_01
tag_division = var.tag_division
tag_project = var.tag_project
### backend_address_pool
backend_address_pool_name = each.value.backend_address_pool_name
fqdns = each.value.fqdns
### backend_http_settings
http_setting_name = each.value.http_setting_name
protocol = each.value.protocol
port = each.value.port
cookie_based_affinity = each.value.cookie_based_affinity
path = each.value.path
### listener
listener_name = each.value.listener_name
host_name = each.value.host_name
### request_routing_rule
request_routing_rule_name = each.value.request_routing_rule_name
rule_type = each.value.rule_type
frontend_port_name = each.value.frontend_port_name
frontend_port = each.value.frontend_port
priority = each.value.priority
}
and call the module:
resource "azurerm_application_gateway" "network" {
name = var.name
resource_group_name = var.rg_name
location = var.location
zones = ["1", "2", "3"]
sku {
name = var.skuName
tier = var.skuTier
capacity = local.capacity_apgw[substr(var.name, 0, 2)]
}
gateway_ip_configuration {
name = "appGatewayIpConfig"
subnet_id = "${local.subnet_id_apgw[substr(var.name, 0, 2)]}"
}
frontend_port {
name = var.frontend_port_name
port = var.frontend_port
}
frontend_ip_configuration { ### public frontend ip
name = "appGwPublicFrontendIp"
public_ip_address_id = var.public_ip_address_id
}
frontend_ip_configuration { ### private frontend ip
name = "appGwPrivateFrontendIp"
subnet_id = "${local.subnet_id_apgw[substr(var.name, 0, 2)]}"
private_ip_address_allocation = "Static"
private_ip_address = var.private_ip_address
}
backend_address_pool {
name = var.backend_address_pool_name
fqdns = [var.fqdns]
}
backend_http_settings {
name = var.http_setting_name
cookie_based_affinity = var.cookie_based_affinity
path = var.path
port = var.port
protocol = var.protocol
request_timeout = var.request_timeout
pick_host_name_from_backend_address = var.pick_host_name_from_backend_address
probe_name = "dv-apse-we-01.probe.http"
}
http_listener {
name = var.listener_name
frontend_ip_configuration_name = "appGwPrivateFrontendIp"
frontend_port_name = var.frontend_port_name
protocol = var.protocol
host_name = var.host_name
}
request_routing_rule {
name = var.request_routing_rule_name
priority = var.priority
rule_type = var.rule_type
http_listener_name = var.listener_name
backend_address_pool_name = var.backend_address_pool_name
backend_http_settings_name = var.http_setting_name
}
probe {
name = "dv-apse-we-01.probe.http"
protocol = "Http"
pick_host_name_from_backend_http_settings = true
path = "/"
interval = 30
timeout = 30
unhealthy_threshold = 3
match {
status_code = ["200-399"]
}
}
probe {
name = "dv-apse-we-01.probe.https"
protocol = "Https"
pick_host_name_from_backend_http_settings = true
path = "/"
interval = 30
timeout = 30
unhealthy_threshold = 3
match {
status_code = ["200-399"]
}
}
tags = {
division = var.tag_division
project = var.tag_project
resourceType = var.tag_resourceType
referent = var.tag_referent
}
lifecycle {
ignore_changes = [tags]
}
}
code is working fine when i execute it the first time, it will create correctly the resource declared. The problem start when i try to add a new block in variable.tf:
default = {
"app01" = {
### backend_address_pool
backend_address_pool_name = "app01"
fqdns = "app01.azurewebsites.net"
### backend_http_settings
http_setting_name = "app01.settings.http"
protocol = "Http"
port = 80
cookie_based_affinity = "Disabled"
path = ""
### listener
listener_name = "app01.listener.http"
host_name = "test.xyz.it"
### request_routing_rule
request_routing_rule_name = "app01.rule.http"
rule_type = "Basic"
frontend_port_name = "port_80"
frontend_port = 80
priority = 10
}
"app02" = {
### backend_address_pool
backend_address_pool_name = "app02"
fqdns = "app02.azurewebsites.net"
### backend_http_settings
http_setting_name = "app02.settings.http"
protocol = "Http"
port = 80
cookie_based_affinity = "Disabled"
path = ""
### listener
listener_name = "app02.listener.http"
host_name = "test2.xyz.it"
### request_routing_rule
request_routing_rule_name = "app02.rule.http"
rule_type = "Basic"
frontend_port_name = "port_80"
frontend_port = 80
priority = 10
}
}
when i execute plan, terraform destroy app gateway and recreate it. Why doesn't terraform recognize that app gateway already exists and just add the new rules? I terraform plan i also see that with the two block it take the 02.
Plan output:
module.apgw-apse-01["dv-apse-02"].azurerm_application_gateway.network: Creating...Error: A resource with the ID"dv-apgw-01" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_application_gateway" for more information. with module.apgw-apse-01["dv-apse-02"].azurerm_application_gateway.network, on ..........\modules\application_gateway\main.tf line 1, in resource "azurerm_application_gateway" "network": 1: resource "azurerm_application_gateway" "network" {
as written before, i solved using dynamic block:
variable "backend_pools" {
description = "Map of backend pools for the application gateway"
type = list(object({
backend_address_pool_name = string # Name of the backend pool
http_setting_name = string # Name of the backend settings
listener_name = string # Name of the listener
request_routing_rule_name = string # Name of the rules
frontend_port_name = string # Name of the frontend port
frontend_port = number
priority = number
port = number
rule_type = string
cookie_based_affinity = string
protocol = string
host_name = string
path = string
fqdns = string
}))
default = [
{
### backend_address_pool
backend_address_pool_name = "dv-apse-01"
fqdns = "dv-apse-01.azurewebsites.net"
### backend_http_settings
http_setting_name = "dv-apse-01.settings.http"
protocol = "Http"
port = 80
cookie_based_affinity = "Disabled"
path = ""
### listener
listener_name = "dv-apse-01.listener.http"
host_name = "app.aaa.it"
### request_routing_rule
request_routing_rule_name = "dv-apse-01.rule.http"
rule_type = "Basic"
frontend_port_name = "port_80"
frontend_port = 80
priority = 10
},
{
### backend_address_pool
backend_address_pool_name = "dv-apse-02"
fqdns = "dv-apse-02.azurewebsites.net"
### backend_http_settings
http_setting_name = "dv-apse-02.settings.http"
protocol = "Http"
port = 80
cookie_based_affinity = "Disabled"
path = ""
### listener
listener_name = "dv-apse-02.listener.http"
host_name = "aaaa.aaa.it"
### request_routing_rule
request_routing_rule_name = "dv-apse-02.rule.http"
rule_type = "Basic"
frontend_port_name = "port_80"
frontend_port = 80
priority = 20
},
{
### backend_address_pool
backend_address_pool_name = "dv-apse-03"
fqdns = "dv-apse-03.azurewebsites.net"
### backend_http_settings
http_setting_name = "dv-apse-03.settings.http"
protocol = "Http"
port = 80
cookie_based_affinity = "Disabled"
path = ""
### listener
listener_name = "dv-apse-03.listener.http"
host_name = "asdad.paa.it"
### request_routing_rule
request_routing_rule_name = "dv-apse-03.rule.http"
rule_type = "Basic"
frontend_port_name = "port_80"
frontend_port = 80
priority = 30
}
]
}
and main now is like:
resource "azurerm_application_gateway" "network" {
name = var.name
resource_group_name = var.rg_name
location = var.location
zones = ["1", "2", "3"]
sku {
name = var.skuName
tier = var.skuTier
capacity = local.capacity_apgw[substr(var.name, 0, 2)]
}
gateway_ip_configuration {
name = "appGatewayIpConfig"
subnet_id = "${local.subnet_id_apgw[substr(var.name, 0, 2)]}"
}
frontend_ip_configuration { ### public frontend ip
name = "appGwPublicFrontendIp"
public_ip_address_id = var.public_ip_address_id
}
frontend_ip_configuration { ### private frontend ip
name = "appGwPrivateFrontendIp"
subnet_id = "${local.subnet_id_apgw[substr(var.name, 0, 2)]}"
private_ip_address_allocation = "Static"
private_ip_address = var.private_ip_address
}
dynamic frontend_port {
for_each = var.backend_pools
content {
name = frontend_port.value.frontend_port_name
port = frontend_port.value.frontend_port
}
}
dynamic backend_address_pool {
for_each = var.backend_pools
content {
name = backend_address_pool.value.backend_address_pool_name
fqdns = [backend_address_pool.value.fqdns]
}
}
dynamic backend_http_settings {
for_each = var.backend_pools
content {
name = backend_http_settings.value.http_setting_name
cookie_based_affinity = backend_http_settings.value.cookie_based_affinity
path = backend_http_settings.value.path
port = backend_http_settings.value.port
protocol = backend_http_settings.value.protocol
request_timeout = var.request_timeout
pick_host_name_from_backend_address = var.pick_host_name_from_backend_address
probe_name = "dv-apse-we-01.probe.http"
}
}
dynamic http_listener {
for_each = var.backend_pools
content {
name = http_listener.value.listener_name
frontend_ip_configuration_name = "appGwPrivateFrontendIp"
frontend_port_name = http_listener.value.frontend_port_name
protocol = http_listener.value.protocol
host_name = http_listener.value.host_name
}
}
dynamic request_routing_rule {
for_each = var.backend_pools
content {
name = request_routing_rule.value.request_routing_rule_name
priority = request_routing_rule.value.priority
rule_type = request_routing_rule.value.rule_type
http_listener_name = request_routing_rule.value.listener_name
backend_address_pool_name = request_routing_rule.value.backend_address_pool_name
backend_http_settings_name = request_routing_rule.value.http_setting_name
}
}
probe {
name = "dv-apse-we-01.probe.http"
protocol = "Http"
pick_host_name_from_backend_http_settings = true
path = "/"
interval = 30
timeout = 30
unhealthy_threshold = 3
match {
status_code = ["200-399"]
}
}
probe {
name = "dv-apse-we-01.probe.https"
protocol = "Https"
pick_host_name_from_backend_http_settings = true
path = "/"
interval = 30
timeout = 30
unhealthy_threshold = 3
match {
status_code = ["200-399"]
}
}
tags = {
division = var.tag_division
project = var.tag_project
resourceType = var.tag_resourceType
referent = var.tag_referent
}
lifecycle {
ignore_changes = [tags]
}
}