From 1da9bbcfb2314217f18ae26d9b60d0bec4569b86 Mon Sep 17 00:00:00 2001 From: Liam Nesteroff <35284740+lnesteroff@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:56:40 +1000 Subject: [PATCH] Allowing multiple on-prem domains (#3219) * Allowing multiple on-prem domains * added on_prem domain example for tests * Made gcp domains (gcp.example.com) optional and not created if null --- fast/stages/2-networking-a-simple/README.md | 22 ++++++++------- fast/stages/2-networking-a-simple/dns-dev.tf | 1 + .../2-networking-a-simple/dns-landing.tf | 18 ++++++++---- fast/stages/2-networking-a-simple/dns-prod.tf | 1 + .../stages/2-networking-a-simple/variables.tf | 13 +++++++-- fast/stages/2-networking-b-nva/README.md | 28 ++++++++++--------- fast/stages/2-networking-b-nva/dns-dev.tf | 1 + fast/stages/2-networking-b-nva/dns-landing.tf | 18 ++++++++---- fast/stages/2-networking-b-nva/dns-prod.tf | 1 + fast/stages/2-networking-b-nva/variables.tf | 13 +++++++-- .../2-networking-c-separate-envs/README.md | 18 ++++++------ .../2-networking-c-separate-envs/dns-dev.tf | 14 ++++++---- .../2-networking-c-separate-envs/dns-prod.tf | 14 ++++++---- .../2-networking-c-separate-envs/main.tf | 1 + .../2-networking-c-separate-envs/variables.tf | 25 +++++++++++++++-- .../stages/s2_networking_a_simple/ncc.tfvars | 3 ++ .../s2_networking_a_simple/simple.tfvars | 3 ++ .../stages/s2_networking_a_simple/vpn.tfvars | 3 ++ .../stages/s2_networking_b_nva/ncc-ra.tfvars | 3 ++ .../s2_networking_b_nva/regional.tfvars | 3 ++ .../stages/s2_networking_b_nva/simple.tfvars | 3 ++ .../simple.tfvars | 3 ++ 22 files changed, 149 insertions(+), 60 deletions(-) diff --git a/fast/stages/2-networking-a-simple/README.md b/fast/stages/2-networking-a-simple/README.md index 8a655c8dd..1edb5d197 100644 --- a/fast/stages/2-networking-a-simple/README.md +++ b/fast/stages/2-networking-a-simple/README.md @@ -260,7 +260,9 @@ Spokes can optionally define private zones (e.g. `prod-dns-private-zone`) - gran #### Cloud to on-prem -Leveraging the forwarding zones defined on Landing (e.g. `onprem-example-dns-forwarding` and `reverse-10-dns-forwarding`), the cloud environment can resolve `in-addr.arpa.` and `onprem.example.com.` using the on-premises DNS infrastructure. Onprem resolvers IPs are set in variable `dns.onprem`. +Leveraging the forwarding zones defined on Landing (e.g. `landing-dns-fwd-onprem` and `landing-dns-fwd-onprem-rev-10`), the cloud environment can resolve `in-addr.arpa.` and domains defined in `var.dns.onprem_domain` using the on-premises DNS infrastructure. Onprem resolvers IPs are set in variable `var.dns.resolvers`. + +Domains defined in `var.dns.onprem_domain` can also optionally overwrite the resolver IPs DNS queries sent to the on-premises infrastructure come from the `35.199.192.0/19` source range, which is only accessible from within a VPC or networks connected to one. @@ -505,18 +507,18 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [prefix](variables-fast.tf#L76) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | 0-bootstrap | | [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | object({…}) | | {…} | | | [custom_roles](variables-fast.tf#L40) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | -| [dns](variables.tf#L42) | DNS configuration. | object({…}) | | {} | | -| [essential_contacts](variables.tf#L53) | Email used for essential contacts, unset if null. | string | | null | | -| [factories_config](variables.tf#L59) | Configuration for network resource factories. | object({…}) | | {} | | -| [outputs_location](variables.tf#L80) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | | -| [psa_ranges](variables.tf#L86) | IP ranges used for Private Service Access (CloudSQL, etc.). | object({…}) | | {} | | -| [regions](variables.tf#L106) | Region definitions. | object({…}) | | {…} | | +| [dns](variables.tf#L42) | DNS configuration. | object({…}) | | {} | | +| [essential_contacts](variables.tf#L60) | Email used for essential contacts, unset if null. | string | | null | | +| [factories_config](variables.tf#L66) | Configuration for network resource factories. | object({…}) | | {} | | +| [outputs_location](variables.tf#L87) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | | +| [psa_ranges](variables.tf#L93) | IP ranges used for Private Service Access (CloudSQL, etc.). | object({…}) | | {} | | +| [regions](variables.tf#L113) | Region definitions. | object({…}) | | {…} | | | [security_profile_groups](variables-fast.tf#L86) | Security profile group ids used for policy rule substitutions. | map(string) | | {} | 2-networking-ngfw | -| [spoke_configs](variables.tf#L118) | Spoke connectivity configurations. | object({…}) | | {…} | | +| [spoke_configs](variables.tf#L125) | Spoke connectivity configurations. | object({…}) | | {…} | | | [stage_configs](variables-fast.tf#L94) | FAST stage configuration. | object({…}) | | {} | 1-resman | | [tag_values](variables-fast.tf#L108) | Root-level tag values. | map(string) | | {} | 1-resman | -| [vpc_configs](variables.tf#L187) | Optional VPC network configurations. | object({…}) | | {} | | -| [vpn_onprem_primary_config](variables.tf#L240) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | | +| [vpc_configs](variables.tf#L194) | Optional VPC network configurations. | object({…}) | | {} | | +| [vpn_onprem_primary_config](variables.tf#L247) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | | ## Outputs diff --git a/fast/stages/2-networking-a-simple/dns-dev.tf b/fast/stages/2-networking-a-simple/dns-dev.tf index ccef02fe1..6f09e6137 100644 --- a/fast/stages/2-networking-a-simple/dns-dev.tf +++ b/fast/stages/2-networking-a-simple/dns-dev.tf @@ -20,6 +20,7 @@ module "dev-dns-priv-example" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.dev-spoke-project.project_id name = "dev-${replace(var.dns.gcp_domain, ".", "-")}" zone_config = { diff --git a/fast/stages/2-networking-a-simple/dns-landing.tf b/fast/stages/2-networking-a-simple/dns-landing.tf index 41e52a748..b52c90514 100644 --- a/fast/stages/2-networking-a-simple/dns-landing.tf +++ b/fast/stages/2-networking-a-simple/dns-landing.tf @@ -16,18 +16,25 @@ # tfdoc:file:description Landing DNS zones and peerings setup. +locals { + onprem_domain_map = { for i in var.dns.onprem_domains : i.domain => i } +} + # forwarding to on-prem DNS resolvers -module "landing-dns-fwd-onprem-example" { +module "landing-dns-fwd-onprem" { source = "../../../modules/dns" - count = length(var.dns.resolvers) > 0 ? 1 : 0 + for_each = local.onprem_domain_map project_id = module.landing-project.project_id - name = replace(var.dns.onprem_domain, ".", "-") + name = replace(each.key, ".", "-") zone_config = { - domain = "${var.dns.onprem_domain}." + domain = "${each.key}." forwarding = { client_networks = [module.landing-vpc.self_link] - forwarders = { for ip in var.dns.resolvers : ip => null } + forwarders = (each.value.overwrite_resolver == null ? + { for ip in var.dns.resolvers : ip => null } + : { for ip in each.value.overwrite_resolver : ip => null } + ) } } } @@ -48,6 +55,7 @@ module "landing-dns-fwd-onprem-rev-10" { module "landing-dns-priv-gcp" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.landing-project.project_id name = replace(var.dns.gcp_domain, ".", "-") zone_config = { diff --git a/fast/stages/2-networking-a-simple/dns-prod.tf b/fast/stages/2-networking-a-simple/dns-prod.tf index 6ca0a63cb..0cf64acf3 100644 --- a/fast/stages/2-networking-a-simple/dns-prod.tf +++ b/fast/stages/2-networking-a-simple/dns-prod.tf @@ -20,6 +20,7 @@ module "prod-dns-priv-example" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.prod-spoke-project.project_id name = "prod-${replace(var.dns.gcp_domain, ".", "-")}" zone_config = { diff --git a/fast/stages/2-networking-a-simple/variables.tf b/fast/stages/2-networking-a-simple/variables.tf index b48452e78..b0c01fd99 100644 --- a/fast/stages/2-networking-a-simple/variables.tf +++ b/fast/stages/2-networking-a-simple/variables.tf @@ -42,12 +42,19 @@ variable "alert_config" { variable "dns" { description = "DNS configuration." type = object({ - gcp_domain = optional(string, "gcp.example.com") - onprem_domain = optional(string, "onprem.example.com") - resolvers = optional(list(string), []) + gcp_domain = optional(string, "gcp.example.com") + onprem_domains = optional(list(object({ + domain = string + overwrite_resolver = optional(list(string), null) + })), []) + resolvers = optional(list(string), []) }) default = {} nullable = false + validation { + condition = length(var.dns.onprem_domains) > 0 == length(var.dns.resolvers) > 0 + error_message = "The 'resolvers' and 'onprem_domains' attributes must be used together. Please provide values for both or leave both empty." + } } variable "essential_contacts" { diff --git a/fast/stages/2-networking-b-nva/README.md b/fast/stages/2-networking-b-nva/README.md index 96a4e7b61..3f3431f6e 100644 --- a/fast/stages/2-networking-b-nva/README.md +++ b/fast/stages/2-networking-b-nva/README.md @@ -331,9 +331,11 @@ The spokes can optionally define private zones (e.g. `prod-dns-private-zone`). G #### Cloud to on-prem -Leveraging the forwarding zone defined in the landing project (e.g. `onprem-example-dns-forwarding` and `reverse-10-dns-forwarding`), the cloud environment can resolve `in-addr.arpa.` and `onprem.example.com.` using the on-premise DNS infrastructure. On-premise resolver IPs are set in the variable `dns.onprem`. +Leveraging the forwarding zones defined on Landing (e.g. `landing-dns-fwd-onprem` and `landing-dns-fwd-onprem-rev-10`), the cloud environment can resolve `in-addr.arpa.` and domains defined in `var.dns.onprem_domain` using the on-premises DNS infrastructure. Onprem resolvers IPs are set in variable `var.dns.resolvers`. -DNS queries sent to the on-premise infrastructure come from the `35.199.192.0/19` source range. +Domains defined in `var.dns.onprem_domain` can also optionally overwrite the resolver IPs + +DNS queries sent to the on-premises infrastructure come from the `35.199.192.0/19` source range, which is only accessible from within a VPC or networks connected to one. #### On-prem to cloud @@ -566,20 +568,20 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS | [prefix](variables-fast.tf#L76) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | 0-bootstrap | | [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | object({…}) | | {…} | | | [custom_roles](variables-fast.tf#L40) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | -| [dns](variables.tf#L42) | DNS configuration. | object({…}) | | {} | | -| [essential_contacts](variables.tf#L53) | Email used for essential contacts, unset if null. | string | | null | | -| [factories_config](variables.tf#L59) | Configuration for network resource factories. | object({…}) | | {} | | -| [gcp_ranges](variables.tf#L80) | GCP address ranges in name => range format. | map(string) | | {…} | | -| [network_mode](variables.tf#L97) | Selection of the network design to deploy. | string | | "simple" | | -| [outputs_location](variables.tf#L108) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | | -| [psa_ranges](variables.tf#L114) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | object({…}) | | {} | | -| [regions](variables.tf#L134) | Region definitions. | object({…}) | | {…} | | +| [dns](variables.tf#L42) | DNS configuration. | object({…}) | | {} | | +| [essential_contacts](variables.tf#L60) | Email used for essential contacts, unset if null. | string | | null | | +| [factories_config](variables.tf#L66) | Configuration for network resource factories. | object({…}) | | {} | | +| [gcp_ranges](variables.tf#L87) | GCP address ranges in name => range format. | map(string) | | {…} | | +| [network_mode](variables.tf#L104) | Selection of the network design to deploy. | string | | "simple" | | +| [outputs_location](variables.tf#L115) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | | +| [psa_ranges](variables.tf#L121) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | object({…}) | | {} | | +| [regions](variables.tf#L141) | Region definitions. | object({…}) | | {…} | | | [security_profile_groups](variables-fast.tf#L86) | Security profile group ids used for policy rule substitutions. | map(string) | | {} | 2-networking-ngfw | | [stage_configs](variables-fast.tf#L94) | FAST stage configuration. | object({…}) | | {} | 1-resman | | [tag_values](variables-fast.tf#L108) | Root-level tag values. | map(string) | | {} | 1-resman | -| [vpc_configs](variables.tf#L146) | Optional VPC network configurations. | object({…}) | | {} | | -| [vpn_onprem_primary_config](variables.tf#L229) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | | -| [vpn_onprem_secondary_config](variables.tf#L272) | VPN gateway configuration for onprem interconnection in the secondary region. | object({…}) | | null | | +| [vpc_configs](variables.tf#L153) | Optional VPC network configurations. | object({…}) | | {} | | +| [vpn_onprem_primary_config](variables.tf#L236) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | | +| [vpn_onprem_secondary_config](variables.tf#L279) | VPN gateway configuration for onprem interconnection in the secondary region. | object({…}) | | null | | ## Outputs diff --git a/fast/stages/2-networking-b-nva/dns-dev.tf b/fast/stages/2-networking-b-nva/dns-dev.tf index fad0b6229..0c4c469b8 100644 --- a/fast/stages/2-networking-b-nva/dns-dev.tf +++ b/fast/stages/2-networking-b-nva/dns-dev.tf @@ -20,6 +20,7 @@ module "dev-dns-priv-example" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.dev-spoke-project.project_id name = "dev-${replace(var.dns.gcp_domain, ".", "-")}" zone_config = { diff --git a/fast/stages/2-networking-b-nva/dns-landing.tf b/fast/stages/2-networking-b-nva/dns-landing.tf index 8faf25966..7907bded5 100644 --- a/fast/stages/2-networking-b-nva/dns-landing.tf +++ b/fast/stages/2-networking-b-nva/dns-landing.tf @@ -16,15 +16,19 @@ # tfdoc:file:description Landing DNS zones and peerings setup. +locals { + onprem_domain_map = { for i in var.dns.onprem_domains : i.domain => i } +} + # forwarding to on-prem DNS resolvers -module "landing-dns-fwd-onprem-example" { +module "landing-dns-fwd-onprem" { source = "../../../modules/dns" - count = length(var.dns.resolvers) > 0 ? 1 : 0 + for_each = local.onprem_domain_map project_id = module.landing-project.project_id - name = replace(var.dns.onprem_domain, ".", "-") + name = replace(each.key, ".", "-") zone_config = { - domain = "${var.dns.onprem_domain}." + domain = "${each.key}." forwarding = { client_networks = concat( [ @@ -37,7 +41,10 @@ module "landing-dns-fwd-onprem-example" { module.regional-secondary-vpc[0].self_link ] : [] ) - forwarders = { for ip in var.dns.resolvers : ip => null } + forwarders = (each.value.overwrite_resolver == null ? + { for ip in var.dns.resolvers : ip => null } + : { for ip in each.value.overwrite_resolver : ip => null } + ) } } } @@ -68,6 +75,7 @@ module "landing-dns-fwd-onprem-rev-10" { module "landing-dns-priv-gcp" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.landing-project.project_id name = replace(var.dns.gcp_domain, ".", "-") zone_config = { diff --git a/fast/stages/2-networking-b-nva/dns-prod.tf b/fast/stages/2-networking-b-nva/dns-prod.tf index 632f0adf0..f3758a8f1 100644 --- a/fast/stages/2-networking-b-nva/dns-prod.tf +++ b/fast/stages/2-networking-b-nva/dns-prod.tf @@ -20,6 +20,7 @@ module "prod-dns-priv-example" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.prod-spoke-project.project_id name = "prod-${replace(var.dns.gcp_domain, ".", "-")}" zone_config = { diff --git a/fast/stages/2-networking-b-nva/variables.tf b/fast/stages/2-networking-b-nva/variables.tf index a1150d5e4..774b25515 100644 --- a/fast/stages/2-networking-b-nva/variables.tf +++ b/fast/stages/2-networking-b-nva/variables.tf @@ -42,12 +42,19 @@ variable "alert_config" { variable "dns" { description = "DNS configuration." type = object({ - gcp_domain = optional(string, "gcp.example.com") - onprem_domain = optional(string, "onprem.example.com") - resolvers = optional(list(string), []) + gcp_domain = optional(string, "gcp.example.com") + onprem_domains = optional(list(object({ + domain = string + overwrite_resolver = optional(list(string), null) + })), []) + resolvers = optional(list(string), []) }) default = {} nullable = false + validation { + condition = length(var.dns.onprem_domains) > 0 == length(var.dns.resolvers) > 0 + error_message = "The 'resolvers' and 'onprem_domains' attributes must be used together. Please provide values for both or leave both empty." + } } variable "essential_contacts" { diff --git a/fast/stages/2-networking-c-separate-envs/README.md b/fast/stages/2-networking-c-separate-envs/README.md index 6832224f9..6d298efa3 100644 --- a/fast/stages/2-networking-c-separate-envs/README.md +++ b/fast/stages/2-networking-c-separate-envs/README.md @@ -364,18 +364,18 @@ Regions are defined via the `regions` variable which sets up a mapping between t | [prefix](variables-fast.tf#L76) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | 0-bootstrap | | [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | object({…}) | | {…} | | | [custom_roles](variables-fast.tf#L40) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | -| [dns](variables.tf#L42) | DNS configuration. | object({…}) | | {} | | -| [essential_contacts](variables.tf#L54) | Email used for essential contacts, unset if null. | string | | null | | -| [factories_config](variables.tf#L60) | Configuration for network resource factories. | object({…}) | | {} | | -| [outputs_location](variables.tf#L81) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | | -| [psa_ranges](variables.tf#L87) | IP ranges used for Private Service Access (e.g. CloudSQL). | object({…}) | | {} | | -| [regions](variables.tf#L107) | Region definitions. | object({…}) | | {…} | | +| [dns](variables.tf#L42) | DNS configuration. | object({…}) | | {} | | +| [essential_contacts](variables.tf#L75) | Email used for essential contacts, unset if null. | string | | null | | +| [factories_config](variables.tf#L81) | Configuration for network resource factories. | object({…}) | | {} | | +| [outputs_location](variables.tf#L102) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | | +| [psa_ranges](variables.tf#L108) | IP ranges used for Private Service Access (e.g. CloudSQL). | object({…}) | | {} | | +| [regions](variables.tf#L128) | Region definitions. | object({…}) | | {…} | | | [security_profile_groups](variables-fast.tf#L86) | Security profile group ids used for policy rule substitutions. | map(string) | | {} | 2-networking-ngfw | | [stage_configs](variables-fast.tf#L94) | FAST stage configuration. | object({…}) | | {} | 1-resman | | [tag_values](variables-fast.tf#L108) | Root-level tag values. | map(string) | | {} | 1-resman | -| [vpc_configs](variables.tf#L117) | Optional VPC network configurations. | object({…}) | | {} | | -| [vpn_onprem_dev_primary_config](variables.tf#L155) | VPN gateway configuration for onprem interconnection from dev in the primary region. | object({…}) | | null | | -| [vpn_onprem_prod_primary_config](variables.tf#L198) | VPN gateway configuration for onprem interconnection from prod in the primary region. | object({…}) | | null | | +| [vpc_configs](variables.tf#L138) | Optional VPC network configurations. | object({…}) | | {} | | +| [vpn_onprem_dev_primary_config](variables.tf#L176) | VPN gateway configuration for onprem interconnection from dev in the primary region. | object({…}) | | null | | +| [vpn_onprem_prod_primary_config](variables.tf#L219) | VPN gateway configuration for onprem interconnection from prod in the primary region. | object({…}) | | null | | ## Outputs diff --git a/fast/stages/2-networking-c-separate-envs/dns-dev.tf b/fast/stages/2-networking-c-separate-envs/dns-dev.tf index 90c3febf0..215868a5c 100644 --- a/fast/stages/2-networking-c-separate-envs/dns-dev.tf +++ b/fast/stages/2-networking-c-separate-envs/dns-dev.tf @@ -20,6 +20,7 @@ module "dev-dns-private-zone" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.dev-spoke-project.project_id name = "dev-${replace(var.dns.gcp_domain, ".", "-")}" zone_config = { @@ -33,16 +34,19 @@ module "dev-dns-private-zone" { } } -module "dev-dns-fwd-onprem-example" { +module "dev-dns-fwd-onprem" { source = "../../../modules/dns" - count = length(var.dns.dev_resolvers) > 0 ? 1 : 0 + for_each = local.onprem_domain_map project_id = module.dev-spoke-project.project_id - name = "example-com" + name = replace(each.key, ".", "-") zone_config = { - domain = "onprem.example.com." + domain = "${each.key}." forwarding = { client_networks = [module.dev-spoke-vpc.self_link] - forwarders = { for ip in var.dns.dev_resolvers : ip => null } + forwarders = (each.value.overwrite_resolver == null ? + { for ip in var.dns.dev_resolvers : ip => null } + : { for ip in each.value.overwrite_resolver : ip => null } + ) } } } diff --git a/fast/stages/2-networking-c-separate-envs/dns-prod.tf b/fast/stages/2-networking-c-separate-envs/dns-prod.tf index 53cb05a9f..f1b3c1656 100644 --- a/fast/stages/2-networking-c-separate-envs/dns-prod.tf +++ b/fast/stages/2-networking-c-separate-envs/dns-prod.tf @@ -20,6 +20,7 @@ module "prod-dns-private-zone" { source = "../../../modules/dns" + count = var.dns.gcp_domain != null ? 1 : 0 project_id = module.prod-spoke-project.project_id name = "prod-${replace(var.dns.gcp_domain, ".", "-")}" zone_config = { @@ -33,16 +34,19 @@ module "prod-dns-private-zone" { } } -module "prod-dns-fwd-onprem-example" { +module "prod-dns-fwd-onprem" { source = "../../../modules/dns" - count = length(var.dns.prod_resolvers) > 0 ? 1 : 0 + for_each = local.onprem_domain_map project_id = module.prod-spoke-project.project_id - name = "example-com" + name = replace(each.key, ".", "-") zone_config = { - domain = "onprem.example.com." + domain = "${each.key}." forwarding = { client_networks = [module.prod-spoke-vpc.self_link] - forwarders = { for ip in var.dns.prod_resolvers : ip => null } + forwarders = (each.value.overwrite_resolver == null ? + { for ip in var.dns.prod_resolvers : ip => null } + : { for ip in each.value.overwrite_resolver : ip => null } + ) } } } diff --git a/fast/stages/2-networking-c-separate-envs/main.tf b/fast/stages/2-networking-c-separate-envs/main.tf index 8861a798f..c197216a6 100644 --- a/fast/stages/2-networking-c-separate-envs/main.tf +++ b/fast/stages/2-networking-c-separate-envs/main.tf @@ -36,6 +36,7 @@ locals { iam_viewer = try( var.stage_configs["networking"].iam_viewer, {} ) + onprem_domain_map = { for i in var.dns.onprem_domains : i.domain => i } # combine all regions from variables and subnets regions = distinct(concat( values(var.regions), diff --git a/fast/stages/2-networking-c-separate-envs/variables.tf b/fast/stages/2-networking-c-separate-envs/variables.tf index ffe683a48..c51f6f750 100644 --- a/fast/stages/2-networking-c-separate-envs/variables.tf +++ b/fast/stages/2-networking-c-separate-envs/variables.tf @@ -42,13 +42,34 @@ variable "alert_config" { variable "dns" { description = "DNS configuration." type = object({ - gcp_domain = optional(string, "gcp.example.com") - onprem_domain = optional(string, "onprem.example.com") + gcp_domain = optional(string, "gcp.example.com") + onprem_domains = optional(list(object({ + domain = string + overwrite_resolver = optional(list(string), null) + })), []) dev_resolvers = optional(list(string), []) prod_resolvers = optional(list(string), []) }) default = {} nullable = false + validation { + condition = !contains( + [ + length(var.dns.onprem_domains) > 0, + length(var.dns.dev_resolvers) > 0, + length(var.dns.prod_resolvers) > 0 + ], + true + ) || !contains( + [ + length(var.dns.onprem_domains) > 0, + length(var.dns.dev_resolvers) > 0, + length(var.dns.prod_resolvers) > 0 + ], + false + ) + error_message = "The 'onprem_domains', 'dev_resolvers', and 'prod_resolvers' attributes must all be specified together. Please provide values for all three, or leave all three empty." + } } variable "essential_contacts" { diff --git a/tests/fast/stages/s2_networking_a_simple/ncc.tfvars b/tests/fast/stages/s2_networking_a_simple/ncc.tfvars index 4d8991703..8220fda7c 100644 --- a/tests/fast/stages/s2_networking_a_simple/ncc.tfvars +++ b/tests/fast/stages/s2_networking_a_simple/ncc.tfvars @@ -9,6 +9,9 @@ custom_roles = { service_project_network_admin = "organizations/123456789012/roles/foo" } dns = { + onprem_domains = [ + { domain = "onprem.example.com" } + ] resolvers = ["10.10.10.10"] } environments = { diff --git a/tests/fast/stages/s2_networking_a_simple/simple.tfvars b/tests/fast/stages/s2_networking_a_simple/simple.tfvars index 2ce954552..e8e0c2994 100644 --- a/tests/fast/stages/s2_networking_a_simple/simple.tfvars +++ b/tests/fast/stages/s2_networking_a_simple/simple.tfvars @@ -9,6 +9,9 @@ custom_roles = { service_project_network_admin = "organizations/123456789012/roles/foo" } dns = { + onprem_domains = [ + { domain = "onprem.example.com" } + ] resolvers = ["10.10.10.10"] } environments = { diff --git a/tests/fast/stages/s2_networking_a_simple/vpn.tfvars b/tests/fast/stages/s2_networking_a_simple/vpn.tfvars index 53f5430a0..e9c334c7d 100644 --- a/tests/fast/stages/s2_networking_a_simple/vpn.tfvars +++ b/tests/fast/stages/s2_networking_a_simple/vpn.tfvars @@ -9,6 +9,9 @@ custom_roles = { service_project_network_admin = "organizations/123456789012/roles/foo" } dns = { + onprem_domains = [ + { domain = "onprem.example.com" } + ] resolvers = ["10.10.10.10"] } environments = { diff --git a/tests/fast/stages/s2_networking_b_nva/ncc-ra.tfvars b/tests/fast/stages/s2_networking_b_nva/ncc-ra.tfvars index 7be895c46..8acf28f54 100644 --- a/tests/fast/stages/s2_networking_b_nva/ncc-ra.tfvars +++ b/tests/fast/stages/s2_networking_b_nva/ncc-ra.tfvars @@ -9,6 +9,9 @@ custom_roles = { service_project_network_admin = "organizations/123456789012/roles/foo" } dns = { + onprem_domains = [ + { domain = "onprem.example.com" } + ] resolvers = ["10.10.10.10"] } enable_test_instances = true diff --git a/tests/fast/stages/s2_networking_b_nva/regional.tfvars b/tests/fast/stages/s2_networking_b_nva/regional.tfvars index 47d9cc019..15fd3579b 100644 --- a/tests/fast/stages/s2_networking_b_nva/regional.tfvars +++ b/tests/fast/stages/s2_networking_b_nva/regional.tfvars @@ -9,6 +9,9 @@ custom_roles = { service_project_network_admin = "organizations/123456789012/roles/foo" } dns = { + onprem_domains = [ + { domain = "onprem.example.com" } + ] resolvers = ["10.10.10.10"] } enable_test_instances = true diff --git a/tests/fast/stages/s2_networking_b_nva/simple.tfvars b/tests/fast/stages/s2_networking_b_nva/simple.tfvars index 26fbffbf4..2ba962ac1 100644 --- a/tests/fast/stages/s2_networking_b_nva/simple.tfvars +++ b/tests/fast/stages/s2_networking_b_nva/simple.tfvars @@ -9,6 +9,9 @@ custom_roles = { service_project_network_admin = "organizations/123456789012/roles/foo" } dns = { + onprem_domains = [ + { domain = "onprem.example.com" } + ] resolvers = ["10.10.10.10"] } enable_test_instances = true diff --git a/tests/fast/stages/s2_networking_c_separate_envs/simple.tfvars b/tests/fast/stages/s2_networking_c_separate_envs/simple.tfvars index bd17d56a3..4cbd1d344 100644 --- a/tests/fast/stages/s2_networking_c_separate_envs/simple.tfvars +++ b/tests/fast/stages/s2_networking_c_separate_envs/simple.tfvars @@ -9,6 +9,9 @@ custom_roles = { service_project_network_admin = "organizations/123456789012/roles/foo" } dns = { + onprem_domains = [ + { domain = "onprem.example.com" } + ] dev_resolvers = ["10.10.10.10"] prod_resolvers = ["10.20.10.10"] }