Skip to content

Commit

Permalink
Switch FAST networking stages to network policies for Google domains (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
ludoo committed May 4, 2023
1 parent 234aa4c commit efb0ebe
Show file tree
Hide file tree
Showing 38 changed files with 1,018 additions and 652 deletions.
28 changes: 11 additions & 17 deletions fast/stages/2-networking-a-peering/README.md
Expand Up @@ -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:

Expand Down Expand Up @@ -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> | |
Expand All @@ -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

Expand Down
110 changes: 110 additions & 0 deletions fast/stages/2-networking-a-peering/data/dns-policy-rules.yaml
@@ -0,0 +1,110 @@
# skip boilerplate check

accounts:
dns_name: "accounts.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
backupdr-cloud:
dns_name: "backupdr.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
backupdr-cloud-all:
dns_name: "*.backupdr.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
backupdr-gu:
dns_name: "backupdr.googleusercontent.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
backupdr-gu-all:
dns_name: "*.backupdr.googleusercontent.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
cloudfunctions:
dns_name: "*.cloudfunctions.net."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
cloudproxy:
dns_name: "*.cloudproxy.app."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
composer-cloud-all:
dns_name: "*.composer.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
composer-gu-all:
dns_name: "*.composer.googleusercontent.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
datafusion-all:
dns_name: "*.datafusion.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
datafusion-gu-all:
dns_name: "*.datafusion.googleusercontent.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
dataproc:
dns_name: "dataproc.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
dataproc-all:
dns_name: "*.dataproc.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
dataproc-gu:
dns_name: "dataproc.googleusercontent.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
dataproc-gu-all:
dns_name: "*.dataproc.googleusercontent.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
dl:
dns_name: "dl.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
gcr:
dns_name: "gcr.io."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
gcr-all:
dns_name: "*.gcr.io."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
googleapis-all:
dns_name: "*.googleapis.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
googleapis-private:
dns_name: "private.googleapis.com."
local_data:
A:
rrdatas:
- 199.36.153.8
- 199.36.153.9
- 199.36.153.10
- 199.36.153.11
googleapis-restricted:
dns_name: "restricted.googleapis.com."
local_data:
A:
rrdatas:
- 199.36.153.4
- 199.36.153.5
- 199.36.153.6
- 199.36.153.7
gstatic-all:
dns_name: "*.gstatic.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
notebooks-all:
dns_name: "*.notebooks.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
notebooks-gu-all:
dns_name: "*.notebooks.googleusercontent.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
packages-cloud:
dns_name: "packages.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
packages-cloud-all:
dns_name: "*.packages.cloud.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
pkgdev:
dns_name: "pkg.dev."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
pkgdev-all:
dns_name: "*.pkg.dev."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
pkigoog:
dns_name: "pki.goog."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
pkigoog-all:
dns_name: "*.pki.goog."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
run-all:
dns_name: "*.run.app."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
source:
dns_name: "source.developers.google.com."
local_data: { CNAME: { rrdatas: ["private.googleapis.com."] } }
21 changes: 18 additions & 3 deletions fast/stages/2-networking-a-peering/dns-dev.tf
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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"
Expand Down

0 comments on commit efb0ebe

Please sign in to comment.