From 54d4961d381e319a337b1deca7b9d6bbc535c8f2 Mon Sep 17 00:00:00 2001 From: Horia Gunica <43091730+horiagunica@users.noreply.github.com> Date: Fri, 13 Sep 2024 11:22:24 +0300 Subject: [PATCH] feat(vmseries): VMSeries appgw backend pool association (#89) Co-authored-by: Adrian Celebanski --- examples/common_vmseries/README.md | 5 ++++- examples/common_vmseries/main.tf | 2 ++ examples/common_vmseries/variables.tf | 20 +++++++++++++++++++- examples/dedicated_vmseries/README.md | 5 ++++- examples/dedicated_vmseries/main.tf | 2 ++ examples/dedicated_vmseries/variables.tf | 20 +++++++++++++++++++- examples/gwlb_with_vmseries/README.md | 5 ++++- examples/gwlb_with_vmseries/main.tf | 2 ++ examples/gwlb_with_vmseries/variables.tf | 20 +++++++++++++++++++- examples/standalone_vmseries/README.md | 5 ++++- examples/standalone_vmseries/main.tf | 2 ++ examples/standalone_vmseries/variables.tf | 20 +++++++++++++++++++- modules/vmseries/README.md | 7 +++++++ modules/vmseries/main.tf | 15 +++++++++++++++ modules/vmseries/variables.tf | 14 ++++++++++++++ 15 files changed, 136 insertions(+), 8 deletions(-) diff --git a/examples/common_vmseries/README.md b/examples/common_vmseries/README.md index 4ecfa00..2bcc1b2 100644 --- a/examples/common_vmseries/README.md +++ b/examples/common_vmseries/README.md @@ -1135,7 +1135,9 @@ The most basic properties are as follows: backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). @@ -1197,6 +1199,7 @@ map(object({ private_ip_address = optional(string) load_balancer_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` diff --git a/examples/common_vmseries/main.tf b/examples/common_vmseries/main.tf index 2e3ab8e..9d2c035 100644 --- a/examples/common_vmseries/main.tf +++ b/examples/common_vmseries/main.tf @@ -443,6 +443,8 @@ module "vmseries" { private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null lb_backend_pool_id = try(module.load_balancer[v.load_balancer_key].backend_pool_id, null) + attach_to_appgw_backend_pool = v.appgw_backend_pool_id != null + appgw_backend_pool_id = try(v.appgw_backend_pool_id, null) }] tags = var.tags diff --git a/examples/common_vmseries/variables.tf b/examples/common_vmseries/variables.tf index d561727..df3706e 100644 --- a/examples/common_vmseries/variables.tf +++ b/examples/common_vmseries/variables.tf @@ -818,7 +818,9 @@ variable "vmseries" { backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF @@ -878,6 +880,7 @@ variable "vmseries" { private_ip_address = optional(string) load_balancer_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package @@ -903,6 +906,21 @@ variable "vmseries" { The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set. EOF } + validation { # interfaces.application_gateway_key & interfaces.appgw_backend_pool_id + condition = alltrue([ + for _, v in var.vmseries : alltrue([ + for nic in v.interfaces : + ( + (nic.application_gateway_key == null || nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key != null && nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key == null && nic.appgw_backend_pool_id != null) + ) + ]) + ]) + error_message = <<-EOF + Only one of `application_gateway_key` or `appgw_backend_pool_id` can be set under an interface, but not both. + EOF + } } # TEST INFRASTRUCTURE diff --git a/examples/dedicated_vmseries/README.md b/examples/dedicated_vmseries/README.md index f812598..abcad77 100644 --- a/examples/dedicated_vmseries/README.md +++ b/examples/dedicated_vmseries/README.md @@ -1139,7 +1139,9 @@ The most basic properties are as follows: backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). @@ -1201,6 +1203,7 @@ map(object({ private_ip_address = optional(string) load_balancer_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` diff --git a/examples/dedicated_vmseries/main.tf b/examples/dedicated_vmseries/main.tf index 2e3ab8e..9d2c035 100644 --- a/examples/dedicated_vmseries/main.tf +++ b/examples/dedicated_vmseries/main.tf @@ -443,6 +443,8 @@ module "vmseries" { private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null lb_backend_pool_id = try(module.load_balancer[v.load_balancer_key].backend_pool_id, null) + attach_to_appgw_backend_pool = v.appgw_backend_pool_id != null + appgw_backend_pool_id = try(v.appgw_backend_pool_id, null) }] tags = var.tags diff --git a/examples/dedicated_vmseries/variables.tf b/examples/dedicated_vmseries/variables.tf index d561727..df3706e 100644 --- a/examples/dedicated_vmseries/variables.tf +++ b/examples/dedicated_vmseries/variables.tf @@ -818,7 +818,9 @@ variable "vmseries" { backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF @@ -878,6 +880,7 @@ variable "vmseries" { private_ip_address = optional(string) load_balancer_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package @@ -903,6 +906,21 @@ variable "vmseries" { The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set. EOF } + validation { # interfaces.application_gateway_key & interfaces.appgw_backend_pool_id + condition = alltrue([ + for _, v in var.vmseries : alltrue([ + for nic in v.interfaces : + ( + (nic.application_gateway_key == null || nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key != null && nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key == null && nic.appgw_backend_pool_id != null) + ) + ]) + ]) + error_message = <<-EOF + Only one of `application_gateway_key` or `appgw_backend_pool_id` can be set under an interface, but not both. + EOF + } } # TEST INFRASTRUCTURE diff --git a/examples/gwlb_with_vmseries/README.md b/examples/gwlb_with_vmseries/README.md index 098a098..aa4529b 100644 --- a/examples/gwlb_with_vmseries/README.md +++ b/examples/gwlb_with_vmseries/README.md @@ -784,7 +784,9 @@ The most basic properties are as follows: backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). @@ -847,6 +849,7 @@ map(object({ gwlb_key = optional(string) gwlb_backend_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` diff --git a/examples/gwlb_with_vmseries/main.tf b/examples/gwlb_with_vmseries/main.tf index 0e20662..b72c471 100644 --- a/examples/gwlb_with_vmseries/main.tf +++ b/examples/gwlb_with_vmseries/main.tf @@ -316,6 +316,8 @@ module "vmseries" { private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null || v.gwlb_key != null lb_backend_pool_id = try(module.gwlb[v.gwlb_key].backend_pool_ids[v.gwlb_backend_key], null) + attach_to_appgw_backend_pool = v.appgw_backend_pool_id != null + appgw_backend_pool_id = try(v.appgw_backend_pool_id, null) }] tags = var.tags diff --git a/examples/gwlb_with_vmseries/variables.tf b/examples/gwlb_with_vmseries/variables.tf index 24911d6..e49413d 100644 --- a/examples/gwlb_with_vmseries/variables.tf +++ b/examples/gwlb_with_vmseries/variables.tf @@ -539,7 +539,9 @@ variable "vmseries" { backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF @@ -600,6 +602,7 @@ variable "vmseries" { gwlb_key = optional(string) gwlb_backend_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package @@ -624,6 +627,21 @@ variable "vmseries" { The `data_snet_key` is required when `bootstrap_xml_template` is set. EOF } + validation { # interfaces.application_gateway_key & interfaces.appgw_backend_pool_id + condition = alltrue([ + for _, v in var.vmseries : alltrue([ + for nic in v.interfaces : + ( + (nic.application_gateway_key == null || nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key != null && nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key == null && nic.appgw_backend_pool_id != null) + ) + ]) + ]) + error_message = <<-EOF + Only one of `application_gateway_key` or `appgw_backend_pool_id` can be set under an interface, but not both. + EOF + } } # TEST INFRASTRUCTURE diff --git a/examples/standalone_vmseries/README.md b/examples/standalone_vmseries/README.md index 7f95591..57c8512 100644 --- a/examples/standalone_vmseries/README.md +++ b/examples/standalone_vmseries/README.md @@ -1073,7 +1073,9 @@ The most basic properties are as follows: backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). @@ -1135,6 +1137,7 @@ map(object({ private_ip_address = optional(string) load_balancer_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) ``` diff --git a/examples/standalone_vmseries/main.tf b/examples/standalone_vmseries/main.tf index 2e3ab8e..9d2c035 100644 --- a/examples/standalone_vmseries/main.tf +++ b/examples/standalone_vmseries/main.tf @@ -443,6 +443,8 @@ module "vmseries" { private_ip_address = v.private_ip_address attach_to_lb_backend_pool = v.load_balancer_key != null lb_backend_pool_id = try(module.load_balancer[v.load_balancer_key].backend_pool_id, null) + attach_to_appgw_backend_pool = v.appgw_backend_pool_id != null + appgw_backend_pool_id = try(v.appgw_backend_pool_id, null) }] tags = var.tags diff --git a/examples/standalone_vmseries/variables.tf b/examples/standalone_vmseries/variables.tf index d561727..df3706e 100644 --- a/examples/standalone_vmseries/variables.tf +++ b/examples/standalone_vmseries/variables.tf @@ -818,7 +818,9 @@ variable "vmseries" { backend pool. - `application_gateway_key` - (`string`, optional, defaults to `null`) key of an Application Gateway defined in `var.appgws` variable, network interface that has this property defined will be added to the Application - Gateway's backend pool. + Gateway's backend pool. Mutually exclusive with `appgw_backend_pool_id`. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of the Application Gateway backend pool to which + the network interface will be added. Mutually exclusive with `application_gateway_key`. For details on all properties refer to [module's documentation](../../modules/panorama/README.md#interfaces). EOF @@ -878,6 +880,7 @@ variable "vmseries" { private_ip_address = optional(string) load_balancer_key = optional(string) application_gateway_key = optional(string) + appgw_backend_pool_id = optional(string) })) })) validation { # virtual_machine.bootstrap_options & virtual_machine.bootstrap_package @@ -903,6 +906,21 @@ variable "vmseries" { The `private_snet_key` and `public_snet_key` are required when `bootstrap_xml_template` is set. EOF } + validation { # interfaces.application_gateway_key & interfaces.appgw_backend_pool_id + condition = alltrue([ + for _, v in var.vmseries : alltrue([ + for nic in v.interfaces : + ( + (nic.application_gateway_key == null || nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key != null && nic.appgw_backend_pool_id == null) || + (nic.application_gateway_key == null && nic.appgw_backend_pool_id != null) + ) + ]) + ]) + error_message = <<-EOF + Only one of `application_gateway_key` or `appgw_backend_pool_id` can be set under an interface, but not both. + EOF + } } # TEST INFRASTRUCTURE diff --git a/modules/vmseries/README.md b/modules/vmseries/README.md index 4c4db6f..180b986 100644 --- a/modules/vmseries/README.md +++ b/modules/vmseries/README.md @@ -48,6 +48,7 @@ If your Region doesn't, use an alternative mechanism of Availability Set, which - `linux_virtual_machine` (managed) - `network_interface` (managed) +- `network_interface_application_gateway_backend_address_pool_association` (managed) - `network_interface_backend_address_pool_association` (managed) - `public_ip` (managed) - `public_ip` (data) @@ -287,6 +288,10 @@ Following configuration options are available: interface with a Load Balancer backend pool. - `lb_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing backend pool to associate the interface with. +- `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing Application Gateway backend pool + to associate the interface with. +- `attach_to_appgw_backend_pool` - (`bool`, optional, defaults to `false`) set to `true` if you would like to associate this + interface with an Application Gateway backend pool. Example: @@ -325,6 +330,8 @@ list(object({ private_ip_address = optional(string) lb_backend_pool_id = optional(string) attach_to_lb_backend_pool = optional(bool, false) + appgw_backend_pool_id = optional(string) + attach_to_appgw_backend_pool = optional(bool, false) })) ``` diff --git a/modules/vmseries/main.tf b/modules/vmseries/main.tf index 8b38b0a..61de0ae 100644 --- a/modules/vmseries/main.tf +++ b/modules/vmseries/main.tf @@ -133,3 +133,18 @@ resource "azurerm_network_interface_backend_address_pool_association" "this" { azurerm_linux_virtual_machine.this ] } + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface_application_gateway_backend_address_pool_association +resource "azurerm_network_interface_application_gateway_backend_address_pool_association" "this" { + + for_each = { for v in var.interfaces : v.name => v.appgw_backend_pool_id if v.attach_to_appgw_backend_pool } + + network_interface_id = azurerm_network_interface.this[each.key].id + ip_configuration_name = azurerm_network_interface.this[each.key].ip_configuration[0].name + backend_address_pool_id = each.value + + depends_on = [ + azurerm_network_interface.this, + azurerm_linux_virtual_machine.this + ] +} diff --git a/modules/vmseries/variables.tf b/modules/vmseries/variables.tf index 3f7b889..26363be 100644 --- a/modules/vmseries/variables.tf +++ b/modules/vmseries/variables.tf @@ -218,6 +218,10 @@ variable "interfaces" { interface with a Load Balancer backend pool. - `lb_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing backend pool to associate the interface with. + - `appgw_backend_pool_id` - (`string`, optional, defaults to `null`) ID of an existing Application Gateway backend pool + to associate the interface with. + - `attach_to_appgw_backend_pool` - (`bool`, optional, defaults to `false`) set to `true` if you would like to associate this + interface with an Application Gateway backend pool. Example: @@ -252,6 +256,8 @@ variable "interfaces" { private_ip_address = optional(string) lb_backend_pool_id = optional(string) attach_to_lb_backend_pool = optional(bool, false) + appgw_backend_pool_id = optional(string) + attach_to_appgw_backend_pool = optional(bool, false) })) validation { # create_public_ip, public_ip_name condition = alltrue([ @@ -277,4 +283,12 @@ variable "interfaces" { The `lb_backend_pool_id` cannot be `null` when `attach_to_lb_backend_pool` is set to `true`. EOF } + validation { # appgw_backend_pool_id & attach_to_appgw_backend_pool + condition = alltrue([ + for v in var.interfaces : v.appgw_backend_pool_id != null if v.attach_to_appgw_backend_pool + ]) + error_message = <<-EOF + The `appgw_backend_pool_id` cannot be `null` when `attach_to_appgw_backend_pool` is set to `true`. + EOF + } }