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