diff --git a/azure_vpn/vpn_gateway_connection/data.tf b/azure_vpn/vpn_gateway_connection/data.tf new file mode 100644 index 0000000..5ba7ebb --- /dev/null +++ b/azure_vpn/vpn_gateway_connection/data.tf @@ -0,0 +1,2 @@ +# Get the current client configuration from the AzureRM provider +data "azurerm_client_config" "current" {} diff --git a/azure_vpn/vpn_gateway_connection/locals.tf b/azure_vpn/vpn_gateway_connection/locals.tf new file mode 100644 index 0000000..c117cce --- /dev/null +++ b/azure_vpn/vpn_gateway_connection/locals.tf @@ -0,0 +1,4 @@ +locals { + subscription_id_connectivity = coalesce(var.subscription_id_connectivity, local.subscription_id_management) + subscription_id_management = coalesce(var.subscription_id_management, data.azurerm_client_config.current.subscription_id) +} diff --git a/azure_vpn/vpn_gateway_connection/main.tf b/azure_vpn/vpn_gateway_connection/main.tf new file mode 100644 index 0000000..e69de29 diff --git a/azure_vpn/vpn_gateway_connection/outputs.tf b/azure_vpn/vpn_gateway_connection/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/azure_vpn/vpn_gateway_connection/provider.tf b/azure_vpn/vpn_gateway_connection/provider.tf new file mode 100644 index 0000000..a1023f0 --- /dev/null +++ b/azure_vpn/vpn_gateway_connection/provider.tf @@ -0,0 +1,7 @@ +provider "azurerm" { + use_oidc = true + features {} + # NOTE: The assumption is that the pipeline will be using the Management subscription for the base provider + # The sub-modules will be using the subscription_id_connectivity + subscription_id = var.subscription_id_connectivity +} diff --git a/azure_vpn/vpn_gateway_connection/variables-vpn-gateway-connection.tf b/azure_vpn/vpn_gateway_connection/variables-vpn-gateway-connection.tf new file mode 100644 index 0000000..1db74aa --- /dev/null +++ b/azure_vpn/vpn_gateway_connection/variables-vpn-gateway-connection.tf @@ -0,0 +1,76 @@ +variable "vpn_gateway_connection_name" { + description = "(Required) The name which should be used for this VPN Gateway Connection. Changing this forces a new VPN Gateway Connection to be created." + type = string +} + +variable "remote_vpn_site_id" { + description = "(Required) The ID of the remote VPN Site, which will connect to the VPN Gateway. Changing this forces a new VPN Gateway Connection to be created." + type = string +} + +variable "vpn_gateway_id" { + description = "(Required) The ID of the VPN Gateway that this VPN Gateway Connection belongs to. Changing this forces a new VPN Gateway Connection to be created." + type = string +} + +variable "vpn_link" { + description = "(Required) One or more vpn_link blocks" + type = list(object({ + name = string + egress_nat_rule_ids = optional(list(string)) + ingress_nat_rule_ids = optional(list(string)) + vpn_site_link_id = string + bandwidth_mbps = optional(number) + bgp_enabled = optional(bool) + connection_mode = optional(string) + ipsec_policy = optional(list(object({ + dh_group = string + ike_encryption_algorithm = string + ike_integrity_algorithm = string + encryption_algorithm = string + integrity_algorithm = string + pfs_group = string + sa_data_size_kb = number + sa_lifetime_sec = number + }))) + protocol = optional(string) + ratelimit_enabled = optional(bool) + route_weight = optional(number) + shared_key = optional(string) + local_azure_ip_address_enabled = optional(bool) + policy_based_traffic_selector_enabled = optional(bool) + custom_bgp_address = optional(list(object({ + ip_address = string + ip_configuration_id = string + }))) + })) +} + +variable "internet_security_enabled" { + description = "(Optional) Whether Internet Security is enabled for this VPN Connection." + type = bool + default = false +} + +variable "routing" { + description = "(Optional) A routing block as defined below. If this is not specified, there will be a default route table created implicitly." + type = object({ + associated_route_table = string + propagated_route_table = optional(object({ + route_table_ids = list(string) + labels = optional(list(string)) + })) + inbound_route_map_id = optional(string) + outbound_route_map_id = optional(string) + }) + default = null +} + +variable "traffic_selector_policy" { + description = "(Optional) One or more traffic_selector_policy blocks" + type = list(object({ + local_address_ranges = list(string) + remote_address_ranges = list(string) + })) + default = null +} \ No newline at end of file diff --git a/azure_vpn/vpn_gateway_connection/variables.tf b/azure_vpn/vpn_gateway_connection/variables.tf new file mode 100644 index 0000000..fa762ff --- /dev/null +++ b/azure_vpn/vpn_gateway_connection/variables.tf @@ -0,0 +1,15 @@ +variable "subscription_id_management" { + type = string + description = "Subscription ID to use for \"management\" resources." +} + +variable "subscription_id_connectivity" { + type = string + description = "Subscription ID to use for \"connectivity\" resources." +} + +variable "tags" { + type = map(string) + description = "A mapping of tags to assign to the resource." + default = null +} diff --git a/azure_vpn/vpn_gateway_connection/vpn_gateway_connection.tf b/azure_vpn/vpn_gateway_connection/vpn_gateway_connection.tf new file mode 100644 index 0000000..93c00a3 --- /dev/null +++ b/azure_vpn/vpn_gateway_connection/vpn_gateway_connection.tf @@ -0,0 +1,81 @@ +resource "azurerm_vpn_gateway_connection" "this" { + name = var.vpn_gateway_connection_name + remote_vpn_site_id = var.remote_vpn_site_id + vpn_gateway_id = var.vpn_gateway_id + + dynamic "vpn_link" { + for_each = var.vpn_link + + content { + name = vpn_link.value.name + egress_nat_rule_ids = vpn_link.value.egress_nat_rule_ids + ingress_nat_rule_ids = vpn_link.value.ingress_nat_rule_ids + vpn_site_link_id = vpn_link.value.vpn_site_link_id + bandwidth_mbps = vpn_link.value.bandwidth_mbps + bgp_enabled = vpn_link.value.bgp_enabled + connection_mode = vpn_link.value.connection_mode + + dynamic "ipsec_policy" { + for_each = vpn_link.value.ipsec_policy != null ? vpn_link.value.ipsec_policy : [] + + content { + dh_group = ipsec_policy.value.dh_group + ike_encryption_algorithm = ipsec_policy.value.ike_encryption_algorithm + ike_integrity_algorithm = ipsec_policy.value.ike_integrity_algorithm + encryption_algorithm = ipsec_policy.value.encryption_algorithm + integrity_algorithm = ipsec_policy.value.integrity_algorithm + pfs_group = ipsec_policy.value.pfs_group + sa_data_size_kb = ipsec_policy.value.sa_data_size_kb + sa_lifetime_sec = ipsec_policy.value.sa_lifetime_sec + } + } + + protocol = vpn_link.value.protocol + ratelimit_enabled = vpn_link.value.ratelimit_enabled + route_weight = vpn_link.value.route_weight + shared_key = vpn_link.value.shared_key + local_azure_ip_address_enabled = vpn_link.value.local_azure_ip_address_enabled + policy_based_traffic_selector_enabled = vpn_link.value.policy_based_traffic_selector_enabled + + dynamic "custom_bgp_address" { + for_each = vpn_link.value.custom_bgp_address != null ? [vpn_link.value.custom_bgp_address] : [] + + content { + ip_address = custom_bgp_address.value.ip_address + ip_configuration_id = custom_bgp_address.value.ip_configuration_id + } + } + } + } + + internet_security_enabled = var.internet_security_enabled + + dynamic "routing" { + for_each = var.routing != null ? [var.routing] : [] + + content { + associated_route_table = routing.value.associated_route_table + + dynamic "propagated_route_table" { + for_each = routing.value.propagated_route_table != null ? [routing.value.propagated_route_table] : [] + + content { + route_table_ids = propagated_route_table.value.route_table_ids + labels = propagated_route_table.value.labels + } + } + + inbound_route_map_id = routing.value.inbound_route_map_id + outbound_route_map_id = routing.value.outbound_route_map_id + } + } + + dynamic "traffic_selector_policy" { + for_each = var.traffic_selector_policy != null ? var.traffic_selector_policy : [] + + content { + local_address_ranges = traffic_selector_policy.value.local_address_ranges + remote_address_ranges = traffic_selector_policy.value.remote_address_ranges + } + } +} \ No newline at end of file diff --git a/azure_vpn/vpn_site/data.tf b/azure_vpn/vpn_site/data.tf new file mode 100644 index 0000000..5ba7ebb --- /dev/null +++ b/azure_vpn/vpn_site/data.tf @@ -0,0 +1,2 @@ +# Get the current client configuration from the AzureRM provider +data "azurerm_client_config" "current" {} diff --git a/azure_vpn/vpn_site/locals.tf b/azure_vpn/vpn_site/locals.tf new file mode 100644 index 0000000..c117cce --- /dev/null +++ b/azure_vpn/vpn_site/locals.tf @@ -0,0 +1,4 @@ +locals { + subscription_id_connectivity = coalesce(var.subscription_id_connectivity, local.subscription_id_management) + subscription_id_management = coalesce(var.subscription_id_management, data.azurerm_client_config.current.subscription_id) +} diff --git a/azure_vpn/vpn_site/main.tf b/azure_vpn/vpn_site/main.tf new file mode 100644 index 0000000..e69de29 diff --git a/azure_vpn/vpn_site/outputs.tf b/azure_vpn/vpn_site/outputs.tf new file mode 100644 index 0000000..8386d52 --- /dev/null +++ b/azure_vpn/vpn_site/outputs.tf @@ -0,0 +1,9 @@ +output "vpn_site_id" { + description = "The ID of the VPN Site." + value = azurerm_vpn_site.this.id +} + +output "vpn_site_link" { + description = "The link block of the VPN Site." + value = azurerm_vpn_site.this.link +} \ No newline at end of file diff --git a/azure_vpn/vpn_site/provider.tf b/azure_vpn/vpn_site/provider.tf new file mode 100644 index 0000000..a1023f0 --- /dev/null +++ b/azure_vpn/vpn_site/provider.tf @@ -0,0 +1,7 @@ +provider "azurerm" { + use_oidc = true + features {} + # NOTE: The assumption is that the pipeline will be using the Management subscription for the base provider + # The sub-modules will be using the subscription_id_connectivity + subscription_id = var.subscription_id_connectivity +} diff --git a/azure_vpn/vpn_site/variables-vpn-site.tf b/azure_vpn/vpn_site/variables-vpn-site.tf new file mode 100644 index 0000000..6aa72d6 --- /dev/null +++ b/azure_vpn/vpn_site/variables-vpn-site.tf @@ -0,0 +1,65 @@ +variable "resource_group_name" { + description = "(Required) The name of the Resource Group where the VPN Site should exist. Changing this forces a new VPN Site to be created." + type = string +} + +variable "location" { + description = "(Required) The Azure Region where the VPN Site should exist. Changing this forces a new VPN Site to be created." + type = string +} + +variable "vpn_site_name" { + description = "(Required) The name which should be used for this VPN Site. Changing this forces a new VPN Site to be created." + type = string +} + +variable "virtual_wan_id" { + description = "(Required) The ID of the Virtual Wan where this VPN site resides in. Changing this forces a new VPN Site to be created." + type = string +} + +variable "link" { + description = "(Optional) One or more link blocks." + type = list(object({ + name = string + bgp = optional(object({ + asn = number + peering_address = string + })) + fqdn = optional(string) + ip_address = optional(string) + provider_name = optional(string) + speed_in_mbps = optional(number) + })) + default = null +} + +variable "address_cidrs" { + description = "(Optional) Specifies a list of IP address CIDRs that are located on your on-premises site. Traffic destined for these address spaces is routed to your local site." + type = list(string) + default = null +} + +variable "device_model" { + description = "(Optional) The model of the VPN device." + type = string + default = null +} + +variable "device_vendor" { + description = "(Optional) The name of the VPN device vendor." + type = string + default = null +} + +variable "o365_policy" { + description = "(Optional) An o365_policy block." + type = object({ + traffic_category = optional(object({ + allow_endpoint_enabled = optional(bool) + default_endpoint_enabled = optional(bool) + optimize_endpoint_enabled = optional(bool) + })) + }) + default = null +} \ No newline at end of file diff --git a/azure_vpn/vpn_site/variables.tf b/azure_vpn/vpn_site/variables.tf new file mode 100644 index 0000000..fa762ff --- /dev/null +++ b/azure_vpn/vpn_site/variables.tf @@ -0,0 +1,15 @@ +variable "subscription_id_management" { + type = string + description = "Subscription ID to use for \"management\" resources." +} + +variable "subscription_id_connectivity" { + type = string + description = "Subscription ID to use for \"connectivity\" resources." +} + +variable "tags" { + type = map(string) + description = "A mapping of tags to assign to the resource." + default = null +} diff --git a/azure_vpn/vpn_site/vpn_site.tf b/azure_vpn/vpn_site/vpn_site.tf new file mode 100644 index 0000000..835761c --- /dev/null +++ b/azure_vpn/vpn_site/vpn_site.tf @@ -0,0 +1,49 @@ +resource "azurerm_vpn_site" "this" { + name = var.vpn_site_name + resource_group_name = var.resource_group_name + location = var.location + virtual_wan_id = var.virtual_wan_id + + dynamic "link" { + for_each = var.link + + content { + name = link.value.name + fqdn = link.value.fqdn + ip_address = link.value.ip_address + provider_name = link.value.provider_name + speed_in_mbps = link.value.speed_in_mbps + + dynamic "bgp" { + for_each = link.value.bgp != null ? [link.value.bgp] : [] + + content { + asn = bgp.value.asn + peering_address = bgp.value.peering_address + } + } + } + } + + address_cidrs = var.address_cidrs + device_model = var.device_model + device_vendor = var.device_vendor + + dynamic "o365_policy" { + for_each = var.o365_policy != null ? [var.o365_policy] : [] + + content { + dynamic "traffic_category" { + for_each = o365_policy.value.traffic_category != null ? [o365_policy.value.traffic_category] : [] + + content { + allow_endpoint_enabled = traffic_category.value.allow_endpoint_enabled + default_endpoint_enabled = traffic_category.value.default_endpoint_enabled + optimize_endpoint_enabled = traffic_category.value.optimize_endpoint_enabled + } + } + } + } + + tags = var.tags +} \ No newline at end of file