From 24c3ffe66b8648a799be6b8d168e1993d714e58b Mon Sep 17 00:00:00 2001 From: Simone Ruffilli Date: Mon, 10 Oct 2022 11:50:07 +0200 Subject: [PATCH] FAST: Separate network environment (#566) --- .../02-networking-separate-envs/.gitignore | 1 + .../stages/02-networking-separate-envs/IAM.md | 16 + .../02-networking-separate-envs/README.md | 262 +++ .../data/cidrs.yaml | 15 + .../data/dashboards/firewall_insights.json | 68 + .../data/dashboards/vpn.json | 248 ++ .../data/firewall-rules/dev/rules.yaml | 27 + .../data/hierarchical-policy-rules.yaml | 49 + .../subnets/dev/dev-dataplatform-ew1.yaml | 8 + .../data/subnets/dev/dev-default-ew1.yaml | 5 + .../data/subnets/prod/prod-default-ew1.yaml | 5 + .../02-networking-separate-envs/diagram.png | Bin 0 -> 126351 bytes .../02-networking-separate-envs/diagram.svg | 2059 +++++++++++++++++ .../02-networking-separate-envs/dns-dev.tf | 69 + .../02-networking-separate-envs/dns-prod.tf | 70 + .../02-networking-separate-envs/main.tf | 58 + .../02-networking-separate-envs/monitoring.tf | 38 + .../02-networking-separate-envs/outputs.tf | 102 + .../02-networking-separate-envs/spoke-dev.tf | 112 + .../02-networking-separate-envs/spoke-prod.tf | 112 + .../test-resources.tf | 83 + .../02-networking-separate-envs/variables.tf | 285 +++ .../vpn-onprem-dev.tf | 62 + .../vpn-onprem-prod.tf | 46 + .../s02_networking_separate_envs/__init__.py | 13 + .../fixture/main.tf | 47 + .../s02_networking_separate_envs/test_plan.py | 20 + 27 files changed, 3880 insertions(+) create mode 100644 fast/stages/02-networking-separate-envs/.gitignore create mode 100644 fast/stages/02-networking-separate-envs/IAM.md create mode 100644 fast/stages/02-networking-separate-envs/README.md create mode 100644 fast/stages/02-networking-separate-envs/data/cidrs.yaml create mode 100644 fast/stages/02-networking-separate-envs/data/dashboards/firewall_insights.json create mode 100644 fast/stages/02-networking-separate-envs/data/dashboards/vpn.json create mode 100644 fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml create mode 100644 fast/stages/02-networking-separate-envs/data/hierarchical-policy-rules.yaml create mode 100644 fast/stages/02-networking-separate-envs/data/subnets/dev/dev-dataplatform-ew1.yaml create mode 100644 fast/stages/02-networking-separate-envs/data/subnets/dev/dev-default-ew1.yaml create mode 100644 fast/stages/02-networking-separate-envs/data/subnets/prod/prod-default-ew1.yaml create mode 100644 fast/stages/02-networking-separate-envs/diagram.png create mode 100644 fast/stages/02-networking-separate-envs/diagram.svg create mode 100644 fast/stages/02-networking-separate-envs/dns-dev.tf create mode 100644 fast/stages/02-networking-separate-envs/dns-prod.tf create mode 100644 fast/stages/02-networking-separate-envs/main.tf create mode 100644 fast/stages/02-networking-separate-envs/monitoring.tf create mode 100644 fast/stages/02-networking-separate-envs/outputs.tf create mode 100644 fast/stages/02-networking-separate-envs/spoke-dev.tf create mode 100644 fast/stages/02-networking-separate-envs/spoke-prod.tf create mode 100644 fast/stages/02-networking-separate-envs/test-resources.tf create mode 100644 fast/stages/02-networking-separate-envs/variables.tf create mode 100644 fast/stages/02-networking-separate-envs/vpn-onprem-dev.tf create mode 100644 fast/stages/02-networking-separate-envs/vpn-onprem-prod.tf create mode 100644 tests/fast/stages/s02_networking_separate_envs/__init__.py create mode 100644 tests/fast/stages/s02_networking_separate_envs/fixture/main.tf create mode 100644 tests/fast/stages/s02_networking_separate_envs/test_plan.py diff --git a/fast/stages/02-networking-separate-envs/.gitignore b/fast/stages/02-networking-separate-envs/.gitignore new file mode 100644 index 00000000..19af5b74 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/.gitignore @@ -0,0 +1 @@ +ludo-* diff --git a/fast/stages/02-networking-separate-envs/IAM.md b/fast/stages/02-networking-separate-envs/IAM.md new file mode 100644 index 00000000..f5c69067 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/IAM.md @@ -0,0 +1,16 @@ +# IAM bindings reference + +Legend: + additive, conditional. + +## Project dev-net-spoke-0 + +| members | roles | +|---|---| +|dev-resman-pf-0
serviceAccount|[roles/resourcemanager.projectIamAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectIamAdmin)
[roles/dns.admin](https://cloud.google.com/iam/docs/understanding-roles#dns.admin) | +|prod-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin | + +## Project prod-net-spoke-0 + +| members | roles | +|---|---| +|prod-resman-pf-0
serviceAccount|[roles/resourcemanager.projectIamAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectIamAdmin)
organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/dns.admin](https://cloud.google.com/iam/docs/understanding-roles#dns.admin) | diff --git a/fast/stages/02-networking-separate-envs/README.md b/fast/stages/02-networking-separate-envs/README.md new file mode 100644 index 00000000..2329aad4 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/README.md @@ -0,0 +1,262 @@ +# Networking + +This stage sets up the shared network infrastructure for the whole organization. It implements a single shared VPC per environment, where each environment is independently connected to the on-premise environment, to maintain a fully separated routing domain on GCP. + +While no communication between environment is implemented on this design, that can be achieved with a number of different options: + +- [VPC Peering](https://cloud.google.com/vpc/docs/vpc-peering) - which is not recommended as it would effectively create a full line of sight between workloads belonging to different environments +- [VPN HA](https://cloud.google.com/network-connectivity/docs/vpn/concepts/topologies) tunnels between environments, exchanging a subset of well-defined routes. +- [Multi-NIC appliances](https://cloud.google.com/architecture/best-practices-vpc-design#multi-nic) connecting the different environments, allowing the use of NVAs to enforce networking policies. + +The following diagram illustrates the high-level design, and should be used as a reference for the following sections. The final number of subnets, and their IP addressing design will of course depend on customer-specific requirements, and can be easily changed via variables or external data files without having to edit the actual code. + +

+ Networking diagram +

+ +## Design overview and choices + +### VPC design + +This architecture creates one VPC for each environment, each in its respective project. Each VPC hosts external connectivity and shared services solely serving its own environment. + +As each environment is fully independent, this design trivialises the creation of new environments. + +### External connectivity + +External connectivity to on-prem is implemented here via HA VPN (two tunnels per region), as this is the minimum common denominator often used directly, or as a stop-gap solution to validate routing and transfer data, while waiting for [interconnects](https://cloud.google.com/network-connectivity/docs/interconnect) to be provisioned. + +Connectivity to additional on-prem sites or other cloud providers should be implemented in a similar fashion, via VPN tunnels or interconnects on each of the environment VPCs, sharing the same regional router. + +### IP ranges, subnetting, routing + +Minimizing the number of routes (and subnets) in use on the cloud environment is an important consideration, as it simplifies management and avoids hitting [Cloud Router](https://cloud.google.com/network-connectivity/docs/router/quotas) and [VPC](https://cloud.google.com/vpc/docs/quota) quotas and limits. For this reason, we recommend careful planning of the IP space used in your cloud environment, to be able to use large IP CIDR blocks in routes whenever possible. + +This stage uses a dedicated /16 block (which should of course be sized to your needs) shared by all regions and environments, and subnets created in each VPC derive their ranges from their relevant block. + +Each VPC also defines and reserves two "special" CIDR ranges dedicated to [PSA (Private Service Access)](https://cloud.google.com/vpc/docs/private-services-access) and [Internal HTTPs Load Balancers (L7ILB)](https://cloud.google.com/load-balancing/docs/l7-internal). + +Routes in GCP are either automatically created for VPC subnets, manually created via static routes, or dynamically programmed by [Cloud Routers](https://cloud.google.com/network-connectivity/docs/router#docs) via BGP sessions, which can be configured to advertise VPC ranges, and/or custom ranges via custom advertisements. + +In this setup: + +- routes between multiple subnets within the same VPC are automatically programmed by GCP +- on-premises is connected to each environment VPC and dynamically exchanges BGP routes with GCP using HA VPN + +### Internet egress + +The path of least resistance for Internet egress is using Cloud NAT, and that is what's implemented in this setup, with a NAT gateway configured for each VPC. + +Several other scenarios are possible of course, with varying degrees of complexity: + +- a forward proxy, with optional URL filters +- a default route to on-prem to leverage existing egress infrastructure +- a full-fledged perimeter firewall to control egress and implement additional security features like IPS + +Future pluggable modules will allow to easily experiment, or deploy the above scenarios. + +### VPC and Hierarchical Firewall + +The GCP Firewall is a stateful, distributed feature that allows the creation of L4 policies, either via VPC-level rules or more recently via hierarchical policies applied on the resource hierarchy (organization, folders). + +The current setup adopts both firewall types, and uses hierarchical rules on the Networking folder for common ingress rules (egress is open by default), e.g. from health check or IAP forwarders ranges, and VPC rules for the environment or workload-level ingress. + +Rules and policies are defined in simple YAML files, described below. + +### DNS + +DNS often goes hand in hand with networking, especially on GCP where Cloud DNS zones and policies are associated at the VPC level. This setup implements both DNS flows: + +- 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 + +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: + +- `private.googleapis.com` +- `restricted.googleapis.com` +- `gcp.example.com` (used as a placeholder) + +From cloud, the `example.com` domain (used as a placeholder) is forwarded to on-prem. + +This configuration is battle-tested, and flexible enough to lend itself to simple modifications without subverting its design, for example by forwarding and peering root zones to bypass Cloud DNS external resolution. + +## How to run this stage + +This stage is meant to be executed after the [resman](../01-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../00-bootstrap) stage. + +It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. + +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. + +### Providers configuration + +The default way of making sure you have the right permissions, is to use the identity of the service account pre-created for this stage during the [resource management](../01-resman) stage, and that you are a member of the group that can impersonate it via provider-level configuration (`gcp-devops` or `organization-admins`). + +To simplify setup, the previous stage pre-configures a valid providers file in its output, and optionally writes it to a local file if the `outputs_location` variable is set to a valid path. + +If you have set a valid value for `outputs_location` in the bootstrap stage, simply link the relevant `providers.tf` file from this stage's folder in the path you specified: + +```bash +# `outputs_location` is set to `~/fast-config` +ln -s ~/fast-config/providers/02-networking-providers.tf . +``` + +If you have not configured `outputs_location` in bootstrap, you can derive the providers file from that stage's outputs: + +```bash +cd ../01-resman +terraform output -json providers | jq -r '.["02-networking"]' \ + > ../02-networking/providers.tf +``` + +### Variable configuration + +There are two broad sets of variables you will need to fill in: + +- variables shared by other stages (org id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) +- variables specific to resources managed by this stage + +To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. + +If you have set a valid value for `outputs_location` in the bootstrap and in the resman stage, simply link the relevant `terraform-*.auto.tfvars.json` files from this stage's folder in the path you specified, where the `*` above is set to the name of the stage that produced it. For this stage, a single `.tfvars` file is available: + +```bash +# `outputs_location` is set to `~/fast-config` +ln -s ../../configs/example/02-networking/terraform-bootstrap.auto.tfvars.json +ln -s ../../configs/example/02-networking/terraform-resman.auto.tfvars.json +# also copy the tfvars file used for the bootstrap stage +cp ../00-bootstrap/terraform.tfvars . +``` + +A second set of variables is specific to this stage, they are all optional so if you need to customize them, add them to the file copied from bootstrap. + +Please refer to the [Variables](#variables) table below for a map of the variable origins, and to the sections below on how to adapt this stage to your networking configuration. + +### VPCs + +VPCs are defined in separate files, one for each of `prod` and `dev`. +Each file contains the same resources, described in the following paragraphs. + +The **project** ([`project`](../../../modules/project)) contains the VPC, and enables the required APIs and sets itself as a "[host project](https://cloud.google.com/vpc/docs/shared-vpc)". + +The **VPC** ([`net-vpc`](../../../modules/net-vpc)) manages the DNS inbound policy, explicit routes for `{private,restricted}.googleapis.com`, and its **subnets**. Subnets are created leveraging a "resource factory" paradigm, where the configuration is separated from the module that implements it, and stored in a well-structured file. To add a new subnet, simply create a new file in the `data_folder` directory defined in the module, following the examples found in the [Fabric `net-vpc` documentation](../../../modules/net-vpc#subnet-factory). Sample subnets are shipped in [data/subnets](./data/subnets), and can be easily customised to fit your needs. + +Subnets for [L7 ILBs](https://cloud.google.com/load-balancing/docs/l7-internal/proxy-only-subnets) are handled differently, and defined in variable `l7ilb_subnets`, while ranges for [PSA](https://cloud.google.com/vpc/docs/configure-private-services-access#allocating-range) are configured by variable `psa_ranges` - such variables are consumed by spoke VPCs. + +**Cloud NAT** ([`net-cloudnat`](../../../modules/net-cloudnat)) manages the networking infrastructure required to enable internet egress. + +### VPNs + +Connectivity to on-prem is implemented with HA VPN ([`net-vpn`](../../../modules/net-vpn-ha)) and defined in `vpn-onprem-{dev,prod}.tf`. The files provisionally implement each a single logical connection between onprem and environment at `europe-west1`, and the relevant parameters for its configuration are found in variable `vpn_onprem_configs`. + +### Routing and BGP + +Each VPC network ([`net-vpc`](../../../modules/net-vpc)) manages a separate routing table, which can define static routes (e.g. to private.googleapis.com) and receives dynamic routes from BGP sessions established with neighbor networks (e.g. from onprem). + +Static routes are defined in `net-*.tf` files, in the `routes` section of each `net-vpc` module. + +### Firewall + +**VPC firewall rules** ([`net-vpc-firewall`](../../../modules/net-vpc-firewall)) are defined per-vpc on each `net-*.tf` file and leverage a resource factory to massively create rules. +To add a new firewall rule, create a new file or edit an existing one in the `data_folder` directory defined in the module `net-vpc-firewall`, following the examples of the "[Rules factory](../../../modules/net-vpc-firewall#rules-factory)" section of the module documentation. Sample firewall rules are shipped in [data/firewall-rules/dev](./data/firewall-rules/dev) and can be easily customised. + +**Hierarchical firewall policies** ([`folder`](../../../modules/folder)) are defined in `main.tf`, and managed through a policy factory implemented by the `folder` module, which applies the defined hierarchical to the `Networking` folder, which contains all the core networking infrastructure. Policies are defined in the `rules_file` file - to define a new one simply use the instructions found on "[Firewall policy factory](../../../modules/organization#firewall-policy-factory)". Sample hierarchical firewall policies are shipped in [data/hierarchical-policy-rules.yaml](./data/hierarchical-policy-rules.yaml) and can be easily customised. + +### DNS architecture + +The DNS ([`dns`](../../../modules/dns)) infrastructure is defined in the respective `dns-xxx.tf` files. + +Cloud DNS manages onprem forwarding and environment-specific zones (i.e. `dev.gcp.example.com` and `prod.gcp.example.com`). + +#### Cloud to on-prem + +Leveraging the forwarding zones defined on each environment, the cloud environment can resolve `in-addr.arpa.` and `onprem.example.com.` using the on-premises DNS infrastructure. Onprem resolvers IPs are set in variable `dns`. + +DNS queries sent to the on-premises infrastructure come from the `35.199.192.0/19` source range, which is only accessible from within a VPC or networks connected to one. + +When implementing this architecture, make sure you'll be able to route packets coming from the /19 range to the right environment (route to prod requests coming from prod and to dev for requests coming from dev). As an alternative, consider leveraging self-managed DNS resolvers (e.g. CoreDNS forwarders) on each environment. + +#### On-prem to cloud + +The [Inbound DNS Policy](https://cloud.google.com/dns/docs/server-policies-overview#dns-server-policy-in) defined on eachVPC automatically reserves the first available IP address on each created subnet (typically the third one in a CIDR) to expose the Cloud DNS service so that it can be consumed from outside of GCP. + +### Private Google Access + +[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. + +For PGA to work: + +- Private Google Access should be enabled on the subnet. \ +Subnets created by the `net-vpc` module are PGA-enabled by default. + +- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ +Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC has explicit routes set in case the `0.0.0.0/0` route is changed. + +- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain), as implemented in module `googleapis-private-zone` in `dns-xxx.tf` + +### Preliminar activities + +Before running `terraform apply` on this stage, make sure to adapt all of `variables.tf` to your needs, to update all reference to regions (e.g. `europe-west1` or `ew1`) in the whole directory to match your preferences. + +If you're not using FAST, you'll also need to create a `providers.tf` file to configure the GCS backend and the service account to use to run the deployment. + +You're now ready to run `terraform init` and `apply`. + +### Post-deployment activities + +- On-prem routers should be configured to advertise all relevant CIDRs to the GCP environments. To avoid hitting GCP quotas, we recomment aggregating routes as much as possible. +- On-prem routers should accept BGP sessions from their cloud peers. +- On-prem DNS servers should have forward zones for GCP-managed ones. + + + + +## Files + +| name | description | modules | resources | +|---|---|---|---| +| [dns-dev.tf](./dns-dev.tf) | Development spoke DNS zones and peerings setup. | dns | | +| [dns-prod.tf](./dns-prod.tf) | Production spoke DNS zones and peerings setup. | dns | | +| [main.tf](./main.tf) | Networking folder and hierarchical policy. | folder | | +| [monitoring.tf](./monitoring.tf) | Network monitoring dashboards. | | google_monitoring_dashboard | +| [outputs.tf](./outputs.tf) | Module outputs. | | google_storage_bucket_object · local_file | +| [spoke-dev.tf](./spoke-dev.tf) | Dev spoke VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | google_project_iam_binding | +| [spoke-prod.tf](./spoke-prod.tf) | Production spoke VPC and related resources. | net-cloudnat · net-vpc · net-vpc-firewall · project | google_project_iam_binding | +| [test-resources.tf](./test-resources.tf) | Temporary instances for testing | compute-vm | | +| [variables.tf](./variables.tf) | Module variables. | | | +| [vpn-onprem-dev.tf](./vpn-onprem-dev.tf) | VPN between dev and onprem. | net-vpn-ha | | +| [vpn-onprem-prod.tf](./vpn-onprem-prod.tf) | VPN between prod and onprem. | net-vpn-ha | | + +## Variables + +| name | description | type | required | default | producer | +|---|---|:---:|:---:|:---:|:---:| +| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 00-bootstrap | +| [billing_account](variables.tf#L25) | Billing account id and organization id ('nnnnnnnn' or null). | object({…}) | ✓ | | 00-bootstrap | +| [folder_ids](variables.tf#L74) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | object({…}) | ✓ | | 01-resman | +| [organization](variables.tf#L102) | Organization details. | object({…}) | ✓ | | 00-bootstrap | +| [prefix](variables.tf#L118) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 00-bootstrap | +| [custom_adv](variables.tf#L34) | Custom advertisement definitions in name => range format. | map(string) | | {…} | | +| [custom_roles](variables.tf#L50) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 00-bootstrap | +| [data_dir](variables.tf#L59) | Relative path for the folder storing configuration data for network resources. | string | | "data" | | +| [dns](variables.tf#L65) | Onprem DNS resolvers. | map(list(string)) | | {…} | | +| [l7ilb_subnets](variables.tf#L84) | Subnets used for L7 ILBs. | map(list(object({…}))) | | {…} | | +| [outputs_location](variables.tf#L112) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | string | | null | | +| [psa_ranges](variables.tf#L129) | IP ranges used for Private Service Access (e.g. CloudSQL). | object({…}) | | null | | +| [router_onprem_configs](variables.tf#L166) | Configurations for routers used for onprem connectivity. | map(object({…})) | | {…} | | +| [service_accounts](variables.tf#L189) | Automation service accounts in name => email format. | object({…}) | | null | 01-resman | +| [vpn_onprem_configs](variables.tf#L201) | VPN gateway configuration for onprem interconnection. | map(object({…})) | | {…} | | + +## Outputs + +| name | description | sensitive | consumers | +|---|---|:---:|---| +| [dev_cloud_dns_inbound_policy](outputs.tf#L59) | IP Addresses for Cloud DNS inbound policy for the dev environment. | | | +| [host_project_ids](outputs.tf#L69) | Network project ids. | | | +| [host_project_numbers](outputs.tf#L74) | Network project numbers. | | | +| [prod_cloud_dns_inbound_policy](outputs.tf#L64) | IP Addresses for Cloud DNS inbound policy for the prod environment. | | | +| [shared_vpc_self_links](outputs.tf#L79) | Shared VPC host projects. | | | +| [tfvars](outputs.tf#L98) | Terraform variables file for the following stages. | ✓ | | +| [vpn_gateway_endpoints](outputs.tf#L84) | External IP Addresses for the GCP VPN gateways. | | | + + diff --git a/fast/stages/02-networking-separate-envs/data/cidrs.yaml b/fast/stages/02-networking-separate-envs/data/cidrs.yaml new file mode 100644 index 00000000..b6c25e21 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/cidrs.yaml @@ -0,0 +1,15 @@ +# skip boilerplate check + +healthchecks: + - 35.191.0.0/16 + - 130.211.0.0/22 + - 209.85.152.0/22 + - 209.85.204.0/22 + +rfc1918: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + +onprem_probes: + - 10.255.255.254/32 diff --git a/fast/stages/02-networking-separate-envs/data/dashboards/firewall_insights.json b/fast/stages/02-networking-separate-envs/data/dashboards/firewall_insights.json new file mode 100644 index 00000000..e829091c --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/dashboards/firewall_insights.json @@ -0,0 +1,68 @@ +{ + "displayName": "Firewall Insights Monitoring", + "gridLayout": { + "columns": "2", + "widgets": [ + { + "title": "Subnet Firewall Hit Counts", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"firewallinsights.googleapis.com/subnet/firewall_hit_count\" resource.type=\"gce_subnetwork\"", + "secondaryAggregation": {} + }, + "unitOverride": "1" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "VM Firewall Hit Counts", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"firewallinsights.googleapis.com/vm/firewall_hit_count\" resource.type=\"gce_instance\"", + "secondaryAggregation": {} + }, + "unitOverride": "1" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + } + ] + } +} \ No newline at end of file diff --git a/fast/stages/02-networking-separate-envs/data/dashboards/vpn.json b/fast/stages/02-networking-separate-envs/data/dashboards/vpn.json new file mode 100644 index 00000000..4396cc00 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/dashboards/vpn.json @@ -0,0 +1,248 @@ +{ + "displayName": "VPN Monitoring", + "gridLayout": { + "columns": "2", + "widgets": [ + { + "title": "Number of connections", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_MEAN" + }, + "filter": "metric.type=\"vpn.googleapis.com/gateway/connections\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "1" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "Tunnel established", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_MEAN" + }, + "filter": "metric.type=\"vpn.googleapis.com/tunnel_established\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "1" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "Cloud VPN Gateway - Received bytes", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"vpn.googleapis.com/network/received_bytes_count\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "By" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "Cloud VPN Gateway - Sent bytes", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"vpn.googleapis.com/network/sent_bytes_count\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "By" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "Cloud VPN Gateway - Received packets", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"vpn.googleapis.com/network/received_packets_count\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "{packets}" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "Cloud VPN Gateway - Sent packets", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"vpn.googleapis.com/network/sent_packets_count\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "{packets}" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "Incoming packets dropped", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"vpn.googleapis.com/network/dropped_received_packets_count\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "1" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + }, + { + "title": "Outgoing packets dropped", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "targetAxis": "Y1", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"vpn.googleapis.com/network/dropped_sent_packets_count\" resource.type=\"vpn_gateway\"", + "secondaryAggregation": {} + }, + "unitOverride": "1" + } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "label": "y1Axis", + "scale": "LINEAR" + } + } + } + ] + } +} \ No newline at end of file diff --git a/fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml new file mode 100644 index 00000000..d4df8cdc --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/firewall-rules/dev/rules.yaml @@ -0,0 +1,27 @@ +# skip boilerplate check + +ingress-allow-composer-nodes: + description: "Allow traffic to Composer nodes." + direction: INGRESS + action: allow + sources: [] + ranges: ["0.0.0.0/0"] + targets: + - composer-worker + use_service_accounts: false + rules: + - protocol: tcp + ports: [80, 443, 3306, 3307] + +ingress-allow-dataflow-load: + description: "Allow traffic to Dataflow nodes." + direction: INGRESS + action: allow + sources: [] + ranges: ["0.0.0.0/0"] + targets: + - dataflow + use_service_accounts: false + rules: + - protocol: tcp + ports: [12345, 12346] diff --git a/fast/stages/02-networking-separate-envs/data/hierarchical-policy-rules.yaml b/fast/stages/02-networking-separate-envs/data/hierarchical-policy-rules.yaml new file mode 100644 index 00000000..0172a309 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/hierarchical-policy-rules.yaml @@ -0,0 +1,49 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + direction: INGRESS + action: allow + priority: 1000 + ranges: + - $rfc1918 + ports: + all: [] + target_resources: null + enable_logging: false + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + direction: INGRESS + action: allow + priority: 1001 + ranges: + - $healthchecks + ports: + tcp: ["80", "443"] + target_resources: null + enable_logging: false + +allow-ssh-from-iap: + description: Enable SSH from IAP + direction: INGRESS + action: allow + priority: 1002 + ranges: + - 35.235.240.0/20 + ports: + tcp: ["22"] + target_resources: null + enable_logging: false + +allow-icmp: + description: Enable ICMP + direction: INGRESS + action: allow + priority: 1003 + ranges: + - 0.0.0.0/0 + ports: + icmp: [] + target_resources: null + enable_logging: false diff --git a/fast/stages/02-networking-separate-envs/data/subnets/dev/dev-dataplatform-ew1.yaml b/fast/stages/02-networking-separate-envs/data/subnets/dev/dev-dataplatform-ew1.yaml new file mode 100644 index 00000000..92994826 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/subnets/dev/dev-dataplatform-ew1.yaml @@ -0,0 +1,8 @@ +# skip boilerplate check + +region: europe-west1 +description: Default subnet for dev Data Platform +ip_cidr_range: 10.128.48.0/24 +secondary_ip_range: + pods: 100.128.48.0/20 + services: 100.255.48.0/24 diff --git a/fast/stages/02-networking-separate-envs/data/subnets/dev/dev-default-ew1.yaml b/fast/stages/02-networking-separate-envs/data/subnets/dev/dev-default-ew1.yaml new file mode 100644 index 00000000..8b066ba7 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/subnets/dev/dev-default-ew1.yaml @@ -0,0 +1,5 @@ +# skip boilerplate check + +region: europe-west1 +ip_cidr_range: 10.128.32.0/24 +description: Default subnet for dev diff --git a/fast/stages/02-networking-separate-envs/data/subnets/prod/prod-default-ew1.yaml b/fast/stages/02-networking-separate-envs/data/subnets/prod/prod-default-ew1.yaml new file mode 100644 index 00000000..0052eff9 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/data/subnets/prod/prod-default-ew1.yaml @@ -0,0 +1,5 @@ +# skip boilerplate check + +region: europe-west1 +ip_cidr_range: 10.128.64.0/24 +description: Default subnet for prod diff --git a/fast/stages/02-networking-separate-envs/diagram.png b/fast/stages/02-networking-separate-envs/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..740b84429a28b6e6163dd4c39861073287acc94f GIT binary patch literal 126351 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
  • {8>nMQYEBTCBUFE{0><@!r=A; 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 CdtU4S literal 0 HcmV?d00001 diff --git a/fast/stages/02-networking-separate-envs/diagram.svg b/fast/stages/02-networking-separate-envs/diagram.svg new file mode 100644 index 00000000..ef569b90 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/diagram.svg @@ -0,0 +1,2059 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fast/stages/02-networking-separate-envs/dns-dev.tf b/fast/stages/02-networking-separate-envs/dns-dev.tf new file mode 100644 index 00000000..355938b2 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/dns-dev.tf @@ -0,0 +1,69 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Development spoke DNS zones and peerings setup. + +# GCP-specific environment zone + +module "dev-dns-private-zone" { + source = "../../../modules/dns" + project_id = module.dev-spoke-project.project_id + type = "private" + name = "dev-gcp-example-com" + domain = "dev.gcp.example.com." + client_networks = [module.dev-spoke-vpc.self_link] + recordsets = { + "A localhost" = { type = "A", ttl = 300, records = ["127.0.0.1"] } + } +} + +module "dev-onprem-example-dns-forwarding" { + source = "../../../modules/dns" + project_id = module.dev-spoke-project.project_id + type = "forwarding" + name = "example-com" + domain = "onprem.example.com." + client_networks = [module.dev-spoke-vpc.self_link] + forwarders = { for ip in var.dns.dev : ip => null } +} + +module "dev-reverse-10-dns-forwarding" { + source = "../../../modules/dns" + project_id = module.dev-spoke-project.project_id + type = "forwarding" + name = "root-reverse-10" + domain = "10.in-addr.arpa." + client_networks = [module.dev-spoke-vpc.self_link] + forwarders = { for ip in var.dns.dev : ip => null } +} + +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" = { type = "A", ttl = 300, records = [ + "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11" + ] } + "A restricted" = { type = "A", ttl = 300, records = [ + "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7" + ] } + "CNAME *" = { type = "CNAME", ttl = 300, records = ["private.googleapis.com."] } + } +} diff --git a/fast/stages/02-networking-separate-envs/dns-prod.tf b/fast/stages/02-networking-separate-envs/dns-prod.tf new file mode 100644 index 00000000..3dc7ff43 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/dns-prod.tf @@ -0,0 +1,70 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Production spoke DNS zones and peerings setup. + +# GCP-specific environment zone + +module "prod-dns-private-zone" { + source = "../../../modules/dns" + project_id = module.prod-spoke-project.project_id + type = "private" + name = "prod-gcp-example-com" + domain = "prod.gcp.example.com." + client_networks = [module.prod-spoke-vpc.self_link] + recordsets = { + "A localhost" = { type = "A", ttl = 300, records = ["127.0.0.1"] } + } +} + +module "prod-onprem-example-dns-forwarding" { + source = "../../../modules/dns" + project_id = module.prod-spoke-project.project_id + type = "forwarding" + name = "example-com" + domain = "onprem.example.com." + client_networks = [module.prod-spoke-vpc.self_link] + forwarders = { for ip in var.dns.prod : ip => null } +} + +module "prod-reverse-10-dns-forwarding" { + source = "../../../modules/dns" + project_id = module.prod-spoke-project.project_id + type = "forwarding" + name = "root-reverse-10" + domain = "10.in-addr.arpa." + client_networks = [module.prod-spoke-vpc.self_link] + forwarders = { for ip in var.dns.prod : ip => null } +} + + +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" = { type = "A", ttl = 300, records = [ + "199.36.153.8", "199.36.153.9", "199.36.153.10", "199.36.153.11" + ] } + "A restricted" = { type = "A", ttl = 300, records = [ + "199.36.153.4", "199.36.153.5", "199.36.153.6", "199.36.153.7" + ] } + "CNAME *" = { type = "CNAME", ttl = 300, records = ["private.googleapis.com."] } + } +} diff --git a/fast/stages/02-networking-separate-envs/main.tf b/fast/stages/02-networking-separate-envs/main.tf new file mode 100644 index 00000000..0b901e33 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/main.tf @@ -0,0 +1,58 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Networking folder and hierarchical policy. + +locals { + custom_roles = coalesce(var.custom_roles, {}) + l7ilb_subnets = { + for env, v in var.l7ilb_subnets : env => [ + for s in v : merge(s, { + active = true + name = "${env}-l7ilb-${s.region}" + })] + } + region_trigram = { + europe-west1 = "ew1" + europe-west3 = "ew3" + } + stage3_sas_delegated_grants = [ + "roles/composer.sharedVpcAgent", + "roles/compute.networkUser", + "roles/container.hostServiceAgentUser", + "roles/vpcaccess.user", + ] + service_accounts = { + for k, v in coalesce(var.service_accounts, {}) : k => "serviceAccount:${v}" if v != null + } +} + +module "folder" { + source = "../../../modules/folder" + parent = "organizations/${var.organization.id}" + name = "Networking" + folder_create = var.folder_ids.networking == null + id = var.folder_ids.networking + firewall_policy_factory = { + cidr_file = "${var.data_dir}/cidrs.yaml" + policy_name = null + rules_file = "${var.data_dir}/hierarchical-policy-rules.yaml" + } + firewall_policy_association = { + factory-policy = "factory" + } +} + diff --git a/fast/stages/02-networking-separate-envs/monitoring.tf b/fast/stages/02-networking-separate-envs/monitoring.tf new file mode 100644 index 00000000..463c6a08 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/monitoring.tf @@ -0,0 +1,38 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Network monitoring dashboards. + +locals { + dashboard_path = "${var.data_dir}/dashboards" + dashboard_files = fileset(local.dashboard_path, "*.json") + dashboards = { + for filename in local.dashboard_files : + filename => "${local.dashboard_path}/${filename}" + } +} + +resource "google_monitoring_dashboard" "dev-dashboard" { + for_each = local.dashboards + project = module.dev-spoke-project.project_id + dashboard_json = file(each.value) +} + +resource "google_monitoring_dashboard" "prod-dashboard" { + for_each = local.dashboards + project = module.prod-spoke-project.project_id + dashboard_json = file(each.value) +} diff --git a/fast/stages/02-networking-separate-envs/outputs.tf b/fast/stages/02-networking-separate-envs/outputs.tf new file mode 100644 index 00000000..2432cdcd --- /dev/null +++ b/fast/stages/02-networking-separate-envs/outputs.tf @@ -0,0 +1,102 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + host_project_ids = { + dev-spoke-0 = module.dev-spoke-project.project_id + prod-spoke-0 = module.prod-spoke-project.project_id + } + host_project_numbers = { + dev-spoke-0 = module.dev-spoke-project.number + prod-spoke-0 = module.prod-spoke-project.number + } + subnet_self_links = { + dev-spoke-0 = module.dev-spoke-vpc.subnet_self_links + prod-spoke-0 = module.prod-spoke-vpc.subnet_self_links + } + tfvars = { + host_project_ids = local.host_project_ids + host_project_numbers = local.host_project_numbers + subnet_self_links = local.subnet_self_links + vpc_self_links = local.vpc_self_links + } + vpc_self_links = { + dev-spoke-0 = module.dev-spoke-vpc.self_link + prod-spoke-0 = module.prod-spoke-vpc.self_link + } +} + +# generate tfvars file for subsequent stages + +resource "local_file" "tfvars" { + for_each = var.outputs_location == null ? {} : { 1 = 1 } + file_permission = "0644" + filename = "${pathexpand(var.outputs_location)}/tfvars/02-networking.auto.tfvars.json" + content = jsonencode(local.tfvars) +} + +resource "google_storage_bucket_object" "tfvars" { + bucket = var.automation.outputs_bucket + name = "tfvars/02-networking.auto.tfvars.json" + content = jsonencode(local.tfvars) +} + +# outputs + +output "dev_cloud_dns_inbound_policy" { + description = "IP Addresses for Cloud DNS inbound policy for the dev environment." + value = [for s in module.dev-spoke-vpc.subnets : cidrhost(s.ip_cidr_range, 2)] +} + +output "prod_cloud_dns_inbound_policy" { + description = "IP Addresses for Cloud DNS inbound policy for the prod environment." + value = [for s in module.prod-spoke-vpc.subnets : cidrhost(s.ip_cidr_range, 2)] +} + +output "host_project_ids" { + description = "Network project ids." + value = local.host_project_ids +} + +output "host_project_numbers" { + description = "Network project numbers." + value = local.host_project_numbers +} + +output "shared_vpc_self_links" { + description = "Shared VPC host projects." + value = local.vpc_self_links +} + +output "vpn_gateway_endpoints" { + description = "External IP Addresses for the GCP VPN gateways." + value = local.enable_onprem_vpn == false ? null : { + dev-onprem-ew1 = { + for v in module.dev-to-onprem-ew1-vpn[0].gateway.vpn_interfaces : + v.id => v.ip_address + } + prod-onprem-ew1 = { + for v in module.prod-to-onprem-ew1-vpn[0].gateway.vpn_interfaces : + v.id => v.ip_address + } + } +} + +output "tfvars" { + description = "Terraform variables file for the following stages." + sensitive = true + value = local.tfvars +} diff --git a/fast/stages/02-networking-separate-envs/spoke-dev.tf b/fast/stages/02-networking-separate-envs/spoke-dev.tf new file mode 100644 index 00000000..94350d33 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/spoke-dev.tf @@ -0,0 +1,112 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Dev spoke VPC and related resources. + +module "dev-spoke-project" { + source = "../../../modules/project" + billing_account = var.billing_account.id + name = "dev-net-spoke-0" + parent = var.folder_ids.networking-dev + prefix = var.prefix + services = [ + "container.googleapis.com", + "compute.googleapis.com", + "dns.googleapis.com", + "iap.googleapis.com", + "networkmanagement.googleapis.com", + "servicenetworking.googleapis.com", + "stackdriver.googleapis.com", + ] + shared_vpc_host_config = { + enabled = true + service_projects = [] + } + iam = { + "roles/dns.admin" = compact([ + try(local.service_accounts.project-factory-dev, null) + ]) + } +} + +module "dev-spoke-vpc" { + source = "../../../modules/net-vpc" + project_id = module.dev-spoke-project.project_id + name = "dev-spoke-0" + mtu = 1500 + data_folder = "${var.data_dir}/subnets/dev" + psa_config = try(var.psa_ranges.dev, null) + subnets_proxy_only = local.l7ilb_subnets.dev + # set explicit routes for googleapis in case the default route is deleted + routes = { + private-googleapis = { + dest_range = "199.36.153.8/30" + priority = 1000 + tags = [] + next_hop_type = "gateway" + next_hop = "default-internet-gateway" + } + restricted-googleapis = { + dest_range = "199.36.153.4/30" + priority = 1000 + tags = [] + next_hop_type = "gateway" + next_hop = "default-internet-gateway" + } + } +} + +module "dev-spoke-firewall" { + source = "../../../modules/net-vpc-firewall" + project_id = module.dev-spoke-project.project_id + network = module.dev-spoke-vpc.name + admin_ranges = [] + http_source_ranges = [] + https_source_ranges = [] + ssh_source_ranges = [] + data_folder = "${var.data_dir}/firewall-rules/dev" + cidr_template_file = "${var.data_dir}/cidrs.yaml" +} + +module "dev-spoke-cloudnat" { + for_each = toset(values(module.dev-spoke-vpc.subnet_regions)) + source = "../../../modules/net-cloudnat" + project_id = module.dev-spoke-project.project_id + region = each.value + name = "dev-nat-${local.region_trigram[each.value]}" + router_create = true + router_network = module.dev-spoke-vpc.name + router_asn = 4200001024 + logging_filter = "ERRORS_ONLY" +} + +# Create delegated grants for stage3 service accounts +resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" { + project = module.dev-spoke-project.project_id + role = "roles/resourcemanager.projectIamAdmin" + members = compact([ + try(local.service_accounts.data-platform-dev, null), + try(local.service_accounts.project-factory-dev, null), + ]) + condition { + title = "dev_stage3_sa_delegated_grants" + description = "Development host project delegated grants." + expression = format( + "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])", + join(",", formatlist("'%s'", local.stage3_sas_delegated_grants)) + ) + } +} diff --git a/fast/stages/02-networking-separate-envs/spoke-prod.tf b/fast/stages/02-networking-separate-envs/spoke-prod.tf new file mode 100644 index 00000000..d1b692b5 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/spoke-prod.tf @@ -0,0 +1,112 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Production spoke VPC and related resources. + +module "prod-spoke-project" { + source = "../../../modules/project" + billing_account = var.billing_account.id + name = "prod-net-spoke-0" + parent = var.folder_ids.networking-prod + prefix = var.prefix + services = [ + "container.googleapis.com", + "compute.googleapis.com", + "dns.googleapis.com", + "iap.googleapis.com", + "networkmanagement.googleapis.com", + "servicenetworking.googleapis.com", + "stackdriver.googleapis.com", + ] + shared_vpc_host_config = { + enabled = true + service_projects = [] + } + iam = { + "roles/dns.admin" = compact([ + try(local.service_accounts.project-factory-prod, null) + ]) + } +} + +module "prod-spoke-vpc" { + source = "../../../modules/net-vpc" + project_id = module.prod-spoke-project.project_id + name = "prod-spoke-0" + mtu = 1500 + data_folder = "${var.data_dir}/subnets/prod" + psa_config = try(var.psa_ranges.prod, null) + subnets_proxy_only = local.l7ilb_subnets.prod + # set explicit routes for googleapis in case the default route is deleted + routes = { + private-googleapis = { + dest_range = "199.36.153.8/30" + priority = 1000 + tags = [] + next_hop_type = "gateway" + next_hop = "default-internet-gateway" + } + restricted-googleapis = { + dest_range = "199.36.153.4/30" + priority = 1000 + tags = [] + next_hop_type = "gateway" + next_hop = "default-internet-gateway" + } + } +} + +module "prod-spoke-firewall" { + source = "../../../modules/net-vpc-firewall" + project_id = module.prod-spoke-project.project_id + network = module.prod-spoke-vpc.name + admin_ranges = [] + http_source_ranges = [] + https_source_ranges = [] + ssh_source_ranges = [] + data_folder = "${var.data_dir}/firewall-rules/prod" + cidr_template_file = "${var.data_dir}/cidrs.yaml" +} + +module "prod-spoke-cloudnat" { + for_each = toset(values(module.prod-spoke-vpc.subnet_regions)) + source = "../../../modules/net-cloudnat" + project_id = module.prod-spoke-project.project_id + region = each.value + name = "prod-nat-${local.region_trigram[each.value]}" + router_create = true + router_network = module.prod-spoke-vpc.name + router_asn = 4200001024 + logging_filter = "ERRORS_ONLY" +} + +# Create delegated grants for stage3 service accounts +resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" { + project = module.prod-spoke-project.project_id + role = "roles/resourcemanager.projectIamAdmin" + members = compact([ + try(local.service_accounts.data-platform-prod, null), + try(local.service_accounts.project-factory-prod, null), + ]) + condition { + title = "prod_stage3_sa_delegated_grants" + description = "Production host project delegated grants." + expression = format( + "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])", + join(",", formatlist("'%s'", local.stage3_sas_delegated_grants)) + ) + } +} diff --git a/fast/stages/02-networking-separate-envs/test-resources.tf b/fast/stages/02-networking-separate-envs/test-resources.tf new file mode 100644 index 00000000..ae3ba90a --- /dev/null +++ b/fast/stages/02-networking-separate-envs/test-resources.tf @@ -0,0 +1,83 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Temporary instances for testing + +# module "test-vm-dev-0" { +# source = "../../../modules/compute-vm" +# project_id = module.dev-spoke-project.project_id +# zone = "europe-west1-b" +# name = "test-vm-0" +# network_interfaces = [{ +# network = module.dev-spoke-vpc.self_link +# # change the subnet name to match the values you are actually using +# subnetwork = module.dev-spoke-vpc.subnet_self_links["europe-west1/dev-default-ew1"] +# alias_ips = {} +# nat = false +# addresses = null +# }] +# tags = ["ssh"] +# service_account_create = true +# boot_disk = { +# image = "projects/debian-cloud/global/images/family/debian-10" +# type = "pd-balanced" +# size = 10 +# } +# options = { +# allow_stopping_for_update = true +# deletion_protection = false +# spot = true +# } +# metadata = { +# startup-script = < v.adv == null ? null : { + advertise_groups = [] + advertise_ip_ranges = { + for adv in(v.adv == null ? [] : v.adv.custom) : + var.custom_adv[adv] => adv + } + advertise_mode = try(v.adv.default, false) ? "DEFAULT" : "CUSTOM" + route_priority = null + } + } +} + +module "dev-to-onprem-ew1-vpn" { + count = local.enable_onprem_vpn ? 1 : 0 + source = "../../../modules/net-vpn-ha" + project_id = module.dev-spoke-project.project_id + network = module.dev-spoke-vpc.self_link + region = "europe-west1" + name = "vpn-to-onprem-ew1" + router_create = true + router_name = "dev-onprem-vpn-ew1" + router_asn = var.router_onprem_configs.dev-ew1.asn + peer_external_gateway = var.vpn_onprem_configs.dev-ew1.peer_external_gateway + tunnels = { + for t in var.vpn_onprem_configs.dev-ew1.tunnels : + "remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => { + bgp_peer = { + address = cidrhost(t.session_range, 1) + asn = t.peer_asn + } + bgp_peer_options = local.bgp_peer_options_onprem.dev-ew1 + bgp_session_range = "${cidrhost(t.session_range, 2)}/30" + ike_version = 2 + peer_external_gateway_interface = t.peer_external_gateway_interface + router = null + shared_secret = t.secret + vpn_gateway_interface = t.vpn_gateway_interface + } + } +} diff --git a/fast/stages/02-networking-separate-envs/vpn-onprem-prod.tf b/fast/stages/02-networking-separate-envs/vpn-onprem-prod.tf new file mode 100644 index 00000000..0a8e9655 --- /dev/null +++ b/fast/stages/02-networking-separate-envs/vpn-onprem-prod.tf @@ -0,0 +1,46 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description VPN between prod and onprem. + +module "prod-to-onprem-ew1-vpn" { + count = local.enable_onprem_vpn ? 1 : 0 + source = "../../../modules/net-vpn-ha" + project_id = module.prod-spoke-project.project_id + network = module.prod-spoke-vpc.self_link + region = "europe-west1" + name = "vpn-to-onprem-ew1" + router_create = true + router_name = "prod-onprem-vpn-ew1" + router_asn = var.router_onprem_configs.prod-ew1.asn + peer_external_gateway = var.vpn_onprem_configs.prod-ew1.peer_external_gateway + tunnels = { + for t in var.vpn_onprem_configs.prod-ew1.tunnels : + "remote-${t.vpn_gateway_interface}-${t.peer_external_gateway_interface}" => { + bgp_peer = { + address = cidrhost(t.session_range, 1) + asn = t.peer_asn + } + bgp_peer_options = local.bgp_peer_options_onprem.prod-ew1 + bgp_session_range = "${cidrhost(t.session_range, 2)}/30" + ike_version = 2 + peer_external_gateway_interface = t.peer_external_gateway_interface + router = null + shared_secret = t.secret + vpn_gateway_interface = t.vpn_gateway_interface + } + } +} diff --git a/tests/fast/stages/s02_networking_separate_envs/__init__.py b/tests/fast/stages/s02_networking_separate_envs/__init__.py new file mode 100644 index 00000000..6d6d1266 --- /dev/null +++ b/tests/fast/stages/s02_networking_separate_envs/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/fast/stages/s02_networking_separate_envs/fixture/main.tf b/tests/fast/stages/s02_networking_separate_envs/fixture/main.tf new file mode 100644 index 00000000..9ecef1ac --- /dev/null +++ b/tests/fast/stages/s02_networking_separate_envs/fixture/main.tf @@ -0,0 +1,47 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module "stage" { + source = "../../../../../fast/stages/02-networking-separate-envs" + data_dir = "../../../../../fast/stages/02-networking-separate-envs/data/" + automation = { + outputs_bucket = "test" + } + billing_account = { + id = "000000-111111-222222" + organization_id = 123456789012 + } + custom_roles = { + service_project_network_admin = "organizations/123456789012/roles/foo" + } + folder_ids = { + networking = null + networking-dev = null + networking-prod = null + } + service_accounts = { + data-platform-dev = "string" + data-platform-prod = "string" + project-factory-dev = "string" + project-factory-prod = "string" + } + organization = { + domain = "fast.example.com" + id = 123456789012 + customer_id = "C00000000" + } + prefix = "fast2" +} diff --git a/tests/fast/stages/s02_networking_separate_envs/test_plan.py b/tests/fast/stages/s02_networking_separate_envs/test_plan.py new file mode 100644 index 00000000..1e697dc9 --- /dev/null +++ b/tests/fast/stages/s02_networking_separate_envs/test_plan.py @@ -0,0 +1,20 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def test_counts(recursive_e2e_plan_runner): + "Test stage." + num_modules, num_resources = recursive_e2e_plan_runner() + # TODO: to re-enable per-module resource count check print _, then test + assert num_modules > 0 and num_resources > 0 \ No newline at end of file