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"]
}