diff --git a/fast/stages/2-networking-a-peering/README.md b/fast/stages/2-networking-a-peering/README.md
index f3c7c9511..2552691a8 100644
--- a/fast/stages/2-networking-a-peering/README.md
+++ b/fast/stages/2-networking-a-peering/README.md
@@ -130,13 +130,7 @@ DNS configuration is further centralized by leveraging peering zones, so that
- the hub/landing Cloud DNS hosts configurations for on-prem forwarding, Google API domains, and the top-level private zone/s (e.g. gcp.example.com)
- the spokes Cloud DNS host configurations for the environment-specific domains (e.g. prod.gcp.example.com), which are bound to the hub/landing leveraging [cross-project binding](https://cloud.google.com/dns/docs/zones/zones-overview#cross-project_binding); a peering zone for the `.` (root) zone is then created on each spoke, delegating all DNS resolution to hub/landing.
-- Private Google Access is enabled for a selection of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options), namely
- - `private.googleapis.com`
- - `restricted.googleapis.com`
- - `gcr.io`
- - `packages.cloud.google.com`
- - `pkg.dev`
- - `pki.goog`
+- Private Google Access is enabled via [DNS Response Policies](https://cloud.google.com/dns/docs/zones/manage-response-policies#create-response-policy-rule) for most of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options)
To complete the configuration, the 35.199.192.0/19 range should be routed on the VPN tunnels from on-prem, and the following names configured for DNS forwarding to cloud:
@@ -382,7 +376,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| name | description | modules | resources |
|---|---|---|---|
| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns | |
-| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns | |
+| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | |
@@ -403,18 +397,18 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap |
-| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
-| [organization](variables.tf#L85) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
-| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
+| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
+| [organization](variables.tf#L86) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
+| [prefix](variables.tf#L102) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | map(list(string)) | | {…} | |
-| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
-| [outputs_location](variables.tf#L95) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
+| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
+| [outputs_location](variables.tf#L96) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
| [peering_configs](variables-peerings.tf#L19) | Peering configurations. | map(object({…})) | | {…} | |
-| [psa_ranges](variables.tf#L112) | IP ranges used for Private Service Access (CloudSQL, etc.). | object({…}) | | null | |
-| [regions](variables.tf#L133) | Region definitions. | object({…}) | | {…} | |
-| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
-| [vpn_onprem_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
+| [psa_ranges](variables.tf#L113) | IP ranges used for Private Service Access (CloudSQL, etc.). | object({…}) | | null | |
+| [regions](variables.tf#L134) | Region definitions. | object({…}) | | {…} | |
+| [service_accounts](variables.tf#L146) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
+| [vpn_onprem_primary_config](variables.tf#L160) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
## Outputs
diff --git a/fast/stages/2-networking-a-peering/data/dns-policy-rules.yaml b/fast/stages/2-networking-a-peering/data/dns-policy-rules.yaml
new file mode 100644
index 000000000..d091e4f08
--- /dev/null
+++ b/fast/stages/2-networking-a-peering/data/dns-policy-rules.yaml
@@ -0,0 +1,110 @@
+# skip boilerplate check
+
+accounts:
+ dns_name: "accounts.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud:
+ dns_name: "backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud-all:
+ dns_name: "*.backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu:
+ dns_name: "backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu-all:
+ dns_name: "*.backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudfunctions:
+ dns_name: "*.cloudfunctions.net."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudproxy:
+ dns_name: "*.cloudproxy.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-cloud-all:
+ dns_name: "*.composer.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-gu-all:
+ dns_name: "*.composer.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-all:
+ dns_name: "*.datafusion.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-gu-all:
+ dns_name: "*.datafusion.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc:
+ dns_name: "dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-all:
+ dns_name: "*.dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu:
+ dns_name: "dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu-all:
+ dns_name: "*.dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dl:
+ dns_name: "dl.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr:
+ dns_name: "gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr-all:
+ dns_name: "*.gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-all:
+ dns_name: "*.googleapis.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-private:
+ dns_name: "private.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.8
+ - 199.36.153.9
+ - 199.36.153.10
+ - 199.36.153.11
+googleapis-restricted:
+ dns_name: "restricted.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.4
+ - 199.36.153.5
+ - 199.36.153.6
+ - 199.36.153.7
+gstatic-all:
+ dns_name: "*.gstatic.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-all:
+ dns_name: "*.notebooks.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-gu-all:
+ dns_name: "*.notebooks.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud:
+ dns_name: "packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud-all:
+ dns_name: "*.packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev:
+ dns_name: "pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev-all:
+ dns_name: "*.pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog:
+ dns_name: "pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog-all:
+ dns_name: "*.pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+run-all:
+ dns_name: "*.run.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+source:
+ dns_name: "source.developers.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
diff --git a/fast/stages/2-networking-a-peering/dns-dev.tf b/fast/stages/2-networking-a-peering/dns-dev.tf
index 03ae01221..efeabeaec 100644
--- a/fast/stages/2-networking-a-peering/dns-dev.tf
+++ b/fast/stages/2-networking-a-peering/dns-dev.tf
@@ -18,7 +18,12 @@
# GCP-specific environment zone
-module "dev-dns-private-zone" {
+moved {
+ from = module.dev-dns-private-zone
+ to = module.dev-dns-priv-example
+}
+
+module "dev-dns-priv-example" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "private"
@@ -32,7 +37,12 @@ module "dev-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "dev-landing-root-dns-peering" {
+moved {
+ from = module.dev-landing-root-dns-peering
+ to = module.dev-dns-peer-landing-root
+}
+
+module "dev-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
@@ -42,7 +52,12 @@ module "dev-landing-root-dns-peering" {
peer_network = module.landing-vpc.self_link
}
-module "dev-reverse-10-dns-peering" {
+moved {
+ from = module.dev-reverse-10-dns-peering
+ to = module.dev-dns-peer-landing-rev-10
+}
+
+module "dev-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-a-peering/dns-landing.tf b/fast/stages/2-networking-a-peering/dns-landing.tf
index 7b97a8cfd..e6a441a52 100644
--- a/fast/stages/2-networking-a-peering/dns-landing.tf
+++ b/fast/stages/2-networking-a-peering/dns-landing.tf
@@ -18,7 +18,12 @@
# forwarding to on-prem DNS resolvers
-module "onprem-example-dns-forwarding" {
+moved {
+ from = module.onprem-example-dns-forwarding
+ to = module.landing-dns-fwd-onprem-example
+}
+
+module "landing-dns-fwd-onprem-example" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -28,7 +33,12 @@ module "onprem-example-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "reverse-10-dns-forwarding" {
+moved {
+ from = module.reverse-10-dns-forwarding
+ to = module.landing-dns-fwd-onprem-rev-10
+}
+
+module "landing-dns-fwd-onprem-rev-10" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -38,7 +48,12 @@ module "reverse-10-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "gcp-example-dns-private-zone" {
+moved {
+ from = module.gcp-example-dns-private-zone
+ to = module.landing-dns-priv-gcp
+}
+
+module "landing-dns-priv-gcp" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "private"
@@ -50,82 +65,14 @@ module "gcp-example-dns-private-zone" {
}
}
-# Google APIs
+# Google APIs via response policies
-module "googleapis-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "googleapis-com"
- domain = "googleapis.com."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A private" = { records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "A restricted" = { records = [
- "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7"
- ] }
- "CNAME *" = { records = ["private.googleapis.com."] }
- }
-}
-
-module "gcrio-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "gcr-io"
- domain = "gcr.io."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A gcr.io." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "packages-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "packages-cloud"
- domain = "packages.cloud.google.com."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A packages.cloud.google.com." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkgdev-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pkg-dev"
- domain = "pkg.dev."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A pkg.dev." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkigoog-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pki-goog"
- domain = "pki.goog."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A pki.goog." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
+module "landing-dns-policy-googleapis" {
+ source = "../../../modules/dns-response-policy"
+ project_id = module.landing-project.project_id
+ name = "googleapis"
+ networks = {
+ landing = module.landing-vpc.self_link
}
+ rules_file = var.factories_config.dns_policy_rules_file
}
diff --git a/fast/stages/2-networking-a-peering/dns-prod.tf b/fast/stages/2-networking-a-peering/dns-prod.tf
index 5bb695fdc..02fa8c239 100644
--- a/fast/stages/2-networking-a-peering/dns-prod.tf
+++ b/fast/stages/2-networking-a-peering/dns-prod.tf
@@ -18,7 +18,12 @@
# GCP-specific environment zone
-module "prod-dns-private-zone" {
+moved {
+ from = module.prod-dns-private-zone
+ to = module.prod-dns-priv-example
+}
+
+module "prod-dns-priv-example" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "private"
@@ -32,7 +37,12 @@ module "prod-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "prod-landing-root-dns-peering" {
+moved {
+ from = module.prod-landing-root-dns-peering
+ to = module.prod-dns-peer-landing-root
+}
+
+module "prod-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
@@ -42,7 +52,12 @@ module "prod-landing-root-dns-peering" {
peer_network = module.landing-vpc.self_link
}
-module "prod-reverse-10-dns-peering" {
+moved {
+ from = module.prod-reverse-10-dns-peering
+ to = module.prod-dns-peer-landing-rev-10
+}
+
+module "prod-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-a-peering/variables.tf b/fast/stages/2-networking-a-peering/variables.tf
index 8c20b6237..c5f58cd4f 100644
--- a/fast/stages/2-networking-a-peering/variables.tf
+++ b/fast/stages/2-networking-a-peering/variables.tf
@@ -55,8 +55,9 @@ variable "dns" {
variable "factories_config" {
description = "Configuration for network resource factories."
type = object({
- data_dir = optional(string, "data")
- firewall_policy_name = optional(string, "factory")
+ data_dir = optional(string, "data")
+ dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml")
+ firewall_policy_name = optional(string, "factory")
})
default = {
data_dir = "data"
diff --git a/fast/stages/2-networking-b-vpn/README.md b/fast/stages/2-networking-b-vpn/README.md
index ab1b9734c..b5b87cefc 100644
--- a/fast/stages/2-networking-b-vpn/README.md
+++ b/fast/stages/2-networking-b-vpn/README.md
@@ -136,13 +136,7 @@ DNS configuration is further centralized by leveraging peering zones, so that
- the hub/landing Cloud DNS hosts configurations for on-prem forwarding, Google API domains, and the top-level private zone/s (e.g. gcp.example.com)
- the spokes Cloud DNS host configurations for the environment-specific domains (e.g. prod.gcp.example.com), which are bound to the hub/landing leveraging [cross-project binding](https://cloud.google.com/dns/docs/zones/zones-overview#cross-project_binding); a peering zone for the `.` (root) zone is then created on each spoke, delegating all DNS resolution to hub/landing.
-- Private Google Access is enabled for a selection of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options), namely
- - `private.googleapis.com`
- - `restricted.googleapis.com`
- - `gcr.io`
- - `packages.cloud.google.com`
- - `pkg.dev`
- - `pki.goog`
+- Private Google Access is enabled via [DNS Response Policies](https://cloud.google.com/dns/docs/zones/manage-response-policies#create-response-policy-rule) for most of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options)
To complete the configuration, the 35.199.192.0/19 range should be routed on the VPN tunnels from on-prem, and the following names configured for DNS forwarding to cloud:
@@ -405,7 +399,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| name | description | modules | resources |
|---|---|---|---|
| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns | |
-| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns | |
+| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | |
@@ -428,18 +422,18 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap |
-| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
-| [organization](variables.tf#L85) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
-| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
+| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
+| [organization](variables.tf#L86) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
+| [prefix](variables.tf#L102) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | map(list(string)) | | {…} | |
-| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
-| [outputs_location](variables.tf#L95) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
-| [psa_ranges](variables.tf#L112) | IP ranges used for Private Service Access (CloudSQL, etc.). | object({…}) | | null | |
-| [regions](variables.tf#L133) | Region definitions. | object({…}) | | {…} | |
-| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
+| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
+| [outputs_location](variables.tf#L96) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
+| [psa_ranges](variables.tf#L113) | IP ranges used for Private Service Access (CloudSQL, etc.). | object({…}) | | null | |
+| [regions](variables.tf#L134) | Region definitions. | object({…}) | | {…} | |
+| [service_accounts](variables.tf#L146) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
| [vpn_configs](variables-vpn.tf#L17) | Hub to spokes VPN configurations. | object({…}) | | {…} | |
-| [vpn_onprem_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
+| [vpn_onprem_primary_config](variables.tf#L160) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
## Outputs
diff --git a/fast/stages/2-networking-b-vpn/data/dns-policy-rules.yaml b/fast/stages/2-networking-b-vpn/data/dns-policy-rules.yaml
new file mode 100644
index 000000000..d091e4f08
--- /dev/null
+++ b/fast/stages/2-networking-b-vpn/data/dns-policy-rules.yaml
@@ -0,0 +1,110 @@
+# skip boilerplate check
+
+accounts:
+ dns_name: "accounts.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud:
+ dns_name: "backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud-all:
+ dns_name: "*.backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu:
+ dns_name: "backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu-all:
+ dns_name: "*.backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudfunctions:
+ dns_name: "*.cloudfunctions.net."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudproxy:
+ dns_name: "*.cloudproxy.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-cloud-all:
+ dns_name: "*.composer.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-gu-all:
+ dns_name: "*.composer.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-all:
+ dns_name: "*.datafusion.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-gu-all:
+ dns_name: "*.datafusion.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc:
+ dns_name: "dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-all:
+ dns_name: "*.dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu:
+ dns_name: "dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu-all:
+ dns_name: "*.dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dl:
+ dns_name: "dl.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr:
+ dns_name: "gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr-all:
+ dns_name: "*.gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-all:
+ dns_name: "*.googleapis.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-private:
+ dns_name: "private.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.8
+ - 199.36.153.9
+ - 199.36.153.10
+ - 199.36.153.11
+googleapis-restricted:
+ dns_name: "restricted.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.4
+ - 199.36.153.5
+ - 199.36.153.6
+ - 199.36.153.7
+gstatic-all:
+ dns_name: "*.gstatic.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-all:
+ dns_name: "*.notebooks.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-gu-all:
+ dns_name: "*.notebooks.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud:
+ dns_name: "packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud-all:
+ dns_name: "*.packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev:
+ dns_name: "pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev-all:
+ dns_name: "*.pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog:
+ dns_name: "pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog-all:
+ dns_name: "*.pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+run-all:
+ dns_name: "*.run.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+source:
+ dns_name: "source.developers.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
diff --git a/fast/stages/2-networking-b-vpn/dns-dev.tf b/fast/stages/2-networking-b-vpn/dns-dev.tf
index 03ae01221..efeabeaec 100644
--- a/fast/stages/2-networking-b-vpn/dns-dev.tf
+++ b/fast/stages/2-networking-b-vpn/dns-dev.tf
@@ -18,7 +18,12 @@
# GCP-specific environment zone
-module "dev-dns-private-zone" {
+moved {
+ from = module.dev-dns-private-zone
+ to = module.dev-dns-priv-example
+}
+
+module "dev-dns-priv-example" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "private"
@@ -32,7 +37,12 @@ module "dev-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "dev-landing-root-dns-peering" {
+moved {
+ from = module.dev-landing-root-dns-peering
+ to = module.dev-dns-peer-landing-root
+}
+
+module "dev-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
@@ -42,7 +52,12 @@ module "dev-landing-root-dns-peering" {
peer_network = module.landing-vpc.self_link
}
-module "dev-reverse-10-dns-peering" {
+moved {
+ from = module.dev-reverse-10-dns-peering
+ to = module.dev-dns-peer-landing-rev-10
+}
+
+module "dev-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-b-vpn/dns-landing.tf b/fast/stages/2-networking-b-vpn/dns-landing.tf
index 7b97a8cfd..e6a441a52 100644
--- a/fast/stages/2-networking-b-vpn/dns-landing.tf
+++ b/fast/stages/2-networking-b-vpn/dns-landing.tf
@@ -18,7 +18,12 @@
# forwarding to on-prem DNS resolvers
-module "onprem-example-dns-forwarding" {
+moved {
+ from = module.onprem-example-dns-forwarding
+ to = module.landing-dns-fwd-onprem-example
+}
+
+module "landing-dns-fwd-onprem-example" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -28,7 +33,12 @@ module "onprem-example-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "reverse-10-dns-forwarding" {
+moved {
+ from = module.reverse-10-dns-forwarding
+ to = module.landing-dns-fwd-onprem-rev-10
+}
+
+module "landing-dns-fwd-onprem-rev-10" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -38,7 +48,12 @@ module "reverse-10-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "gcp-example-dns-private-zone" {
+moved {
+ from = module.gcp-example-dns-private-zone
+ to = module.landing-dns-priv-gcp
+}
+
+module "landing-dns-priv-gcp" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "private"
@@ -50,82 +65,14 @@ module "gcp-example-dns-private-zone" {
}
}
-# Google APIs
+# Google APIs via response policies
-module "googleapis-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "googleapis-com"
- domain = "googleapis.com."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A private" = { records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "A restricted" = { records = [
- "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7"
- ] }
- "CNAME *" = { records = ["private.googleapis.com."] }
- }
-}
-
-module "gcrio-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "gcr-io"
- domain = "gcr.io."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A gcr.io." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "packages-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "packages-cloud"
- domain = "packages.cloud.google.com."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A packages.cloud.google.com." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkgdev-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pkg-dev"
- domain = "pkg.dev."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A pkg.dev." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkigoog-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pki-goog"
- domain = "pki.goog."
- client_networks = [module.landing-vpc.self_link]
- recordsets = {
- "A pki.goog." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
+module "landing-dns-policy-googleapis" {
+ source = "../../../modules/dns-response-policy"
+ project_id = module.landing-project.project_id
+ name = "googleapis"
+ networks = {
+ landing = module.landing-vpc.self_link
}
+ rules_file = var.factories_config.dns_policy_rules_file
}
diff --git a/fast/stages/2-networking-b-vpn/dns-prod.tf b/fast/stages/2-networking-b-vpn/dns-prod.tf
index 5bb695fdc..02fa8c239 100644
--- a/fast/stages/2-networking-b-vpn/dns-prod.tf
+++ b/fast/stages/2-networking-b-vpn/dns-prod.tf
@@ -18,7 +18,12 @@
# GCP-specific environment zone
-module "prod-dns-private-zone" {
+moved {
+ from = module.prod-dns-private-zone
+ to = module.prod-dns-priv-example
+}
+
+module "prod-dns-priv-example" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "private"
@@ -32,7 +37,12 @@ module "prod-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "prod-landing-root-dns-peering" {
+moved {
+ from = module.prod-landing-root-dns-peering
+ to = module.prod-dns-peer-landing-root
+}
+
+module "prod-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
@@ -42,7 +52,12 @@ module "prod-landing-root-dns-peering" {
peer_network = module.landing-vpc.self_link
}
-module "prod-reverse-10-dns-peering" {
+moved {
+ from = module.prod-reverse-10-dns-peering
+ to = module.prod-dns-peer-landing-rev-10
+}
+
+module "prod-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-b-vpn/variables.tf b/fast/stages/2-networking-b-vpn/variables.tf
index 8c20b6237..c5f58cd4f 100644
--- a/fast/stages/2-networking-b-vpn/variables.tf
+++ b/fast/stages/2-networking-b-vpn/variables.tf
@@ -55,8 +55,9 @@ variable "dns" {
variable "factories_config" {
description = "Configuration for network resource factories."
type = object({
- data_dir = optional(string, "data")
- firewall_policy_name = optional(string, "factory")
+ data_dir = optional(string, "data")
+ dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml")
+ firewall_policy_name = optional(string, "factory")
})
default = {
data_dir = "data"
diff --git a/fast/stages/2-networking-c-nva/README.md b/fast/stages/2-networking-c-nva/README.md
index 5aeefa29f..7ab05f567 100644
--- a/fast/stages/2-networking-c-nva/README.md
+++ b/fast/stages/2-networking-c-nva/README.md
@@ -210,13 +210,7 @@ DNS configuration is further centralized by leveraging peering zones, so that
- the hub/landing Cloud DNS hosts configurations for on-prem forwarding, Google API domains, and the top-level private zone/s (e.g. gcp.example.com)
- the spokes Cloud DNS host configurations for the environment-specific domains (e.g. prod.gcp.example.com), which are bound to the hub/landing leveraging [cross-project binding](https://cloud.google.com/dns/docs/zones/zones-overview#cross-project_binding); a peering zone for the `.` (root) zone is then created on each spoke, delegating all DNS resolution to hub/landing.
-- Private Google Access is enabled for a selection of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options), namely
- - `private.googleapis.com`
- - `restricted.googleapis.com`
- - `gcr.io`
- - `packages.cloud.google.com`
- - `pkg.dev`
- - `pki.goog`
+- Private Google Access is enabled via [DNS Response Policies](https://cloud.google.com/dns/docs/zones/manage-response-policies#create-response-policy-rule) for most of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options)
To complete the configuration, the 35.199.192.0/19 range should be routed to the VPN tunnels from on-premises, and the following names should be configured for DNS forwarding to cloud:
@@ -464,7 +458,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| name | description | modules | resources |
|---|---|---|---|
| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns | |
-| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns | |
+| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | |
@@ -484,20 +478,20 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap |
-| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
-| [organization](variables.tf#L108) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
-| [prefix](variables.tf#L124) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
+| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
+| [organization](variables.tf#L109) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
+| [prefix](variables.tf#L125) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | map(list(string)) | | {…} | |
-| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
-| [gcp_ranges](variables.tf#L85) | GCP address ranges in name => range format. | map(string) | | {…} | |
-| [onprem_cidr](variables.tf#L100) | Onprem addresses in name => range format. | map(string) | | {…} | |
-| [outputs_location](variables.tf#L118) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
-| [psa_ranges](variables.tf#L135) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | object({…}) | | null | |
-| [regions](variables.tf#L156) | Region definitions. | object({…}) | | {…} | |
-| [service_accounts](variables.tf#L168) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
-| [vpn_onprem_primary_config](variables.tf#L182) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
-| [vpn_onprem_secondary_config](variables.tf#L225) | VPN gateway configuration for onprem interconnection in the secondary region. | object({…}) | | null | |
+| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
+| [gcp_ranges](variables.tf#L86) | GCP address ranges in name => range format. | map(string) | | {…} | |
+| [onprem_cidr](variables.tf#L101) | Onprem addresses in name => range format. | map(string) | | {…} | |
+| [outputs_location](variables.tf#L119) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
+| [psa_ranges](variables.tf#L136) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | object({…}) | | null | |
+| [regions](variables.tf#L157) | Region definitions. | object({…}) | | {…} | |
+| [service_accounts](variables.tf#L169) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
+| [vpn_onprem_primary_config](variables.tf#L183) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
+| [vpn_onprem_secondary_config](variables.tf#L226) | VPN gateway configuration for onprem interconnection in the secondary region. | object({…}) | | null | |
## Outputs
diff --git a/fast/stages/2-networking-c-nva/data/dns-policy-rules.yaml b/fast/stages/2-networking-c-nva/data/dns-policy-rules.yaml
new file mode 100644
index 000000000..d091e4f08
--- /dev/null
+++ b/fast/stages/2-networking-c-nva/data/dns-policy-rules.yaml
@@ -0,0 +1,110 @@
+# skip boilerplate check
+
+accounts:
+ dns_name: "accounts.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud:
+ dns_name: "backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud-all:
+ dns_name: "*.backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu:
+ dns_name: "backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu-all:
+ dns_name: "*.backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudfunctions:
+ dns_name: "*.cloudfunctions.net."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudproxy:
+ dns_name: "*.cloudproxy.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-cloud-all:
+ dns_name: "*.composer.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-gu-all:
+ dns_name: "*.composer.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-all:
+ dns_name: "*.datafusion.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-gu-all:
+ dns_name: "*.datafusion.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc:
+ dns_name: "dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-all:
+ dns_name: "*.dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu:
+ dns_name: "dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu-all:
+ dns_name: "*.dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dl:
+ dns_name: "dl.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr:
+ dns_name: "gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr-all:
+ dns_name: "*.gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-all:
+ dns_name: "*.googleapis.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-private:
+ dns_name: "private.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.8
+ - 199.36.153.9
+ - 199.36.153.10
+ - 199.36.153.11
+googleapis-restricted:
+ dns_name: "restricted.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.4
+ - 199.36.153.5
+ - 199.36.153.6
+ - 199.36.153.7
+gstatic-all:
+ dns_name: "*.gstatic.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-all:
+ dns_name: "*.notebooks.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-gu-all:
+ dns_name: "*.notebooks.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud:
+ dns_name: "packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud-all:
+ dns_name: "*.packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev:
+ dns_name: "pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev-all:
+ dns_name: "*.pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog:
+ dns_name: "pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog-all:
+ dns_name: "*.pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+run-all:
+ dns_name: "*.run.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+source:
+ dns_name: "source.developers.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
diff --git a/fast/stages/2-networking-c-nva/dns-dev.tf b/fast/stages/2-networking-c-nva/dns-dev.tf
index 4eb472a15..98d56aa72 100644
--- a/fast/stages/2-networking-c-nva/dns-dev.tf
+++ b/fast/stages/2-networking-c-nva/dns-dev.tf
@@ -32,7 +32,12 @@ module "dev-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "dev-landing-root-dns-peering" {
+moved {
+ from = module.dev-landing-root-dns-peering
+ to = module.dev-dns-peer-landing-root
+}
+
+module "dev-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
@@ -42,7 +47,12 @@ module "dev-landing-root-dns-peering" {
peer_network = module.landing-trusted-vpc.self_link
}
-module "dev-reverse-10-dns-peering" {
+moved {
+ from = module.dev-reverse-10-dns-peering
+ to = module.dev-dns-peer-landing-rev-10
+}
+
+module "dev-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-c-nva/dns-landing.tf b/fast/stages/2-networking-c-nva/dns-landing.tf
index 40090279f..50b658901 100644
--- a/fast/stages/2-networking-c-nva/dns-landing.tf
+++ b/fast/stages/2-networking-c-nva/dns-landing.tf
@@ -18,7 +18,12 @@
# forwarding to on-prem DNS resolvers
-module "onprem-example-dns-forwarding" {
+moved {
+ from = module.onprem-example-dns-forwarding
+ to = module.landing-dns-fwd-onprem-example
+}
+
+module "landing-dns-fwd-onprem-example" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -31,7 +36,12 @@ module "onprem-example-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "reverse-10-dns-forwarding" {
+moved {
+ from = module.reverse-10-dns-forwarding
+ to = module.landing-dns-fwd-onprem-rev-10
+}
+
+module "landing-dns-fwd-onprem-rev-10" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -44,7 +54,12 @@ module "reverse-10-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "gcp-example-dns-private-zone" {
+moved {
+ from = module.gcp-example-dns-private-zone
+ to = module.landing-dns-priv-gcp
+}
+
+module "landing-dns-priv-gcp" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "private"
@@ -61,95 +76,13 @@ module "gcp-example-dns-private-zone" {
# Google APIs
-module "googleapis-private-zone" {
- source = "../../../modules/dns"
+module "landing-dns-policy-googleapis" {
+ source = "../../../modules/dns-response-policy"
project_id = module.landing-project.project_id
- type = "private"
- name = "googleapis-com"
- domain = "googleapis.com."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A private" = { records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "A restricted" = { records = [
- "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7"
- ] }
- "CNAME *" = { records = ["private.googleapis.com."] }
- }
-}
-
-module "gcrio-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "gcr-io"
- domain = "gcr.io."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A gcr.io." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "packages-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "packages-cloud"
- domain = "packages.cloud.google.com."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A packages.cloud.google.com." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkgdev-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pkg-dev"
- domain = "pkg.dev."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A pkg.dev." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkigoog-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pki-goog"
- domain = "pki.goog."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A pki.goog." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
+ name = "googleapis"
+ networks = {
+ landing-trusted = module.landing-trusted-vpc.self_link
+ landing-untrusted = module.landing-untrusted-vpc.self_link
}
+ rules_file = var.factories_config.dns_policy_rules_file
}
diff --git a/fast/stages/2-networking-c-nva/dns-prod.tf b/fast/stages/2-networking-c-nva/dns-prod.tf
index b54609dfd..5627e4386 100644
--- a/fast/stages/2-networking-c-nva/dns-prod.tf
+++ b/fast/stages/2-networking-c-nva/dns-prod.tf
@@ -32,7 +32,12 @@ module "prod-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "prod-landing-root-dns-peering" {
+moved {
+ from = module.prod-landing-root-dns-peering
+ to = module.prod-dns-peer-landing-root
+}
+
+module "prod-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
@@ -42,7 +47,12 @@ module "prod-landing-root-dns-peering" {
peer_network = module.landing-trusted-vpc.self_link
}
-module "prod-reverse-10-dns-peering" {
+moved {
+ from = module.prod-reverse-10-dns-peering
+ to = module.prod-dns-peer-landing-rev-10
+}
+
+module "prod-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-c-nva/variables.tf b/fast/stages/2-networking-c-nva/variables.tf
index e4fe6896a..b56c72d81 100644
--- a/fast/stages/2-networking-c-nva/variables.tf
+++ b/fast/stages/2-networking-c-nva/variables.tf
@@ -55,8 +55,9 @@ variable "dns" {
variable "factories_config" {
description = "Configuration for network resource factories."
type = object({
- data_dir = optional(string, "data")
- firewall_policy_name = optional(string, "factory")
+ data_dir = optional(string, "data")
+ dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml")
+ firewall_policy_name = optional(string, "factory")
})
default = {
data_dir = "data"
diff --git a/fast/stages/2-networking-d-separate-envs/README.md b/fast/stages/2-networking-d-separate-envs/README.md
index a718cda8a..3929db7ee 100644
--- a/fast/stages/2-networking-d-separate-envs/README.md
+++ b/fast/stages/2-networking-d-separate-envs/README.md
@@ -95,13 +95,7 @@ DNS often goes hand in hand with networking, especially on GCP where Cloud DNS z
- on-prem to cloud via private zones for cloud-managed domains, and an [inbound policy](https://cloud.google.com/dns/docs/server-policies-overview#dns-server-policy-in) used as forwarding target or via delegation (requires some extra configuration) from on-prem DNS resolvers
- cloud to on-prem via forwarding zones for the on-prem managed domains
-- Private Google Access is enabled for a selection of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options), namely
- - `private.googleapis.com`
- - `restricted.googleapis.com`
- - `gcr.io`
- - `packages.cloud.google.com`
- - `pkg.dev`
- - `pki.goog`
+- Private Google Access is enabled via [DNS Response Policies](https://cloud.google.com/dns/docs/zones/manage-response-policies#create-response-policy-rule) for most of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options)
To complete the configuration, the 35.199.192.0/19 range should be routed on the VPN tunnels from on-prem, and the following names configured for DNS forwarding to cloud:
@@ -328,8 +322,8 @@ Regions are defined via the `regions` variable which sets up a mapping between t
| name | description | modules | resources |
|---|---|---|---|
-| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns | |
-| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | |
+| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns · dns-response-policy | |
+| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns · dns-response-policy | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | |
| [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard |
| [outputs.tf](./outputs.tf) | Module outputs. | | google_storage_bucket_object · local_file |
@@ -346,18 +340,18 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap |
-| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
-| [organization](variables.tf#L86) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
-| [prefix](variables.tf#L102) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
+| [folder_ids](variables.tf#L77) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
+| [organization](variables.tf#L87) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
+| [prefix](variables.tf#L103) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | map(list(string)) | | {…} | |
-| [factories_config](variables.tf#L56) | Configuration for network resource factories. | object({…}) | | {…} | |
-| [outputs_location](variables.tf#L96) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
-| [psa_ranges](variables.tf#L113) | IP ranges used for Private Service Access (e.g. CloudSQL). | object({…}) | | null | |
-| [regions](variables.tf#L134) | Region definitions. | object({…}) | | {…} | |
-| [service_accounts](variables.tf#L144) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
-| [vpn_onprem_dev_primary_config](variables.tf#L158) | VPN gateway configuration for onprem interconnection from dev in the primary region. | object({…}) | | null | |
-| [vpn_onprem_prod_primary_config](variables.tf#L201) | VPN gateway configuration for onprem interconnection from prod in the primary region. | object({…}) | | null | |
+| [factories_config](variables.tf#L56) | Configuration for network resource factories. | object({…}) | | {…} | |
+| [outputs_location](variables.tf#L97) | 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). | object({…}) | | null | |
+| [regions](variables.tf#L135) | Region definitions. | object({…}) | | {…} | |
+| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
+| [vpn_onprem_dev_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection from dev in the primary region. | object({…}) | | null | |
+| [vpn_onprem_prod_primary_config](variables.tf#L202) | VPN gateway configuration for onprem interconnection from prod in the primary region. | object({…}) | | null | |
## Outputs
diff --git a/fast/stages/2-networking-d-separate-envs/data/dns-policy-rules.yaml b/fast/stages/2-networking-d-separate-envs/data/dns-policy-rules.yaml
new file mode 100644
index 000000000..d091e4f08
--- /dev/null
+++ b/fast/stages/2-networking-d-separate-envs/data/dns-policy-rules.yaml
@@ -0,0 +1,110 @@
+# skip boilerplate check
+
+accounts:
+ dns_name: "accounts.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud:
+ dns_name: "backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud-all:
+ dns_name: "*.backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu:
+ dns_name: "backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu-all:
+ dns_name: "*.backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudfunctions:
+ dns_name: "*.cloudfunctions.net."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudproxy:
+ dns_name: "*.cloudproxy.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-cloud-all:
+ dns_name: "*.composer.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-gu-all:
+ dns_name: "*.composer.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-all:
+ dns_name: "*.datafusion.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-gu-all:
+ dns_name: "*.datafusion.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc:
+ dns_name: "dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-all:
+ dns_name: "*.dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu:
+ dns_name: "dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu-all:
+ dns_name: "*.dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dl:
+ dns_name: "dl.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr:
+ dns_name: "gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr-all:
+ dns_name: "*.gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-all:
+ dns_name: "*.googleapis.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-private:
+ dns_name: "private.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.8
+ - 199.36.153.9
+ - 199.36.153.10
+ - 199.36.153.11
+googleapis-restricted:
+ dns_name: "restricted.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.4
+ - 199.36.153.5
+ - 199.36.153.6
+ - 199.36.153.7
+gstatic-all:
+ dns_name: "*.gstatic.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-all:
+ dns_name: "*.notebooks.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-gu-all:
+ dns_name: "*.notebooks.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud:
+ dns_name: "packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud-all:
+ dns_name: "*.packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev:
+ dns_name: "pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev-all:
+ dns_name: "*.pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog:
+ dns_name: "pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog-all:
+ dns_name: "*.pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+run-all:
+ dns_name: "*.run.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+source:
+ dns_name: "source.developers.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
diff --git a/fast/stages/2-networking-d-separate-envs/dns-dev.tf b/fast/stages/2-networking-d-separate-envs/dns-dev.tf
index 25adab5e2..134b69cff 100644
--- a/fast/stages/2-networking-d-separate-envs/dns-dev.tf
+++ b/fast/stages/2-networking-d-separate-envs/dns-dev.tf
@@ -30,7 +30,12 @@ module "dev-dns-private-zone" {
}
}
-module "dev-onprem-example-dns-forwarding" {
+moved {
+ from = module.dev-onprem-example-dns-forwarding
+ to = module.dev-dns-fwd-onprem-example
+}
+
+module "dev-dns-fwd-onprem-example" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "forwarding"
@@ -40,7 +45,12 @@ module "dev-onprem-example-dns-forwarding" {
forwarders = { for ip in var.dns.dev : ip => null }
}
-module "dev-reverse-10-dns-forwarding" {
+moved {
+ from = module.dev-reverse-10-dns-forwarding
+ to = module.dev-dns-fwd-onprem-rev-10
+}
+
+module "dev-dns-fwd-onprem-rev-10" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "forwarding"
@@ -52,80 +62,12 @@ module "dev-reverse-10-dns-forwarding" {
# Google APIs
-module "dev-googleapis-private-zone" {
- source = "../../../modules/dns"
- project_id = module.dev-spoke-project.project_id
- type = "private"
- name = "googleapis-com"
- domain = "googleapis.com."
- client_networks = [module.dev-spoke-vpc.self_link]
- recordsets = {
- "A private" = { records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "A restricted" = { records = [
- "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7"
- ] }
- "CNAME *" = { records = ["private.googleapis.com."] }
- }
-}
-
-module "dev-gcrio-private-zone" {
- source = "../../../modules/dns"
- project_id = module.dev-spoke-project.project_id
- type = "private"
- name = "gcr-io"
- domain = "gcr.io."
- client_networks = [module.dev-spoke-vpc.self_link]
- recordsets = {
- "A gcr.io." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "dev-packages-private-zone" {
- source = "../../../modules/dns"
- project_id = module.dev-spoke-project.project_id
- type = "private"
- name = "packages-cloud"
- domain = "packages.cloud.google.com."
- client_networks = [module.dev-spoke-vpc.self_link]
- recordsets = {
- "A packages.cloud.google.com." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "dev-pkgdev-private-zone" {
- source = "../../../modules/dns"
- project_id = module.dev-spoke-project.project_id
- type = "private"
- name = "pkg-dev"
- domain = "pkg.dev."
- client_networks = [module.dev-spoke-vpc.self_link]
- recordsets = {
- "A pkg.dev." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "dev-pkigoog-private-zone" {
- source = "../../../modules/dns"
- project_id = module.dev-spoke-project.project_id
- type = "private"
- name = "pki-goog"
- domain = "pki.goog."
- client_networks = [module.dev-spoke-vpc.self_link]
- recordsets = {
- "A pki.goog." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
+module "dev-dns-policy-googleapis" {
+ source = "../../../modules/dns-response-policy"
+ project_id = module.dev-spoke-project.project_id
+ name = "googleapis"
+ networks = {
+ dev = module.dev-spoke-vpc.self_link
}
+ rules_file = var.factories_config.dns_policy_rules_file
}
diff --git a/fast/stages/2-networking-d-separate-envs/dns-prod.tf b/fast/stages/2-networking-d-separate-envs/dns-prod.tf
index 47c8cdca4..351db57f0 100644
--- a/fast/stages/2-networking-d-separate-envs/dns-prod.tf
+++ b/fast/stages/2-networking-d-separate-envs/dns-prod.tf
@@ -30,7 +30,12 @@ module "prod-dns-private-zone" {
}
}
-module "prod-onprem-example-dns-forwarding" {
+moved {
+ from = module.prod-onprem-example-dns-forwarding
+ to = module.prod-dns-fwd-onprem-example
+}
+
+module "prod-dns-fwd-onprem-example" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "forwarding"
@@ -40,7 +45,12 @@ module "prod-onprem-example-dns-forwarding" {
forwarders = { for ip in var.dns.prod : ip => null }
}
-module "prod-reverse-10-dns-forwarding" {
+moved {
+ from = module.prod-reverse-10-dns-forwarding
+ to = module.prod-dns-fwd-onprem-rev-10
+}
+
+module "prod-dns-fwd-onprem-rev-10" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "forwarding"
@@ -52,80 +62,12 @@ module "prod-reverse-10-dns-forwarding" {
# Google APIs
-module "prod-googleapis-private-zone" {
- source = "../../../modules/dns"
- project_id = module.prod-spoke-project.project_id
- type = "private"
- name = "googleapis-com"
- domain = "googleapis.com."
- client_networks = [module.prod-spoke-vpc.self_link]
- recordsets = {
- "A private" = { records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "A restricted" = { records = [
- "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7"
- ] }
- "CNAME *" = { records = ["private.googleapis.com."] }
- }
-}
-
-module "prod-gcrio-private-zone" {
- source = "../../../modules/dns"
- project_id = module.prod-spoke-project.project_id
- type = "private"
- name = "gcr-io"
- domain = "gcr.io."
- client_networks = [module.prod-spoke-vpc.self_link]
- recordsets = {
- "A gcr.io." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "prod-packages-private-zone" {
- source = "../../../modules/dns"
- project_id = module.prod-spoke-project.project_id
- type = "private"
- name = "packages-cloud"
- domain = "packages.cloud.google.com."
- client_networks = [module.prod-spoke-vpc.self_link]
- recordsets = {
- "A packages.cloud.google.com." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "prod-pkgdev-private-zone" {
- source = "../../../modules/dns"
- project_id = module.prod-spoke-project.project_id
- type = "private"
- name = "pkg-dev"
- domain = "pkg.dev."
- client_networks = [module.prod-spoke-vpc.self_link]
- recordsets = {
- "A pkg.dev." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "prod-pkigoog-private-zone" {
- source = "../../../modules/dns"
- project_id = module.prod-spoke-project.project_id
- type = "private"
- name = "pki-goog"
- domain = "pki.goog."
- client_networks = [module.prod-spoke-vpc.self_link]
- recordsets = {
- "A pki.goog." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
+module "prod-dns-policy-googleapis" {
+ source = "../../../modules/dns-response-policy"
+ project_id = module.prod-spoke-project.project_id
+ name = "googleapis"
+ networks = {
+ prod = module.prod-spoke-vpc.self_link
}
+ rules_file = var.factories_config.dns_policy_rules_file
}
diff --git a/fast/stages/2-networking-d-separate-envs/variables.tf b/fast/stages/2-networking-d-separate-envs/variables.tf
index a8920c533..5ea75c521 100644
--- a/fast/stages/2-networking-d-separate-envs/variables.tf
+++ b/fast/stages/2-networking-d-separate-envs/variables.tf
@@ -56,8 +56,9 @@ variable "dns" {
variable "factories_config" {
description = "Configuration for network resource factories."
type = object({
- data_dir = optional(string, "data")
- firewall_policy_name = optional(string, "factory")
+ data_dir = optional(string, "data")
+ dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml")
+ firewall_policy_name = optional(string, "factory")
})
default = {
data_dir = "data"
diff --git a/fast/stages/2-networking-e-nva-bgp/README.md b/fast/stages/2-networking-e-nva-bgp/README.md
index ea1e2ec56..4fee97354 100644
--- a/fast/stages/2-networking-e-nva-bgp/README.md
+++ b/fast/stages/2-networking-e-nva-bgp/README.md
@@ -230,13 +230,7 @@ DNS configuration is further centralized by leveraging peering zones, so that
- the hub/landing Cloud DNS hosts configurations for on-prem forwarding, Google API domains, and the top-level private zone/s (e.g. gcp.example.com)
- the spokes Cloud DNS host configurations for the environment-specific domains (e.g. prod.gcp.example.com), which are bound to the hub/landing leveraging [cross-project binding](https://cloud.google.com/dns/docs/zones/zones-overview#cross-project_binding); a peering zone for the `.` (root) zone is then created on each spoke, delegating all DNS resolution to hub/landing.
-- Private Google Access is enabled for a selection of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options), namely
- - `private.googleapis.com`
- - `restricted.googleapis.com`
- - `gcr.io`
- - `packages.cloud.google.com`
- - `pkg.dev`
- - `pki.goog`
+- Private Google Access is enabled via [DNS Response Policies](https://cloud.google.com/dns/docs/zones/manage-response-policies#create-response-policy-rule) for most of the [supported domains](https://cloud.google.com/vpc/docs/configure-private-google-access#domain-options)
To complete the configuration, the 35.199.192.0/19 range should be routed to the VPN tunnels from on-premises, and the following names should be configured for DNS forwarding to cloud:
@@ -488,7 +482,7 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
| name | description | modules | resources |
|---|---|---|---|
| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns | |
-| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns | |
+| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | dns · dns-response-policy | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | |
@@ -509,22 +503,22 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap |
-| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
-| [organization](variables.tf#L119) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
-| [prefix](variables.tf#L135) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
+| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 1-resman |
+| [organization](variables.tf#L120) | Organization details. | object({…}) | ✓ | | 0-bootstrap |
+| [prefix](variables.tf#L136) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | map(list(string)) | | {…} | |
-| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
-| [gcp_ranges](variables.tf#L85) | GCP address ranges in name => range format. | map(string) | | {…} | |
-| [ncc_asn](variables.tf#L100) | The NCC Cloud Routers ASN configuration. | map(number) | | {…} | |
-| [onprem_cidr](variables.tf#L111) | Onprem addresses in name => range format. | map(string) | | {…} | |
-| [outputs_location](variables.tf#L129) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
-| [psa_ranges](variables.tf#L146) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | object({…}) | | null | |
-| [regions](variables.tf#L167) | Region definitions. | object({…}) | | {…} | |
-| [service_accounts](variables.tf#L179) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
-| [vpn_onprem_primary_config](variables.tf#L193) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
-| [vpn_onprem_secondary_config](variables.tf#L236) | VPN gateway configuration for onprem interconnection in the secondary region. | object({…}) | | null | |
-| [zones](variables.tf#L279) | Zones in which NVAs are deployed. | list(string) | | ["b", "c"] | |
+| [factories_config](variables.tf#L55) | Configuration for network resource factories. | object({…}) | | {…} | |
+| [gcp_ranges](variables.tf#L86) | GCP address ranges in name => range format. | map(string) | | {…} | |
+| [ncc_asn](variables.tf#L101) | The NCC Cloud Routers ASN configuration. | map(number) | | {…} | |
+| [onprem_cidr](variables.tf#L112) | Onprem addresses in name => range format. | map(string) | | {…} | |
+| [outputs_location](variables.tf#L130) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | |
+| [psa_ranges](variables.tf#L147) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | object({…}) | | null | |
+| [regions](variables.tf#L168) | Region definitions. | object({…}) | | {…} | |
+| [service_accounts](variables.tf#L180) | Automation service accounts in name => email format. | object({…}) | | null | 1-resman |
+| [vpn_onprem_primary_config](variables.tf#L194) | VPN gateway configuration for onprem interconnection in the primary region. | object({…}) | | null | |
+| [vpn_onprem_secondary_config](variables.tf#L237) | VPN gateway configuration for onprem interconnection in the secondary region. | object({…}) | | null | |
+| [zones](variables.tf#L280) | Zones in which NVAs are deployed. | list(string) | | ["b", "c"] | |
## Outputs
diff --git a/fast/stages/2-networking-e-nva-bgp/data/dns-policy-rules.yaml b/fast/stages/2-networking-e-nva-bgp/data/dns-policy-rules.yaml
new file mode 100644
index 000000000..d091e4f08
--- /dev/null
+++ b/fast/stages/2-networking-e-nva-bgp/data/dns-policy-rules.yaml
@@ -0,0 +1,110 @@
+# skip boilerplate check
+
+accounts:
+ dns_name: "accounts.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud:
+ dns_name: "backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-cloud-all:
+ dns_name: "*.backupdr.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu:
+ dns_name: "backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+backupdr-gu-all:
+ dns_name: "*.backupdr.googleusercontent.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudfunctions:
+ dns_name: "*.cloudfunctions.net."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+cloudproxy:
+ dns_name: "*.cloudproxy.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-cloud-all:
+ dns_name: "*.composer.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+composer-gu-all:
+ dns_name: "*.composer.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-all:
+ dns_name: "*.datafusion.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+datafusion-gu-all:
+ dns_name: "*.datafusion.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc:
+ dns_name: "dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-all:
+ dns_name: "*.dataproc.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu:
+ dns_name: "dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dataproc-gu-all:
+ dns_name: "*.dataproc.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+dl:
+ dns_name: "dl.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr:
+ dns_name: "gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+gcr-all:
+ dns_name: "*.gcr.io."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-all:
+ dns_name: "*.googleapis.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+googleapis-private:
+ dns_name: "private.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.8
+ - 199.36.153.9
+ - 199.36.153.10
+ - 199.36.153.11
+googleapis-restricted:
+ dns_name: "restricted.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.4
+ - 199.36.153.5
+ - 199.36.153.6
+ - 199.36.153.7
+gstatic-all:
+ dns_name: "*.gstatic.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-all:
+ dns_name: "*.notebooks.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+notebooks-gu-all:
+ dns_name: "*.notebooks.googleusercontent.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud:
+ dns_name: "packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+packages-cloud-all:
+ dns_name: "*.packages.cloud.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev:
+ dns_name: "pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkgdev-all:
+ dns_name: "*.pkg.dev."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog:
+ dns_name: "pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+pkigoog-all:
+ dns_name: "*.pki.goog."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+run-all:
+ dns_name: "*.run.app."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
+source:
+ dns_name: "source.developers.google.com."
+ local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
diff --git a/fast/stages/2-networking-e-nva-bgp/dns-dev.tf b/fast/stages/2-networking-e-nva-bgp/dns-dev.tf
index 4eb472a15..98d56aa72 100644
--- a/fast/stages/2-networking-e-nva-bgp/dns-dev.tf
+++ b/fast/stages/2-networking-e-nva-bgp/dns-dev.tf
@@ -32,7 +32,12 @@ module "dev-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "dev-landing-root-dns-peering" {
+moved {
+ from = module.dev-landing-root-dns-peering
+ to = module.dev-dns-peer-landing-root
+}
+
+module "dev-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
@@ -42,7 +47,12 @@ module "dev-landing-root-dns-peering" {
peer_network = module.landing-trusted-vpc.self_link
}
-module "dev-reverse-10-dns-peering" {
+moved {
+ from = module.dev-reverse-10-dns-peering
+ to = module.dev-dns-peer-landing-rev-10
+}
+
+module "dev-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.dev-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-e-nva-bgp/dns-landing.tf b/fast/stages/2-networking-e-nva-bgp/dns-landing.tf
index 40090279f..50b658901 100644
--- a/fast/stages/2-networking-e-nva-bgp/dns-landing.tf
+++ b/fast/stages/2-networking-e-nva-bgp/dns-landing.tf
@@ -18,7 +18,12 @@
# forwarding to on-prem DNS resolvers
-module "onprem-example-dns-forwarding" {
+moved {
+ from = module.onprem-example-dns-forwarding
+ to = module.landing-dns-fwd-onprem-example
+}
+
+module "landing-dns-fwd-onprem-example" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -31,7 +36,12 @@ module "onprem-example-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "reverse-10-dns-forwarding" {
+moved {
+ from = module.reverse-10-dns-forwarding
+ to = module.landing-dns-fwd-onprem-rev-10
+}
+
+module "landing-dns-fwd-onprem-rev-10" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "forwarding"
@@ -44,7 +54,12 @@ module "reverse-10-dns-forwarding" {
forwarders = { for ip in var.dns.onprem : ip => null }
}
-module "gcp-example-dns-private-zone" {
+moved {
+ from = module.gcp-example-dns-private-zone
+ to = module.landing-dns-priv-gcp
+}
+
+module "landing-dns-priv-gcp" {
source = "../../../modules/dns"
project_id = module.landing-project.project_id
type = "private"
@@ -61,95 +76,13 @@ module "gcp-example-dns-private-zone" {
# Google APIs
-module "googleapis-private-zone" {
- source = "../../../modules/dns"
+module "landing-dns-policy-googleapis" {
+ source = "../../../modules/dns-response-policy"
project_id = module.landing-project.project_id
- type = "private"
- name = "googleapis-com"
- domain = "googleapis.com."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A private" = { records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "A restricted" = { records = [
- "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7"
- ] }
- "CNAME *" = { records = ["private.googleapis.com."] }
- }
-}
-
-module "gcrio-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "gcr-io"
- domain = "gcr.io."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A gcr.io." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "packages-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "packages-cloud"
- domain = "packages.cloud.google.com."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A packages.cloud.google.com." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkgdev-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pkg-dev"
- domain = "pkg.dev."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A pkg.dev." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
- }
-}
-
-module "pkigoog-private-zone" {
- source = "../../../modules/dns"
- project_id = module.landing-project.project_id
- type = "private"
- name = "pki-goog"
- domain = "pki.goog."
- client_networks = [
- module.landing-untrusted-vpc.self_link,
- module.landing-trusted-vpc.self_link
- ]
- recordsets = {
- "A pki.goog." = { ttl = 300, records = [
- "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11"
- ] }
- "CNAME *" = { ttl = 300, records = ["private.googleapis.com."] }
+ name = "googleapis"
+ networks = {
+ landing-trusted = module.landing-trusted-vpc.self_link
+ landing-untrusted = module.landing-untrusted-vpc.self_link
}
+ rules_file = var.factories_config.dns_policy_rules_file
}
diff --git a/fast/stages/2-networking-e-nva-bgp/dns-prod.tf b/fast/stages/2-networking-e-nva-bgp/dns-prod.tf
index b54609dfd..5627e4386 100644
--- a/fast/stages/2-networking-e-nva-bgp/dns-prod.tf
+++ b/fast/stages/2-networking-e-nva-bgp/dns-prod.tf
@@ -32,7 +32,12 @@ module "prod-dns-private-zone" {
# root zone peering to landing to centralize configuration; remove if unneeded
-module "prod-landing-root-dns-peering" {
+moved {
+ from = module.prod-landing-root-dns-peering
+ to = module.prod-dns-peer-landing-root
+}
+
+module "prod-dns-peer-landing-root" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
@@ -42,7 +47,12 @@ module "prod-landing-root-dns-peering" {
peer_network = module.landing-trusted-vpc.self_link
}
-module "prod-reverse-10-dns-peering" {
+moved {
+ from = module.prod-reverse-10-dns-peering
+ to = module.prod-dns-peer-landing-rev-10
+}
+
+module "prod-dns-peer-landing-rev-10" {
source = "../../../modules/dns"
project_id = module.prod-spoke-project.project_id
type = "peering"
diff --git a/fast/stages/2-networking-e-nva-bgp/variables.tf b/fast/stages/2-networking-e-nva-bgp/variables.tf
index 85d3c7c07..155a715cc 100644
--- a/fast/stages/2-networking-e-nva-bgp/variables.tf
+++ b/fast/stages/2-networking-e-nva-bgp/variables.tf
@@ -55,8 +55,9 @@ variable "dns" {
variable "factories_config" {
description = "Configuration for network resource factories."
type = object({
- data_dir = optional(string, "data")
- firewall_policy_name = optional(string, "factory")
+ data_dir = optional(string, "data")
+ dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml")
+ firewall_policy_name = optional(string, "factory")
})
default = {
data_dir = "data"
diff --git a/modules/dns-response-policy/README.md b/modules/dns-response-policy/README.md
index dddf4aba5..e55cd3d32 100644
--- a/modules/dns-response-policy/README.md
+++ b/modules/dns-response-policy/README.md
@@ -2,6 +2,8 @@
This module allows management of a [Google Cloud DNS policy and its rules](https://cloud.google.com/dns/docs/zones/manage-response-policies). The policy can already exist and be referenced by name by setting the `policy_create` variable to `false`.
+The module also allows setting rules via a factory. An example is given below.
+
## Examples
### Manage policy and override resolution for specific names
@@ -44,7 +46,15 @@ module "dns-policy" {
landing = var.vpc.self_link
}
rules = {
- default = {
+ gcr = {
+ dns_name = "gcr.io."
+ local_data = {
+ CNAME = {
+ rrdatas = ["restricted.googleapis.com."]
+ }
+ }
+ }
+ googleapis-all = {
dns_name = "*.googleapis.com."
local_data = {
CNAME = {
@@ -59,13 +69,59 @@ module "dns-policy" {
dns_name = "restricted.googleapis.com."
local_data = {
A = {
- rrdatas = ["199.36.153.4", "199.36.153.5"]
+ rrdatas = [
+ "199.36.153.4",
+ "199.36.153.5",
+ "199.36.153.6",
+ "199.36.153.7"
+ ]
}
}
}
}
}
-# tftest modules=1 resources=3 inventory=nocreate.yaml
+# tftest modules=1 resources=4 inventory=complex.yaml
+```
+
+### Define policy rules via a factory file
+
+This example shows how to define rules in a factory file, that mirrors the rules defined via variables in the previous example. Rules defined via the variable are merged with factory rules and take precedence over them when using the same rule names. The YAML syntax closely follows the `rules` variable type.
+
+```hcl
+module "dns-policy" {
+ source = "./fabric/modules/dns-response-policy"
+ project_id = "myproject"
+ name = "googleapis"
+ policy_create = false
+ networks = {
+ landing = var.vpc.self_link
+ }
+ rules_file = "config/rules.yaml"
+}
+# tftest modules=1 resources=4 files=rules-file inventory=complex.yaml
+```
+
+```yaml
+gcr:
+ dns_name: "gcr.io."
+ local_data:
+ CNAME: {rrdatas: ["restricted.googleapis.com."]}
+googleapis-all:
+ dns_name: "*.googleapis.com."
+ local_data:
+ CNAME: {rrdatas: ["restricted.googleapis.com."]}
+pubsub:
+ dns_name: "pubsub.googleapis.com."
+restricted:
+ dns_name: "restricted.googleapis.com."
+ local_data:
+ A:
+ rrdatas:
+ - 199.36.153.4
+ - 199.36.153.5
+ - 199.36.153.6
+ - 199.36.153.7
+# tftest-file id=rules-file path=config/rules.yaml
```
@@ -80,6 +136,7 @@ module "dns-policy" {
| [networks](variables.tf#L35) | Map of VPC self links to which this policy is applied in name => self link format. | map(string) | | {} |
| [policy_create](variables.tf#L42) | Set to false to use the existing policy matching name and only manage rules. | bool | | true |
| [rules](variables.tf#L54) | Map of policy rules in name => rule format. Local data takes precedence over behavior and is in the form record type => attributes. | map(object({…})) | | {} |
+| [rules_file](variables.tf#L68) | Optional data file in YAML format listing rules that will be combined with those passed in via the `rules` variable. | string | | null |
## Outputs
diff --git a/modules/dns-response-policy/main.tf b/modules/dns-response-policy/main.tf
index 26d0a26f8..69b7ff4aa 100644
--- a/modules/dns-response-policy/main.tf
+++ b/modules/dns-response-policy/main.tf
@@ -15,6 +15,17 @@
*/
locals {
+ _factory_rules = try(yamldecode(file(var.rules_file)), {})
+ factory_rules = {
+ for k, v in local._factory_rules : k => {
+ dns_name = v.dns_name
+ behavior = lookup(v, "behavior", "bypassResponsePolicy")
+ local_data = {
+ for kk, vv in lookup(v, "local_data", {}) :
+ kk => merge({ ttl = null, rrdatas = [] }, vv)
+ }
+ }
+ }
policy_name = (
var.policy_create
? google_dns_response_policy.default.0.response_policy_name
@@ -43,7 +54,7 @@ resource "google_dns_response_policy" "default" {
resource "google_dns_response_policy_rule" "default" {
provider = google-beta
- for_each = var.rules
+ for_each = merge(local.factory_rules, var.rules)
project = var.project_id
response_policy = local.policy_name
rule_name = each.key
diff --git a/modules/dns-response-policy/variables.tf b/modules/dns-response-policy/variables.tf
index 8f37ec2b3..fa26c3bb4 100644
--- a/modules/dns-response-policy/variables.tf
+++ b/modules/dns-response-policy/variables.tf
@@ -64,3 +64,9 @@ variable "rules" {
default = {}
nullable = false
}
+
+variable "rules_file" {
+ description = "Optional data file in YAML format listing rules that will be combined with those passed in via the `rules` variable."
+ type = string
+ default = null
+}
diff --git a/tests/fast/stages/s2_networking_a_peering/stage.yaml b/tests/fast/stages/s2_networking_a_peering/stage.yaml
index 556d8f14f..e307c614b 100644
--- a/tests/fast/stages/s2_networking_a_peering/stage.yaml
+++ b/tests/fast/stages/s2_networking_a_peering/stage.yaml
@@ -13,5 +13,5 @@
# limitations under the License.
counts:
- modules: 31
- resources: 122
\ No newline at end of file
+ modules: 27
+ resources: 139
diff --git a/tests/fast/stages/s2_networking_b_vpn/stage.yaml b/tests/fast/stages/s2_networking_b_vpn/stage.yaml
index d63a3e4fe..ebe3fb483 100644
--- a/tests/fast/stages/s2_networking_b_vpn/stage.yaml
+++ b/tests/fast/stages/s2_networking_b_vpn/stage.yaml
@@ -13,5 +13,5 @@
# limitations under the License.
counts:
- modules: 33
- resources: 159
+ modules: 29
+ resources: 176
diff --git a/tests/fast/stages/s2_networking_c_nva/stage.yaml b/tests/fast/stages/s2_networking_c_nva/stage.yaml
index f79d40155..bbd6d6bab 100644
--- a/tests/fast/stages/s2_networking_c_nva/stage.yaml
+++ b/tests/fast/stages/s2_networking_c_nva/stage.yaml
@@ -13,5 +13,5 @@
# limitations under the License.
counts:
- modules: 45
- resources: 168
+ modules: 41
+ resources: 185
diff --git a/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml b/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml
index c6824980a..0313e359c 100644
--- a/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml
+++ b/tests/fast/stages/s2_networking_d_separate_envs/stage.yaml
@@ -13,5 +13,5 @@
# limitations under the License.
counts:
- modules: 28
- resources: 122
+ modules: 20
+ resources: 156
diff --git a/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml b/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml
index 660e718fb..10abee575 100644
--- a/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml
+++ b/tests/fast/stages/s2_networking_e_nva_bgp/stage.yaml
@@ -13,5 +13,5 @@
# limitations under the License.
counts:
- modules: 39
- resources: 181
+ modules: 35
+ resources: 198
diff --git a/tests/modules/dns_response_policy/examples/nocreate.yaml b/tests/modules/dns_response_policy/examples/complex.yaml
similarity index 51%
rename from tests/modules/dns_response_policy/examples/nocreate.yaml
rename to tests/modules/dns_response_policy/examples/complex.yaml
index ccef34bcc..1b22df2a0 100644
--- a/tests/modules/dns_response_policy/examples/nocreate.yaml
+++ b/tests/modules/dns_response_policy/examples/complex.yaml
@@ -13,19 +13,34 @@
# limitations under the License.
values:
- module.dns-policy.google_dns_response_policy_rule.default["default"]:
+ module.dns-policy.google_dns_response_policy_rule.default["gcr"]:
behavior: null
- dns_name: '*.googleapis.com.'
+ dns_name: gcr.io.
local_data:
- - local_datas:
- - name: '*.googleapis.com.'
- rrdatas:
- - restricted.googleapis.com.
- ttl: null
- type: CNAME
+ - local_datas:
+ - name: gcr.io.
+ rrdatas:
+ - restricted.googleapis.com.
+ ttl: null
+ type: CNAME
project: myproject
response_policy: googleapis
- rule_name: default
+ rule_name: gcr
+ timeouts: null
+ module.dns-policy.google_dns_response_policy_rule.default["googleapis-all"]:
+ behavior: null
+ dns_name: "*.googleapis.com."
+ local_data:
+ - local_datas:
+ - name: "*.googleapis.com."
+ rrdatas:
+ - restricted.googleapis.com.
+ ttl: null
+ type: CNAME
+ project: myproject
+ response_policy: googleapis
+ rule_name: googleapis-all
+ timeouts: null
module.dns-policy.google_dns_response_policy_rule.default["pubsub"]:
behavior: bypassResponsePolicy
dns_name: pubsub.googleapis.com.
@@ -33,20 +48,28 @@ values:
project: myproject
response_policy: googleapis
rule_name: pubsub
+ timeouts: null
module.dns-policy.google_dns_response_policy_rule.default["restricted"]:
behavior: null
dns_name: restricted.googleapis.com.
local_data:
- - local_datas:
- - name: restricted.googleapis.com.
- rrdatas:
- - 199.36.153.4
- - 199.36.153.5
- ttl: null
- type: A
+ - local_datas:
+ - name: restricted.googleapis.com.
+ rrdatas:
+ - 199.36.153.4
+ - 199.36.153.5
+ - 199.36.153.6
+ - 199.36.153.7
+ ttl: null
+ type: A
project: myproject
response_policy: googleapis
rule_name: restricted
+ timeouts: null
counts:
- google_dns_response_policy_rule: 3
+ google_dns_response_policy_rule: 4
+ modules: 1
+ resources: 4
+
+outputs: {}