Switch FAST networking stages to network policies for Google domains (#1352)

* peering stage implementation

* vpn stage implementation

* tfdoc

* tests

* add most supported google domains

* align all net stages

* add support for factory to DNS response policy module

* use dns policy factory in network stages

* boilerplate
This commit is contained in:
Ludovico Magnocavallo 2023-05-04 07:38:40 +02:00 committed by GitHub
parent 234aa4c55d
commit efb0ebe689
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1018 additions and 652 deletions

View File

@ -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. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> · <code>dns-response-policy</code> | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | <code>dns</code> | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | <code>folder</code> | |
@ -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. | <code title="object&#40;&#123;&#10; outputs_bucket &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L85) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L86) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L102) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; service_project_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code title="&#123;&#10; onprem &#61; &#91;&#34;10.0.200.3&#34;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L95) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; dns_policy_rules_file &#61; optional&#40;string, &#34;data&#47;dns-policy-rules.yaml&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L96) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [peering_configs](variables-peerings.tf#L19) | Peering configurations. | <code title="map&#40;object&#40;&#123;&#10; export_local_custom_routes &#61; bool&#10; export_peer_custom_routes &#61; bool&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; dev &#61; &#123;&#10; export_local_custom_routes &#61; true&#10; export_peer_custom_routes &#61; true&#10; &#125;&#10; prod &#61; &#123;&#10; export_local_custom_routes &#61; true&#10; export_peer_custom_routes &#61; true&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [psa_ranges](variables.tf#L112) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L133) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L113) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L134) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L146) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_primary_config](variables.tf#L160) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
## Outputs

View File

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

View File

@ -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"

View File

@ -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
}

View File

@ -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"

View File

@ -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"

View File

@ -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. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> · <code>dns-response-policy</code> | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | <code>dns</code> | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | <code>folder</code> | |
@ -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. | <code title="object&#40;&#123;&#10; outputs_bucket &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L85) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L101) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L86) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L102) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; service_project_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code title="&#123;&#10; onprem &#61; &#91;&#34;10.0.200.3&#34;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L95) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L112) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L133) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; dns_policy_rules_file &#61; optional&#40;string, &#34;data&#47;dns-policy-rules.yaml&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L96) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L113) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L134) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L146) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_configs](variables-vpn.tf#L17) | Hub to spokes VPN configurations. | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; asn &#61; number&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; landing &#61; object&#40;&#123;&#10; asn &#61; number&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; asn &#61; number&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; dev &#61; &#123;&#10; asn &#61; 65501&#10; &#125;&#10; landing &#61; &#123;&#10; asn &#61; 65500&#10; &#125;&#10; prod &#61; &#123;&#10; asn &#61; 65502&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [vpn_onprem_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [vpn_onprem_primary_config](variables.tf#L160) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
## Outputs

View File

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

View File

@ -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"

View File

@ -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
}

View File

@ -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"

View File

@ -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"

View File

@ -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. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> · <code>dns-response-policy</code> | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | <code>dns</code> | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | <code>folder</code> | |
@ -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. | <code title="object&#40;&#123;&#10; outputs_bucket &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L108) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L124) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L109) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L125) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; service_project_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code title="&#123;&#10; onprem &#61; &#91;&#34;10.0.200.3&#34;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [gcp_ranges](variables.tf#L85) | GCP address ranges in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp_dev_primary &#61; &#34;10.128.128.0&#47;19&#34;&#10; gcp_dev_secondary &#61; &#34;10.128.160.0&#47;19&#34;&#10; gcp_landing_trusted_primary &#61; &#34;10.128.64.0&#47;19&#34;&#10; gcp_landing_trusted_secondary &#61; &#34;10.128.96.0&#47;19&#34;&#10; gcp_landing_untrusted_primary &#61; &#34;10.128.0.0&#47;19&#34;&#10; gcp_landing_untrusted_secondary &#61; &#34;10.128.32.0&#47;19&#34;&#10; gcp_prod_primary &#61; &#34;10.128.192.0&#47;19&#34;&#10; gcp_prod_secondary &#61; &#34;10.128.224.0&#47;19&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [onprem_cidr](variables.tf#L100) | Onprem addresses in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; main &#61; &#34;10.0.0.0&#47;24&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L118) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L135) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L156) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L168) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_primary_config](variables.tf#L182) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [vpn_onprem_secondary_config](variables.tf#L225) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; dns_policy_rules_file &#61; optional&#40;string, &#34;data&#47;dns-policy-rules.yaml&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [gcp_ranges](variables.tf#L86) | GCP address ranges in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp_dev_primary &#61; &#34;10.128.128.0&#47;19&#34;&#10; gcp_dev_secondary &#61; &#34;10.128.160.0&#47;19&#34;&#10; gcp_landing_trusted_primary &#61; &#34;10.128.64.0&#47;19&#34;&#10; gcp_landing_trusted_secondary &#61; &#34;10.128.96.0&#47;19&#34;&#10; gcp_landing_untrusted_primary &#61; &#34;10.128.0.0&#47;19&#34;&#10; gcp_landing_untrusted_secondary &#61; &#34;10.128.32.0&#47;19&#34;&#10; gcp_prod_primary &#61; &#34;10.128.192.0&#47;19&#34;&#10; gcp_prod_secondary &#61; &#34;10.128.224.0&#47;19&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [onprem_cidr](variables.tf#L101) | Onprem addresses in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; main &#61; &#34;10.0.0.0&#47;24&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L119) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L136) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L157) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L169) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_primary_config](variables.tf#L183) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [vpn_onprem_secondary_config](variables.tf#L226) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
## Outputs

View File

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

View File

@ -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"

View File

@ -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
}

View File

@ -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"

View File

@ -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"

View File

@ -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. | <code>dns</code> | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | <code>dns</code> | |
| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | <code>dns</code> · <code>dns-response-policy</code> | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | <code>dns</code> · <code>dns-response-policy</code> | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | <code>folder</code> | |
| [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | <code>google_monitoring_dashboard</code> |
| [outputs.tf](./outputs.tf) | Module outputs. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
@ -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. | <code title="object&#40;&#123;&#10; outputs_bucket &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L86) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L102) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L77) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L87) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L103) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; service_project_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code title="&#123;&#10; prod &#61; &#91;&#34;10.0.1.1&#34;&#93;&#10; dev &#61; &#91;&#34;10.0.2.1&#34;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [factories_config](variables.tf#L56) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L96) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L113) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L134) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L144) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_dev_primary_config](variables.tf#L158) | VPN gateway configuration for onprem interconnection from dev in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [vpn_onprem_prod_primary_config](variables.tf#L201) | VPN gateway configuration for onprem interconnection from prod in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [factories_config](variables.tf#L56) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; dns_policy_rules_file &#61; optional&#40;string, &#34;data&#47;dns-policy-rules.yaml&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L97) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L114) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L135) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L145) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_dev_primary_config](variables.tf#L159) | VPN gateway configuration for onprem interconnection from dev in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [vpn_onprem_prod_primary_config](variables.tf#L202) | VPN gateway configuration for onprem interconnection from prod in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
## Outputs

View File

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

View File

@ -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
}

View File

@ -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
}

View File

@ -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"

View File

@ -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. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> | |
| [dns-landing.tf](./dns-landing.tf) | Landing DNS zones and peerings setup. | <code>dns</code> · <code>dns-response-policy</code> | |
| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | <code>dns</code> | |
| [landing.tf](./landing.tf) | Landing VPC and related resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>project</code> | |
| [main.tf](./main.tf) | Networking folder and hierarchical policy. | <code>folder</code> | |
@ -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. | <code title="object&#40;&#123;&#10; outputs_bucket &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L75) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L119) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L135) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [folder_ids](variables.tf#L76) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object&#40;&#123;&#10; networking &#61; string&#10; networking-dev &#61; string&#10; networking-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>1-resman</code> |
| [organization](variables.tf#L120) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [prefix](variables.tf#L136) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [custom_roles](variables.tf#L38) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; service_project_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [dns](variables.tf#L47) | Onprem DNS resolvers. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code title="&#123;&#10; onprem &#61; &#91;&#34;10.0.200.3&#34;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [gcp_ranges](variables.tf#L85) | GCP address ranges in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp_dev_primary &#61; &#34;10.128.128.0&#47;19&#34;&#10; gcp_dev_secondary &#61; &#34;10.128.160.0&#47;19&#34;&#10; gcp_landing_trusted_primary &#61; &#34;10.128.64.0&#47;19&#34;&#10; gcp_landing_trusted_secondary &#61; &#34;10.128.96.0&#47;19&#34;&#10; gcp_landing_untrusted_primary &#61; &#34;10.128.0.0&#47;19&#34;&#10; gcp_landing_untrusted_secondary &#61; &#34;10.128.32.0&#47;19&#34;&#10; gcp_prod_primary &#61; &#34;10.128.192.0&#47;19&#34;&#10; gcp_prod_secondary &#61; &#34;10.128.224.0&#47;19&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [ncc_asn](variables.tf#L100) | The NCC Cloud Routers ASN configuration. | <code>map&#40;number&#41;</code> | | <code title="&#123;&#10; nva_primary &#61; 64513&#10; nva_secondary &#61; 64514&#10; trusted &#61; 64515&#10; untrusted &#61; 64512&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [onprem_cidr](variables.tf#L111) | Onprem addresses in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; main &#61; &#34;10.0.0.0&#47;24&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L129) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L146) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L167) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L179) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_primary_config](variables.tf#L193) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [vpn_onprem_secondary_config](variables.tf#L236) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [zones](variables.tf#L279) | Zones in which NVAs are deployed. | <code>list&#40;string&#41;</code> | | <code>&#91;&#34;b&#34;, &#34;c&#34;&#93;</code> | |
| [factories_config](variables.tf#L55) | Configuration for network resource factories. | <code title="object&#40;&#123;&#10; data_dir &#61; optional&#40;string, &#34;data&#34;&#41;&#10; dns_policy_rules_file &#61; optional&#40;string, &#34;data&#47;dns-policy-rules.yaml&#34;&#41;&#10; firewall_policy_name &#61; optional&#40;string, &#34;factory&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_dir &#61; &#34;data&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [gcp_ranges](variables.tf#L86) | GCP address ranges in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp_dev_primary &#61; &#34;10.128.128.0&#47;19&#34;&#10; gcp_dev_secondary &#61; &#34;10.128.160.0&#47;19&#34;&#10; gcp_landing_trusted_primary &#61; &#34;10.128.64.0&#47;19&#34;&#10; gcp_landing_trusted_secondary &#61; &#34;10.128.96.0&#47;19&#34;&#10; gcp_landing_untrusted_primary &#61; &#34;10.128.0.0&#47;19&#34;&#10; gcp_landing_untrusted_secondary &#61; &#34;10.128.32.0&#47;19&#34;&#10; gcp_prod_primary &#61; &#34;10.128.192.0&#47;19&#34;&#10; gcp_prod_secondary &#61; &#34;10.128.224.0&#47;19&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [ncc_asn](variables.tf#L101) | The NCC Cloud Routers ASN configuration. | <code>map&#40;number&#41;</code> | | <code title="&#123;&#10; nva_primary &#61; 64513&#10; nva_secondary &#61; 64514&#10; trusted &#61; 64515&#10; untrusted &#61; 64512&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [onprem_cidr](variables.tf#L112) | Onprem addresses in name => range format. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; main &#61; &#34;10.0.0.0&#47;24&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L130) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [psa_ranges](variables.tf#L147) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object&#40;&#123;&#10; dev &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10; prod &#61; object&#40;&#123;&#10; ranges &#61; map&#40;string&#41;&#10; routes &#61; object&#40;&#123;&#10; export &#61; bool&#10; import &#61; bool&#10; &#125;&#41;&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [regions](variables.tf#L168) | Region definitions. | <code title="object&#40;&#123;&#10; primary &#61; string&#10; secondary &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; primary &#61; &#34;europe-west1&#34;&#10; secondary &#61; &#34;europe-west4&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [service_accounts](variables.tf#L180) | Automation service accounts in name => email format. | <code title="object&#40;&#123;&#10; data-platform-dev &#61; string&#10; data-platform-prod &#61; string&#10; gke-dev &#61; string&#10; gke-prod &#61; string&#10; project-factory-dev &#61; string&#10; project-factory-prod &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>1-resman</code> |
| [vpn_onprem_primary_config](variables.tf#L194) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [vpn_onprem_secondary_config](variables.tf#L237) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object&#40;&#123;&#10; peer_external_gateways &#61; map&#40;object&#40;&#123;&#10; redundancy_type &#61; string&#10; interfaces &#61; list&#40;string&#41;&#10; &#125;&#41;&#41;&#10; router_config &#61; object&#40;&#123;&#10; create &#61; optional&#40;bool, true&#41;&#10; asn &#61; number&#10; name &#61; optional&#40;string&#41;&#10; keepalive &#61; optional&#40;number&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; tunnels &#61; map&#40;object&#40;&#123;&#10; bgp_peer &#61; object&#40;&#123;&#10; address &#61; string&#10; asn &#61; number&#10; route_priority &#61; optional&#40;number, 1000&#41;&#10; custom_advertise &#61; optional&#40;object&#40;&#123;&#10; all_subnets &#61; bool&#10; all_vpc_subnets &#61; bool&#10; all_peer_vpc_subnets &#61; bool&#10; ip_ranges &#61; map&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; bgp_session_range &#61; string&#10; ike_version &#61; optional&#40;number, 2&#41;&#10; peer_external_gateway_interface &#61; optional&#40;number&#41;&#10; peer_gateway &#61; optional&#40;string, &#34;default&#34;&#41;&#10; router &#61; optional&#40;string&#41;&#10; shared_secret &#61; optional&#40;string&#41;&#10; vpn_gateway_interface &#61; number&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [zones](variables.tf#L280) | Zones in which NVAs are deployed. | <code>list&#40;string&#41;</code> | | <code>&#91;&#34;b&#34;, &#34;c&#34;&#93;</code> | |
## Outputs

View File

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

View File

@ -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"

View File

@ -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
}

View File

@ -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"

View File

@ -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"

View File

@ -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
```
<!-- BEGIN TFDOC -->
@ -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. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [policy_create](variables.tf#L42) | Set to false to use the existing policy matching name and only manage rules. | <code>bool</code> | | <code>true</code> |
| [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. | <code title="map&#40;object&#40;&#123;&#10; dns_name &#61; string&#10; behavior &#61; optional&#40;string, &#34;bypassResponsePolicy&#34;&#41;&#10; local_data &#61; optional&#40;map&#40;object&#40;&#123;&#10; ttl &#61; optional&#40;number&#41;&#10; rrdatas &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [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. | <code>string</code> | | <code>null</code> |
## Outputs

View File

@ -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

View File

@ -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
}

View File

@ -13,5 +13,5 @@
# limitations under the License.
counts:
modules: 31
resources: 122
modules: 27
resources: 139

View File

@ -13,5 +13,5 @@
# limitations under the License.
counts:
modules: 33
resources: 159
modules: 29
resources: 176

View File

@ -13,5 +13,5 @@
# limitations under the License.
counts:
modules: 45
resources: 168
modules: 41
resources: 185

View File

@ -13,5 +13,5 @@
# limitations under the License.
counts:
modules: 28
resources: 122
modules: 20
resources: 156

View File

@ -13,5 +13,5 @@
# limitations under the License.
counts:
modules: 39
resources: 181
modules: 35
resources: 198

View File

@ -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: {}