diff --git a/fast/stages/2-networking-a-peering/README.md b/fast/stages/2-networking-a-peering/README.md index f3c7c9511b..2552691a84 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 0000000000..d091e4f084 --- /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 03ae01221c..efeabeaec9 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 7b97a8cfd5..e6a441a52d 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 - -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."] } - } -} +# Google APIs via response policies -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 5bb695fdcb..02fa8c2391 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 8c20b62373..c5f58cd4f6 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 ab1b9734cb..b5b87cefc3 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 0000000000..d091e4f084 --- /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 03ae01221c..efeabeaec9 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 7b97a8cfd5..e6a441a52d 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 - -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."] } - } -} +# Google APIs via response policies -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 5bb695fdcb..02fa8c2391 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 8c20b62373..c5f58cd4f6 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 5aeefa29fb..7ab05f5675 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 0000000000..d091e4f084 --- /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 4eb472a159..98d56aa723 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 40090279f9..50b6589018 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" - 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" +module "landing-dns-policy-googleapis" { + source = "../../../modules/dns-response-policy" 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 b54609dfdb..5627e4386b 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 e4fe6896a3..b56c72d815 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 a718cda8a5..3929db7ee2 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 0000000000..d091e4f084 --- /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 25adab5e22..134b69cff7 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 47c8cdca48..351db57f0e 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 a8920c533e..5ea75c521a 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 ea1e2ec56e..4fee973543 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 0000000000..d091e4f084 --- /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 4eb472a159..98d56aa723 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 40090279f9..50b6589018 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" - 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" +module "landing-dns-policy-googleapis" { + source = "../../../modules/dns-response-policy" 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 b54609dfdb..5627e4386b 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 85d3c7c07e..155a715ccc 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 dddf4aba58..e55cd3d321 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 26d0a26f87..69b7ff4aab 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 8f37ec2b36..fa26c3bb47 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 556d8f14f4..e307c614b8 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 d63a3e4fe8..ebe3fb483e 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 f79d401553..bbd6d6bab2 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 c6824980a8..0313e359cc 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 660e718fb6..10abee575d 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 ccef34bcc1..1b22df2a05 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: {}