Merge branch 'master' into 1849-implement-cloud-run-module-version-2
|
@ -39,7 +39,7 @@ examples/cloud-operations/adfs/ansible/vars/vars.yaml
|
|||
examples/cloud-operations/adfs/ansible/gssh.sh
|
||||
examples/cloud-operations/multi-cluster-mesh-gke-fleet-api/ansible/vars.yaml
|
||||
examples/cloud-operations/multi-cluster-mesh-gke-fleet-api/ansible/gssh.sh
|
||||
blueprints/cloud-operations/network-dashboard/cloud-function.zip
|
||||
blueprints/cloud-operations/network-quota-monitoring/cloud-function.zip
|
||||
blueprints/apigee/bigquery-analytics/bundle-export.zip
|
||||
blueprints/apigee/bigquery-analytics/bundle-gcs2bq.zip
|
||||
blueprints/apigee/bigquery-analytics/apiproxy.zip
|
||||
|
|
|
@ -5,11 +5,11 @@ This section provides **[networking blueprints](./networking/)** that implement
|
|||
Currently available blueprints:
|
||||
|
||||
- **apigee** - [Apigee Hybrid on GKE](./apigee/hybrid-gke/), [Apigee X analytics in BigQuery](./apigee/bigquery-analytics), [Apigee network patterns](./apigee/network-patterns/)
|
||||
- **cloud operations** - [Active Directory Federation Services](./cloud-operations/adfs), [Cloud Asset Inventory feeds for resource change tracking and remediation](./cloud-operations/asset-inventory-feed-remediation), [Fine-grained Cloud DNS IAM via Service Directory](./cloud-operations/dns-fine-grained-iam), [Cloud DNS & Shared VPC design](./cloud-operations/dns-shared-vpc), [Delegated Role Grants](./cloud-operations/iam-delegated-role-grants), [Networking Dashboard](./cloud-operations/network-dashboard), [Managing on-prem service account keys by uploading public keys](./cloud-operations/onprem-sa-key-management), [Compute Image builder with Hashicorp Packer](./cloud-operations/packer-image-builder), [Packer example](./cloud-operations/packer-image-builder/packer), [Compute Engine quota monitoring](./cloud-operations/quota-monitoring), [Scheduled Cloud Asset Inventory Export to Bigquery](./cloud-operations/scheduled-asset-inventory-export-bq), [Configuring workload identity federation with Terraform Cloud/Enterprise workflows](./cloud-operations/terraform-cloud-dynamic-credentials), [TCP healthcheck and restart for unmanaged GCE instances](./cloud-operations/unmanaged-instances-healthcheck), [Migrate for Compute Engine (v5) blueprints](./cloud-operations/vm-migration), [Configuring workload identity federation to access Google Cloud resources from apps running on Azure](./cloud-operations/workload-identity-federation)
|
||||
- **cloud operations** - [Active Directory Federation Services](./cloud-operations/adfs), [Cloud Asset Inventory feeds for resource change tracking and remediation](./cloud-operations/asset-inventory-feed-remediation), [Fine-grained Cloud DNS IAM via Service Directory](./cloud-operations/dns-fine-grained-iam), [Cloud DNS & Shared VPC design](./cloud-operations/dns-shared-vpc), [Delegated Role Grants](./cloud-operations/iam-delegated-role-grants), [Network Quota Monitoring](./cloud-operations/network-quota-monitoring), [Managing on-prem service account keys by uploading public keys](./cloud-operations/onprem-sa-key-management), [Compute Image builder with Hashicorp Packer](./cloud-operations/packer-image-builder), [Packer example](./cloud-operations/packer-image-builder/packer), [Compute Engine quota monitoring](./cloud-operations/compute-quota-monitoring), [Scheduled Cloud Asset Inventory Export to Bigquery](./cloud-operations/scheduled-asset-inventory-export-bq), [Configuring workload identity federation with Terraform Cloud/Enterprise workflows](./cloud-operations/terraform-cloud-dynamic-credentials), [TCP healthcheck and restart for unmanaged GCE instances](./cloud-operations/unmanaged-instances-healthcheck), [Migrate for Compute Engine (v5) blueprints](./cloud-operations/vm-migration), [Configuring workload identity federation to access Google Cloud resources from apps running on Azure](./cloud-operations/workload-identity-federation)
|
||||
- **data solutions** - [GCE and GCS CMEK via centralized Cloud KMS](./data-solutions/cmek-via-centralized-kms), [Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key](./data-solutions/composer-2), [Cloud SQL instance with multi-region read replicas](./data-solutions/cloudsql-multiregion), [Data Platform](./data-solutions/data-platform-foundations), [Minimal Data Platform](./data-solutions/data-platform-minimal), [Spinning up a foundation data pipeline on Google Cloud using Cloud Storage, Dataflow and BigQuery](./data-solutions/gcs-to-bq-with-least-privileges), [#SQL Server Always On Groups blueprint](./data-solutions/sqlserver-alwayson), [Data Playground](./data-solutions/data-playground), [MLOps with Vertex AI](./data-solutions/vertex-mlops), [Shielded Folder](./data-solutions/shielded-folder), [BigQuery ML and Vertex AI Pipeline](./data-solutions/bq-ml)
|
||||
- **factories** - [The why and the how of Resource Factories](./factories), [Google Cloud Identity Group Factory](./factories/cloud-identity-group-factory), [Google Cloud BQ Factory](./factories/bigquery-factory), [Google Cloud VPC Firewall Factory](./factories/net-vpc-firewall-yaml), [Minimal Project Factory](./factories/project-factory)
|
||||
- **GKE** - [Binary Authorization Pipeline Blueprint](./gke/binauthz), [Storage API](./gke/binauthz/image), [Multi-cluster mesh on GKE (fleet API)](./gke/multi-cluster-mesh-gke-fleet-api), [GKE Multitenant Blueprint](./gke/multitenant-fleet), [Shared VPC with GKE support](./networking/shared-vpc-gke/), [GKE Autopilot](./gke/autopilot)
|
||||
- **networking** - [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [HA VPN over Interconnect](./networking/ha-vpn-over-interconnect/), [GLB and multi-regional daisy-chaining through hybrid NEGs](./networking/glb-hybrid-neg-internal), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), On-prem DNS and Google Private Access, [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke)
|
||||
- **networking** - [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [HA VPN over Interconnect](./networking/ha-vpn-over-interconnect/), [GLB and multi-regional daisy-chaining through hybrid NEGs](./networking/glb-hybrid-neg-internal), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), On-prem DNS and Google Private Access, [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke), [VPC Connectivity Lab](./networking/vpc-connectivity-lab/)
|
||||
- **serverless** - [Cloud Run series](./serverless/cloud-run-explore)
|
||||
- **third party solutions** - [OpenShift on GCP user-provisioned infrastructure](./third-party-solutions/openshift), [Wordpress deployment on Cloud Run](./third-party-solutions/wordpress/cloudrun)
|
||||
|
||||
|
|
|
@ -16,6 +16,12 @@ The blueprint's feed tracks changes to Google Compute instances, and the Cloud F
|
|||
|
||||
<br clear="left">
|
||||
|
||||
## Compute Engine quota monitoring
|
||||
|
||||
<a href="./compute-quota-monitoring" title="Compute Engine quota monitoring"><img src="./compute-quota-monitoring/diagram.png" align="left" width="280px"></a> This [blueprint](./compute-quota-monitoring) shows a practical way of collecting and monitoring [Compute Engine resource quotas](https://cloud.google.com/compute/quotas) via Cloud Monitoring metrics as an alternative to the recently released [built-in quota metrics](https://cloud.google.com/monitoring/alerts/using-quota-metrics). A simple alert on quota thresholds is also part of the blueprint.
|
||||
|
||||
<br clear="left">
|
||||
|
||||
## Granular Cloud DNS IAM via Service Directory
|
||||
|
||||
<a href="./dns-fine-grained-iam" title="Fine-grained Cloud DNS IAM with Service Directory"><img src="./dns-fine-grained-iam/diagram.png" align="left" width="280px"></a> This [blueprint](./dns-fine-grained-iam) shows how to leverage [Service Directory](https://cloud.google.com/blog/products/networking/introducing-service-directory) and Cloud DNS Service Directory private zones, to implement fine-grained IAM controls on DNS. The blueprint creates a Service Directory namespace, a Cloud DNS private zone that uses it as its authoritative source, service accounts with different levels of permissions, and VMs to test them.
|
||||
|
@ -34,9 +40,9 @@ The blueprint's feed tracks changes to Google Compute instances, and the Cloud F
|
|||
|
||||
<br clear="left">
|
||||
|
||||
## Network Dashboard
|
||||
## Network Quota Monitoring
|
||||
|
||||
<a href="./network-dashboard" title="Network Dashboard"><img src="./network-dashboard/metric.png" align="left" width="280px"></a> This [blueprint](./network-dashboard/) provides an end-to-end solution to gather some GCP Networking quotas and limits (that cannot be seen in the GCP console today) and display them in a dashboard. The goal is to allow for better visibility of these limits, facilitating capacity planning and avoiding hitting these limits..
|
||||
<a href="./network-quota-monitoring" title="Network Quota Monitoring"><img src="./network-quota-monitoring/metric.png" align="left" width="280px"></a> This [blueprint](./network-quota-monitoring) provides an end-to-end solution to gather some GCP Networking quotas and limits (that cannot be seen in the GCP console today) and display them in a dashboard. The goal is to allow for better visibility of these limits, facilitating capacity planning and avoiding hitting these limits.
|
||||
|
||||
<br clear="left">
|
||||
|
||||
|
@ -52,12 +58,6 @@ This [blueprint](./onprem-sa-key-management) shows how to manage IAM Service Acc
|
|||
|
||||
<br clear="left">
|
||||
|
||||
## Compute Engine quota monitoring
|
||||
|
||||
<a href="./quota-monitoring" title="Compute Engine quota monitoring"><img src="./quota-monitoring/diagram.png" align="left" width="280px"></a> This [blueprint](./quota-monitoring) shows a practical way of collecting and monitoring [Compute Engine resource quotas](https://cloud.google.com/compute/quotas) via Cloud Monitoring metrics as an alternative to the recently released [built-in quota metrics](https://cloud.google.com/monitoring/alerts/using-quota-metrics). A simple alert on quota thresholds is also part of the blueprint.
|
||||
|
||||
<br clear="left">
|
||||
|
||||
## Scheduled Cloud Asset Inventory Export to Bigquery
|
||||
|
||||
<a href="./scheduled-asset-inventory-export-bq" title="Scheduled Cloud Asset Inventory Export to Bigquery"><img src="./scheduled-asset-inventory-export-bq/diagram.png" align="left" width="280px"></a> This [blueprint](./scheduled-asset-inventory-export-bq) shows how to leverage the [Cloud Asset Inventory Exporting to Bigquery](https://cloud.google.com/asset-inventory/docs/exporting-to-bigquery) feature, to keep track of your organization's assets over time storing information in Bigquery. Data stored in Bigquery can then be used for different purposes like dashboarding or analysis.
|
||||
|
|
|
@ -72,7 +72,7 @@ Clone this repository or [open it in cloud shell](https://ssh.cloud.google.com/c
|
|||
|
||||
```hcl
|
||||
module "test" {
|
||||
source = "./fabric/blueprints/cloud-operations/quota-monitoring"
|
||||
source = "./fabric/blueprints/cloud-operations/compute-quota-monitoring"
|
||||
name = "name"
|
||||
project_id = "test"
|
||||
project_create_config = {
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
|
@ -1,4 +1,4 @@
|
|||
# Network Dashboard and Discovery Tool
|
||||
# Network Quota Monitoring
|
||||
|
||||
This repository provides an end-to-end solution to gather some GCP networking quotas, limits, and their corresponding usage, store them in Cloud Operations timeseries which can displayed in one or more dashboards or wired to alerts.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# Network Dashboard Discovery via Cloud Function
|
||||
# Network Quota Monitoring via Cloud Function
|
||||
|
||||
This simple Terraform setup allows deploying the [discovery tool for the Network Dashboard](../src/) to a Cloud Function, triggered by a schedule via PubSub.
|
||||
|
||||
|
@ -53,7 +53,7 @@ tf output -raw troubleshooting_payload
|
|||
|
||||
## Monitoring dashboard
|
||||
|
||||
A monitoring dashboard can be optionally be deployed int he same project by setting the `dashboard_json_path` variable to the path of a dashboard JSON file. A sample dashboard is in included, and can be deployed with this variable configuration:
|
||||
A monitoring dashboard can be optionally be deployed int the same project by setting the `dashboard_json_path` variable to the path of a dashboard JSON file. A sample dashboard is in included, and can be deployed with this variable configuration:
|
||||
|
||||
```tfvars
|
||||
dashboard_json_path = "../dashboards/quotas-utilization.json"
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
|
@ -1,8 +1,8 @@
|
|||
# Network Dashboard Discovery Tool
|
||||
# Network Quota Monitoring Tool
|
||||
|
||||
This tool constitutes the discovery and data gathering side of the Network Dashboard, and can be used in combination with the related [Terraform deployment examples](../), or packaged in different ways including standalone manual use.
|
||||
|
||||
- [Network Dashboard Discovery Tool](#network-dashboard-discovery-tool)
|
||||
- [Network Quota Monitoring Tool](#network-dashboard-discovery-tool)
|
||||
- [Quick Usage Example](#quick-usage-example)
|
||||
- [High Level Architecture and Plugin Design](#high-level-architecture-and-plugin-design)
|
||||
- [Debugging and Troubleshooting](#debugging-and-troubleshooting)
|
|
@ -96,3 +96,9 @@ It is meant to be used as a starting point for most Shared VPC configurations, a
|
|||
It is meant to be used as a starting point for users that want to explore PSC to reduce some of the complexity in their network setup.
|
||||
|
||||
<br clear="left">
|
||||
|
||||
### VPC Connectivity Lab
|
||||
|
||||
<a href="./vpc-connectivity-lab/" title="VPC Connectivity Lab"><img src="./vpc-connectivity-lab/diagram.png" align="left" width="280px"></a> This [blueprint](./vpc-connectivity-lab/) creates a networking playground showing a number of different VPC connectivity options (peering, HA VPN, NVA), along with PBR routing.
|
||||
|
||||
<br clear="left">
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
# VPC Connectivity Lab
|
||||
|
||||
This blueprint creates a networking playground showing a number of different VPC connectivity options:
|
||||
|
||||
* Hub and spoke via HA VPN
|
||||
* Hub and spoke via VPC peering
|
||||
* Interconnecting two networks via a network virtual appliance (aka NVA)
|
||||
|
||||
On top of that, this blueprint implements Policy Based Routing (aka PBR) to show how to force all traffic within a VPC to be funneled through an internal network passthrough load balancer, to implement an Intrusion Prevention System (IPS). PBR is enabled in the `hub` VPC, matching all traffic originating from within that VPC.
|
||||
|
||||
The blueprint has been purposefully kept simple to show how to use and wire VPCs together, and so that it can be used as a basis for experimentation.
|
||||
|
||||
This is the high level diagram of this blueprint:
|
||||
|
||||
![High-level diagram](diagram.png "High-level diagram")
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This blueprint is contained within a single project to keep complexity to a minimum, even though in a real world scenario each spoke would probably use a separate project.
|
||||
|
||||
The blueprint can either create a new project or consume an existing one.
|
||||
If the variable `var.project_create_config` is populated, the blueprint will create a new project named `var.project_id`, otherwise the blueprint will use an existing project with the same id.
|
||||
|
||||
## Testing reachability
|
||||
|
||||
After running terraform, and in case `var.test_vms` is set to true (as it is by default), a set of ping commands will be printed to check the reachability of all VMs. The blueprint is configured to ensure that all VMs can ping each other - so you can simply SSH to each one, and run the generated ping commands, e.g.:
|
||||
|
||||
```bash
|
||||
ping -c 1 ext.example
|
||||
ping -c 1 hub-a.example
|
||||
ping -c 1 hub-b.example
|
||||
ping -c 1 spoke-peering-a.example
|
||||
ping -c 1 spoke-peering-b.example
|
||||
ping -c 1 spoke-vpn-a.example
|
||||
ping -c 1 spoke-vpn-b.example
|
||||
```
|
||||
|
||||
## Testing IPS/NVA
|
||||
|
||||
Per blueprint setup, not all traffic will flow through the deployed test NVAs.
|
||||
You should expect the following flows to be routed through them:
|
||||
|
||||
* `ext` to {`hub`, `peering-a`, `peering-b`, `vpn-a`, `vpn-b`}
|
||||
* `peering-a` to {`ext`, `peering-b`}
|
||||
* `peering-b` to {`ext`, `peering-a`}
|
||||
* `vpn-a` to {`ext`}
|
||||
* `vpn-b` to {`ext`}
|
||||
|
||||
Additional PBR routes could be configured to force all traffic coming from `vpn-{a,b}` to go through the NVA - however traffic coming from `peering-{a,b}` can NOT be subjected to PBR routes, due to product constrains.
|
||||
|
||||
In order to see the actual traffic flow, you'll want to manually stop one of the NVA instances (to force all traffic to be sent through a single VM), SSH to the active NVA instance and run the following commands:
|
||||
|
||||
```bash
|
||||
# Setting the toolbox up might take a while since we're using cheap instances :)
|
||||
$ toolbox
|
||||
|
||||
# Once inside the toolbox
|
||||
$ tcpdump -i any icmp -n
|
||||
|
||||
```
|
||||
|
||||
<!-- TFDOC OPTS files:1 -->
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Files
|
||||
|
||||
| name | description | modules | resources |
|
||||
|---|---|---|---|
|
||||
| [dns-hub.tf](./dns-hub.tf) | DNS setup. | <code>dns</code> | |
|
||||
| [main.tf](./main.tf) | Project setup. | <code>project</code> | |
|
||||
| [nva.tf](./nva.tf) | None | <code>compute-vm</code> · <code>simple-nva</code> | <code>google_compute_instance_group</code> |
|
||||
| [outputs.tf](./outputs.tf) | Module outputs. | | |
|
||||
| [test-resources.tf](./test-resources.tf) | None | | |
|
||||
| [variables.tf](./variables.tf) | Module variables. | | |
|
||||
| [vpc-ext.tf](./vpc-ext.tf) | External VPC. | <code>net-address</code> · <code>net-cloudnat</code> · <code>net-lb-int</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> | <code>google_compute_route</code> |
|
||||
| [vpc-hub.tf](./vpc-hub.tf) | Internal Hub VPC. | <code>net-address</code> · <code>net-lb-int</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpc-peering</code> · <code>net-vpn-ha</code> | <code>google_compute_route</code> |
|
||||
| [vpc-peering-a.tf](./vpc-peering-a.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> | |
|
||||
| [vpc-peering-b.tf](./vpc-peering-b.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> | |
|
||||
| [vpc-vpn-a.tf](./vpc-vpn-a.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpn-ha</code> | |
|
||||
| [vpc-vpn-b.tf](./vpc-vpn-b.tf) | None | <code>net-vpc</code> · <code>net-vpc-firewall</code> · <code>net-vpn-ha</code> | |
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [prefix](variables.tf#L37) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [ip_ranges](variables.tf#L17) | Subnet/Routes IP CIDR ranges. | <code>map(string)</code> | | <code title="{ ext = "10.255.0.0/16" hub-a = "10.0.1.0/24" hub-all = "10.0.0.0/16" hub-b = "10.0.2.0/24" hub-nva = "10.0.0.0/24" int = "10.0.0.0/9" peering-a = "10.3.0.0/24" peering-b = "10.4.0.0/24" rfc1918_10 = "10.0.0.0/8" rfc1918_172 = "172.16.0.0/12" rfc1918_192 = "192.168.0.0/16" vpn-a = "10.1.0.0/24" vpn-b = "10.2.0.0/24" }">{…}</code> |
|
||||
| [project_create_config](variables.tf#L46) | Populate with billing account id to trigger project creation. | <code title="object({ billing_account_id = string parent_id = string })">object({…})</code> | | <code>null</code> |
|
||||
| [project_id](variables.tf#L55) | Project id for all resources. | <code>string</code> | | <code>"net-test-02"</code> |
|
||||
| [region](variables.tf#L61) | Region used to deploy resources. | <code>string</code> | | <code>"europe-west8"</code> |
|
||||
| [test_vms](variables.tf#L67) | Enable the creation of test resources. | <code>bool</code> | | <code>true</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [ping_commands](outputs.tf#L17) | Ping commands that can be run to check VPC reachability. | |
|
||||
<!-- END TFDOC -->
|
||||
## Test
|
||||
|
||||
```hcl
|
||||
module "test" {
|
||||
source = "./fabric/blueprints/networking/vpc-connectivity-lab"
|
||||
project_create_config = {
|
||||
billing_account_id = "123456-123456-123456"
|
||||
parent_id = "folders/123456789"
|
||||
}
|
||||
project_id = "net-test-04"
|
||||
prefix = "fast-sr0-sbox"
|
||||
}
|
||||
|
||||
# tftest modules=35 resources=131
|
||||
```
|
After Width: | Height: | Size: 272 KiB |
After Width: | Height: | Size: 196 KiB |
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Copyright 2023 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 DNS setup.
|
||||
|
||||
module "hub-dns" {
|
||||
source = "../../../modules/dns"
|
||||
project_id = module.project.project_id
|
||||
name = "${var.prefix}-example"
|
||||
zone_config = {
|
||||
domain = "example."
|
||||
private = {
|
||||
client_networks = [
|
||||
module.hub-vpc.self_link,
|
||||
module.ext-vpc.self_link,
|
||||
module.spoke-peering-a-vpc.self_link,
|
||||
module.spoke-peering-b-vpc.self_link,
|
||||
module.spoke-vpn-a-vpc.self_link,
|
||||
module.spoke-vpn-b-vpc.self_link,
|
||||
]
|
||||
}
|
||||
}
|
||||
recordsets = merge({
|
||||
"A localhost" = { records = ["127.0.0.1"] }
|
||||
},
|
||||
var.test_vms
|
||||
? { for instance, _ in local.test-vms : "A ${instance}" => { records = [module.test-vms[instance].internal_ip] } }
|
||||
: {})
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Copyright 2023 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 Project setup.
|
||||
|
||||
module "project" {
|
||||
source = "../../../modules/project"
|
||||
name = var.project_id
|
||||
parent = try(var.project_create_config.parent_id, null)
|
||||
billing_account = try(var.project_create_config.billing_account_id, null)
|
||||
project_create = try(var.project_create_config.billing_account_id, null) != null
|
||||
prefix = var.prefix
|
||||
services = [
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"networkconnectivity.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* Copyright 2023 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 {
|
||||
network_interfaces = [
|
||||
{
|
||||
addresses = null
|
||||
name = "ext"
|
||||
nat = false
|
||||
enable_masquerading = true
|
||||
network = module.ext-vpc.self_link
|
||||
routes = [var.ip_ranges.ext, "0.0.0.0/0"]
|
||||
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
|
||||
},
|
||||
{
|
||||
addresses = null
|
||||
name = "hub"
|
||||
nat = false
|
||||
network = module.hub-vpc.self_link
|
||||
routes = [var.ip_ranges.int]
|
||||
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-nva"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
module "cos-nva" {
|
||||
source = "../../../modules/cloud-config-container/simple-nva"
|
||||
enable_health_checks = true
|
||||
network_interfaces = local.network_interfaces
|
||||
}
|
||||
|
||||
module "nva-a" {
|
||||
source = "../../../modules/compute-vm"
|
||||
project_id = module.project.project_id
|
||||
zone = "${var.region}-a"
|
||||
name = "cos-nva-a"
|
||||
network_interfaces = local.network_interfaces
|
||||
can_ip_forward = true
|
||||
instance_type = "e2-micro"
|
||||
options = {
|
||||
spot = true
|
||||
termination_action = "STOP"
|
||||
}
|
||||
metadata = {
|
||||
user-data = module.cos-nva.cloud_config
|
||||
google-logging-enabled = true
|
||||
}
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
type = "pd-ssd"
|
||||
size = 10
|
||||
}
|
||||
}
|
||||
tags = ["nva", "ssh"]
|
||||
}
|
||||
|
||||
module "nva-b" {
|
||||
source = "../../../modules/compute-vm"
|
||||
project_id = module.project.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "cos-nva-b"
|
||||
network_interfaces = local.network_interfaces
|
||||
can_ip_forward = true
|
||||
instance_type = "e2-micro"
|
||||
options = {
|
||||
spot = true
|
||||
termination_action = "STOP"
|
||||
}
|
||||
metadata = {
|
||||
user-data = module.cos-nva.cloud_config
|
||||
google-logging-enabled = true
|
||||
}
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
image = "projects/cos-cloud/global/images/family/cos-stable"
|
||||
type = "pd-ssd"
|
||||
size = 10
|
||||
}
|
||||
}
|
||||
tags = ["nva", "ssh"]
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group" "nva-a" {
|
||||
name = "nva-ig-a"
|
||||
description = "NVA instance group for the primary region, zone a."
|
||||
zone = "${var.region}-a"
|
||||
project = module.project.project_id
|
||||
network = module.ext-vpc.self_link
|
||||
instances = toset([
|
||||
module.nva-a.self_link,
|
||||
])
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group" "nva-b" {
|
||||
name = "nva-ig-b"
|
||||
description = "NVA instance group for the primary region, zone b."
|
||||
zone = "${var.region}-b"
|
||||
project = module.project.project_id
|
||||
network = module.ext-vpc.self_link
|
||||
instances = toset([
|
||||
module.nva-b.self_link,
|
||||
])
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
output "ping_commands" {
|
||||
description = "Ping commands that can be run to check VPC reachability."
|
||||
value = var.test_vms ? join("\n", [for instance, _ in local.test-vms : "ping -c 1 ${instance}.example"]) : ""
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* Copyright 2023 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 {
|
||||
test-vms = {
|
||||
ext = {
|
||||
network = module.ext-vpc.self_link
|
||||
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
|
||||
}
|
||||
hub-a = {
|
||||
network = module.hub-vpc.self_link
|
||||
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-a"]
|
||||
}
|
||||
hub-b = {
|
||||
network = module.hub-vpc.self_link
|
||||
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-b"]
|
||||
}
|
||||
spoke-vpn-a = {
|
||||
network = module.spoke-vpn-a-vpc.self_link
|
||||
subnetwork = module.spoke-vpn-a-vpc.subnet_self_links["${var.region}/vpn-a"]
|
||||
},
|
||||
spoke-peering-a = {
|
||||
network = module.spoke-peering-a-vpc.self_link
|
||||
subnetwork = module.spoke-peering-a-vpc.subnet_self_links["${var.region}/peering-a"]
|
||||
},
|
||||
spoke-vpn-b = {
|
||||
network = module.spoke-vpn-b-vpc.self_link
|
||||
subnetwork = module.spoke-vpn-b-vpc.subnet_self_links["${var.region}/vpn-b"]
|
||||
},
|
||||
spoke-peering-b = {
|
||||
network = module.spoke-peering-b-vpc.self_link
|
||||
subnetwork = module.spoke-peering-b-vpc.subnet_self_links["${var.region}/peering-b"]
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
module "test-vms" {
|
||||
for_each = var.test_vms ? local.test-vms : {}
|
||||
source = "../../../modules/compute-vm"
|
||||
project_id = module.project.project_id
|
||||
zone = "${var.region}-a"
|
||||
name = "test-vm-${each.key}"
|
||||
network_interfaces = [{
|
||||
network = each.value.network
|
||||
# change the subnet name to match the values you are actually using
|
||||
subnetwork = each.value.subnetwork
|
||||
}]
|
||||
instance_type = "e2-micro"
|
||||
tags = ["ssh"]
|
||||
boot_disk = {
|
||||
initialize_params = {
|
||||
image = "projects/debian-cloud/global/images/family/debian-11"
|
||||
}
|
||||
}
|
||||
options = {
|
||||
spot = true
|
||||
termination_action = "STOP"
|
||||
}
|
||||
metadata = {
|
||||
startup-script = <<EOF
|
||||
export DEB_VERSION=`lsb_release -c | awk '{print $2}'`
|
||||
echo "deb https://packages.cloud.google.com/mirror/cloud-apt/$DEB_VERSION $DEB_VERSION main" > /etc/apt/sources.list
|
||||
echo "deb https://packages.cloud.google.com/mirror/cloud-apt/$DEB_VERSION-security $DEB_VERSION-security main" >> /etc/apt/sources.list
|
||||
echo "deb https://packages.cloud.google.com/mirror/cloud-apt/$DEB_VERSION-updates $DEB_VERSION-updates main" >> /etc/apt/sources.list
|
||||
apt update
|
||||
apt install -y iputils-ping bind9-dnsutils
|
||||
EOF
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* Copyright 2023 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.
|
||||
*/
|
||||
|
||||
variable "ip_ranges" {
|
||||
description = "Subnet/Routes IP CIDR ranges."
|
||||
type = map(string)
|
||||
default = {
|
||||
ext = "10.255.0.0/16"
|
||||
hub-a = "10.0.1.0/24"
|
||||
hub-all = "10.0.0.0/16"
|
||||
hub-b = "10.0.2.0/24"
|
||||
hub-nva = "10.0.0.0/24"
|
||||
int = "10.0.0.0/9"
|
||||
peering-a = "10.3.0.0/24"
|
||||
peering-b = "10.4.0.0/24"
|
||||
rfc1918_10 = "10.0.0.0/8"
|
||||
rfc1918_172 = "172.16.0.0/12"
|
||||
rfc1918_192 = "192.168.0.0/16"
|
||||
vpn-a = "10.1.0.0/24"
|
||||
vpn-b = "10.2.0.0/24"
|
||||
}
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create_config" {
|
||||
description = "Populate with billing account id to trigger project creation."
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent_id = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project id for all resources."
|
||||
type = string
|
||||
default = "net-test-02"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region used to deploy resources."
|
||||
type = string
|
||||
default = "europe-west8"
|
||||
}
|
||||
|
||||
variable "test_vms" {
|
||||
description = "Enable the creation of test resources."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* Copyright 2023 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 External VPC.
|
||||
|
||||
module "ext-vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "ext"
|
||||
mtu = 1500
|
||||
subnets = [
|
||||
{
|
||||
name = "ext"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.ext
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
module "nat" {
|
||||
source = "../../../modules/net-cloudnat"
|
||||
project_id = module.project.project_id
|
||||
router_network = module.ext-vpc.name
|
||||
region = var.region
|
||||
name = "default"
|
||||
}
|
||||
|
||||
module "ext-firewall" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.ext-vpc.name
|
||||
default_rules_config = {
|
||||
admin_ranges = [var.ip_ranges.rfc1918_10]
|
||||
ssh_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_route" "ext-rfc1918-10" {
|
||||
project = module.project.project_id
|
||||
network = module.ext-vpc.name
|
||||
name = "ext-rfc1918-10"
|
||||
description = "Terraform-managed."
|
||||
dest_range = var.ip_ranges.rfc1918_10
|
||||
priority = 1000
|
||||
next_hop_ilb = module.ext-lb.forwarding_rule_self_links[""]
|
||||
}
|
||||
|
||||
module "ext-addresses" {
|
||||
source = "../../../modules/net-address"
|
||||
project_id = module.project.project_id
|
||||
internal_addresses = {
|
||||
ext = {
|
||||
region = var.region
|
||||
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
|
||||
address = cidrhost(module.ext-vpc.subnet_ips["${var.region}/ext"], -3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "ext-lb" {
|
||||
source = "../../../modules/net-lb-int"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
name = "ext-lb"
|
||||
vpc_config = {
|
||||
network = module.ext-vpc.name
|
||||
subnetwork = module.ext-vpc.subnet_self_links["${var.region}/ext"]
|
||||
}
|
||||
forwarding_rules_config = {
|
||||
"" = {
|
||||
global_access = false
|
||||
address = module.ext-addresses.internal_addresses["ext"].address
|
||||
}
|
||||
}
|
||||
backends = [
|
||||
{
|
||||
failover = false
|
||||
group = google_compute_instance_group.nva-a.id
|
||||
balancing_mode = "CONNECTION"
|
||||
},
|
||||
{
|
||||
failover = false
|
||||
group = google_compute_instance_group.nva-b.id
|
||||
balancing_mode = "CONNECTION"
|
||||
},
|
||||
]
|
||||
health_check_config = {
|
||||
tcp = {
|
||||
port = 22
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
/**
|
||||
* Copyright 2023 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 Internal Hub VPC.
|
||||
|
||||
module "hub-vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "hub"
|
||||
mtu = 1500
|
||||
subnets = [
|
||||
{
|
||||
name = "hub-nva"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.hub-nva
|
||||
},
|
||||
{
|
||||
name = "hub-a"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.hub-a
|
||||
},
|
||||
{
|
||||
name = "hub-b"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.hub-b
|
||||
},
|
||||
]
|
||||
policy_based_routes = {
|
||||
nva-skip = {
|
||||
use_default_routing = true
|
||||
priority = 100
|
||||
target = {
|
||||
tags = ["nva"]
|
||||
}
|
||||
}
|
||||
default-nva = {
|
||||
next_hop_ilb_ip = module.hub-lb.forwarding_rule_addresses[""]
|
||||
priority = 101
|
||||
filter = {
|
||||
src_range = var.ip_ranges.hub-all
|
||||
dest_range = "0.0.0.0/0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "hub-firewall" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.hub-vpc.name
|
||||
default_rules_config = {
|
||||
admin_ranges = [var.ip_ranges.rfc1918_10]
|
||||
ssh_ranges = ["35.235.240.0/20", "35.191.0.0/16", "130.211.0.0/22", "209.85.152.0/22", "209.85.204.0/22"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_route" "hub-0-0" {
|
||||
project = module.project.project_id
|
||||
network = module.hub-vpc.name
|
||||
name = "hub-0-0"
|
||||
description = "Terraform-managed."
|
||||
dest_range = "0.0.0.0/0"
|
||||
priority = 1000
|
||||
next_hop_ilb = module.hub-lb.forwarding_rule_self_links[""]
|
||||
}
|
||||
|
||||
module "hub-addresses" {
|
||||
source = "../../../modules/net-address"
|
||||
project_id = module.project.project_id
|
||||
internal_addresses = {
|
||||
hub = {
|
||||
region = var.region
|
||||
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-nva"]
|
||||
address = cidrhost(module.hub-vpc.subnet_ips["${var.region}/hub-nva"], -3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "hub-lb" {
|
||||
source = "../../../modules/net-lb-int"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
name = "hub-lb"
|
||||
vpc_config = {
|
||||
network = module.hub-vpc.name
|
||||
subnetwork = module.hub-vpc.subnet_self_links["${var.region}/hub-nva"]
|
||||
}
|
||||
forwarding_rules_config = {
|
||||
"" = {
|
||||
global_access = false
|
||||
address = module.hub-addresses.internal_addresses["hub"].address
|
||||
}
|
||||
}
|
||||
|
||||
backends = [
|
||||
{
|
||||
failover = false
|
||||
group = google_compute_instance_group.nva-a.id
|
||||
balancing_mode = "CONNECTION"
|
||||
},
|
||||
{
|
||||
failover = false
|
||||
group = google_compute_instance_group.nva-b.id
|
||||
balancing_mode = "CONNECTION"
|
||||
},
|
||||
]
|
||||
health_check_config = {
|
||||
tcp = {
|
||||
port = 22
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module "vpn-hub-a" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
network = module.hub-vpc.self_link
|
||||
name = "hub-a"
|
||||
peer_gateways = {
|
||||
default = { gcp = module.vpn-a-hub.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = 64513
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"0.0.0.0/0" = "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
remote-0 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.2"
|
||||
asn = 64514
|
||||
}
|
||||
bgp_session_range = "169.254.1.1/30"
|
||||
shared_secret = module.vpn-a-hub.random_secret
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
remote-1 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.2"
|
||||
asn = 64514
|
||||
}
|
||||
bgp_session_range = "169.254.2.1/30"
|
||||
shared_secret = module.vpn-a-hub.random_secret
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "vpn-hub-b" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
network = module.hub-vpc.self_link
|
||||
name = "hub-b"
|
||||
peer_gateways = {
|
||||
default = { gcp = module.vpn-b-hub.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = 64513
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
"0.0.0.0/0" = "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
remote-0 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.6"
|
||||
asn = 64515
|
||||
}
|
||||
bgp_session_range = "169.254.1.5/30"
|
||||
shared_secret = module.vpn-b-hub.random_secret
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
remote-1 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.6"
|
||||
asn = 64515
|
||||
}
|
||||
bgp_session_range = "169.254.2.5/30"
|
||||
shared_secret = module.vpn-b-hub.random_secret
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "peering-hub-a" {
|
||||
source = "../../../modules/net-vpc-peering"
|
||||
prefix = "a"
|
||||
local_network = module.hub-vpc.id
|
||||
peer_network = module.spoke-peering-a-vpc.id
|
||||
}
|
||||
|
||||
module "peering-hub-b" {
|
||||
source = "../../../modules/net-vpc-peering"
|
||||
prefix = "b"
|
||||
local_network = module.hub-vpc.id
|
||||
peer_network = module.spoke-peering-b-vpc.id
|
||||
depends_on = [module.spoke-peering-a-vpc.id]
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Copyright 2023 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 "spoke-peering-a-vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "peering-a"
|
||||
mtu = 1500
|
||||
subnets = [
|
||||
{
|
||||
name = "peering-a"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.peering-a
|
||||
|
||||
}
|
||||
]
|
||||
routes = {
|
||||
default = {
|
||||
description = "Route to default."
|
||||
dest_range = "0.0.0.0/0"
|
||||
tags = null
|
||||
next_hop_type = "ilb"
|
||||
next_hop = module.hub-lb.forwarding_rule_addresses[""]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "peering-a-firewall" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.spoke-peering-a-vpc.name
|
||||
default_rules_config = {
|
||||
admin_ranges = [var.ip_ranges.rfc1918_10]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Copyright 2023 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 "spoke-peering-b-vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "peering-b"
|
||||
mtu = 1500
|
||||
subnets = [
|
||||
{
|
||||
name = "peering-b"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.peering-b
|
||||
}
|
||||
]
|
||||
routes = {
|
||||
default = {
|
||||
description = "Route to default."
|
||||
dest_range = "0.0.0.0/0"
|
||||
tags = null
|
||||
next_hop_type = "ilb"
|
||||
next_hop = module.hub-lb.forwarding_rule_addresses[""]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "peering-b-firewall" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.spoke-peering-b-vpc.name
|
||||
default_rules_config = {
|
||||
admin_ranges = [var.ip_ranges.rfc1918_10]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Copyright 2023 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 "spoke-vpn-a-vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "vpn-a"
|
||||
mtu = 1500
|
||||
subnets = [
|
||||
{
|
||||
name = "vpn-a"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.vpn-a
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
module "vpn-a-firewall" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.spoke-vpn-a-vpc.name
|
||||
default_rules_config = {
|
||||
admin_ranges = [var.ip_ranges.rfc1918_10]
|
||||
}
|
||||
}
|
||||
|
||||
module "vpn-a-hub" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
network = module.spoke-vpn-a-vpc.self_link
|
||||
name = "a-hub"
|
||||
peer_gateways = {
|
||||
default = { gcp = module.vpn-hub-a.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = 64514
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
(var.ip_ranges.vpn-a) = "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
remote-0 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.1.2/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
remote-1 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.1"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.2/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Copyright 2023 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 "spoke-vpn-b-vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "vpn-b"
|
||||
mtu = 1500
|
||||
subnets = [
|
||||
{
|
||||
name = "vpn-b"
|
||||
region = var.region
|
||||
ip_cidr_range = var.ip_ranges.vpn-b
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
module "vpn-b-firewall" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.spoke-vpn-b-vpc.name
|
||||
default_rules_config = {
|
||||
admin_ranges = [var.ip_ranges.rfc1918_10]
|
||||
}
|
||||
}
|
||||
|
||||
module "vpn-b-hub" {
|
||||
source = "../../../modules/net-vpn-ha"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
network = module.spoke-vpn-b-vpc.self_link
|
||||
name = "b-hub"
|
||||
peer_gateways = {
|
||||
default = { gcp = module.vpn-hub-b.self_link }
|
||||
}
|
||||
router_config = {
|
||||
asn = 64515
|
||||
custom_advertise = {
|
||||
all_subnets = false
|
||||
ip_ranges = {
|
||||
(var.ip_ranges.vpn-b) = "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
tunnels = {
|
||||
remote-0 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.1.5"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.1.6/30"
|
||||
vpn_gateway_interface = 0
|
||||
}
|
||||
remote-1 = {
|
||||
bgp_peer = {
|
||||
address = "169.254.2.5"
|
||||
asn = 64513
|
||||
}
|
||||
bgp_session_range = "169.254.2.6/30"
|
||||
vpn_gateway_interface = 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,11 +28,11 @@ env:
|
|||
FAST_SERVICE_ACCOUNT: ${service_account}
|
||||
FAST_WIF_PROVIDER: ${identity_provider}
|
||||
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||
%{~ if tf_providers_file != "" ~}
|
||||
TF_PROVIDERS_FILE: ${tf_providers_file}
|
||||
%{~ if tf_var_files != [] ~}
|
||||
TF_VAR_FILES: ${join("\n ", tf_var_files)}
|
||||
%{~ endif ~}
|
||||
TF_VAR_FILES: ${tf_var_files == [] ? "''" : join("\n ", tf_var_files)}
|
||||
TF_VERSION: 1.4.4
|
||||
TF_VERSION: 1.5.1
|
||||
|
||||
jobs:
|
||||
fast-pr:
|
||||
|
@ -57,7 +57,7 @@ jobs:
|
|||
# set up authentication via Workload identity Federation
|
||||
- id: gcp-auth
|
||||
name: Authenticate to Google Cloud
|
||||
uses: google-github-actions/auth@v0
|
||||
uses: google-github-actions/auth@v2
|
||||
with:
|
||||
workload_identity_provider: $${{ env.FAST_WIF_PROVIDER }}
|
||||
service_account: $${{ env.FAST_SERVICE_ACCOUNT }}
|
||||
|
@ -73,15 +73,15 @@ jobs:
|
|||
- id: tf-config
|
||||
name: Copy Terraform output files
|
||||
run: |
|
||||
%{~ if tf_providers_file != "" ~}
|
||||
gcloud alpha storage cp -r \
|
||||
"gs://$${{env.FAST_OUTPUTS_BUCKET}}/providers/$${{env.TF_PROVIDERS_FILE}}" ./
|
||||
%{~ endif ~}
|
||||
%{~ if tf_var_files != [] ~}
|
||||
gcloud alpha storage cp -r \
|
||||
"gs://$${{env.FAST_OUTPUTS_BUCKET}}/tfvars" ./
|
||||
for f in $${{env.TF_VAR_FILES}}; do
|
||||
ln -s "tfvars/$f" ./
|
||||
done
|
||||
%{~ endif ~}
|
||||
|
||||
- id: tf-setup
|
||||
name: Set up Terraform
|
||||
|
@ -97,8 +97,8 @@ jobs:
|
|||
terraform init -no-color
|
||||
|
||||
- id: tf-validate
|
||||
name: Terraform validate
|
||||
continue-on-error: true
|
||||
name: Terraform validate
|
||||
run: terraform validate -no-color
|
||||
|
||||
- id: tf-plan
|
||||
|
|
|
@ -29,8 +29,10 @@ env:
|
|||
FAST_WIF_PROVIDER: ${identity_provider}
|
||||
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||
TF_PROVIDERS_FILE: ${tf_providers_file}
|
||||
TF_VAR_FILES: ${tf_var_files == [] ? "''" : join("\n ", tf_var_files)}
|
||||
TF_VERSION: 1.4.4
|
||||
%{~ if tf_var_files != [] ~}
|
||||
TF_VAR_FILES: ${join("\n ", tf_var_files)}
|
||||
%{~ endif ~}
|
||||
TF_VERSION: 1.5.1
|
||||
|
||||
jobs:
|
||||
fast-pr:
|
||||
|
@ -55,7 +57,7 @@ jobs:
|
|||
# set up authentication via Workload identity Federation
|
||||
- id: gcp-auth
|
||||
name: Authenticate to Google Cloud
|
||||
uses: google-github-actions/auth@v0
|
||||
uses: google-github-actions/auth@v2
|
||||
with:
|
||||
workload_identity_provider: $${{ env.FAST_WIF_PROVIDER }}
|
||||
service_account: $${{ env.FAST_SERVICE_ACCOUNT }}
|
||||
|
@ -73,11 +75,13 @@ jobs:
|
|||
run: |
|
||||
gcloud alpha storage cp -r \
|
||||
"gs://$${{env.FAST_OUTPUTS_BUCKET}}/providers/$${{env.TF_PROVIDERS_FILE}}" ./
|
||||
%{~ if tf_var_files != [] ~}
|
||||
gcloud alpha storage cp -r \
|
||||
"gs://$${{env.FAST_OUTPUTS_BUCKET}}/tfvars" ./
|
||||
for f in $${{env.TF_VAR_FILES}}; do
|
||||
ln -s "tfvars/$f" ./
|
||||
done
|
||||
%{~ endif ~}
|
||||
|
||||
- id: tf-setup
|
||||
name: Set up Terraform
|
||||
|
@ -93,8 +97,8 @@ jobs:
|
|||
terraform init -no-color
|
||||
|
||||
- id: tf-validate
|
||||
name: Terraform validate
|
||||
continue-on-error: true
|
||||
name: Terraform validate
|
||||
run: terraform validate -no-color
|
||||
|
||||
- id: tf-plan
|
||||
|
|
|
@ -597,7 +597,7 @@ The `fast_features` variable consists of 4 toggles:
|
|||
| [organization](variables.tf#L235) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | |
|
||||
| [prefix](variables.tf#L250) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
|
||||
| [bootstrap_user](variables.tf#L27) | Email of the nominal user running this stage for the first time. | <code>string</code> | | <code>null</code> | |
|
||||
| [cicd_repositories](variables.tf#L33) | CI/CD repository configuration. Identity providers reference keys in the `federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object({ bootstrap = optional(object({ branch = string identity_provider = string name = string type = string })) resman = optional(object({ branch = string identity_provider = string name = string type = string })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [cicd_repositories](variables.tf#L33) | CI/CD repository configuration. Identity providers reference keys in the `federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object({ bootstrap = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) resman = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [custom_roles](variables.tf#L79) | Map of role names => list of permissions to additionally create at the organization level. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [factories_config](variables.tf#L86) | Configuration for the organization policies factory. | <code title="object({ custom_roles = optional(string, "data/custom-roles") org_policy = optional(string, "data/org-policies") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [fast_features](variables.tf#L96) | Selective control for top-level FAST features. | <code title="object({ data_platform = optional(bool, false) gke = optional(bool, false) project_factory = optional(bool, false) sandbox = optional(bool, false) teams = optional(bool, false) })">object({…})</code> | | <code>{}</code> | |
|
||||
|
|
|
@ -33,9 +33,10 @@ locals {
|
|||
"attribute.repository" = "assertion.repository"
|
||||
"attribute.repository_owner" = "assertion.repository_owner"
|
||||
"attribute.ref" = "assertion.ref"
|
||||
"attribute.fast_sub" = "\"repo:\" + assertion.repository + \":ref:\" + assertion.ref"
|
||||
}
|
||||
issuer_uri = "https://token.actions.githubusercontent.com"
|
||||
principal_tpl = "principal://iam.googleapis.com/%s/subject/repo:%s:ref:refs/heads/%s"
|
||||
principal_tpl = "principalSet://iam.googleapis.com/%s/attribute.fast_sub/repo:%s:ref:refs/heads/%s"
|
||||
principalset_tpl = "principalSet://iam.googleapis.com/%s/attribute.repository/%s"
|
||||
}
|
||||
# https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html#token-payload
|
||||
|
@ -89,7 +90,7 @@ resource "google_iam_workload_identity_pool_provider" "default" {
|
|||
? each.value.custom_settings.issuer_uri
|
||||
: try(each.value.issuer_uri, null)
|
||||
)
|
||||
# OIDC JWKs in JSON String format. If no value is provided, they key is
|
||||
# OIDC JWKs in JSON String format. If no value is provided, they key is
|
||||
# fetched from the `.well-known` path for the issuer_uri
|
||||
jwks_json = each.value.custom_settings.jwks_json
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ env:
|
|||
%{~ if tf_var_files != [] ~}
|
||||
TF_VAR_FILES: ${join("\n ", tf_var_files)}
|
||||
%{~ endif ~}
|
||||
TF_VERSION: 1.4.4
|
||||
TF_VERSION: 1.5.1
|
||||
|
||||
jobs:
|
||||
fast-pr:
|
||||
|
@ -47,19 +47,6 @@ jobs:
|
|||
name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# # Print JWT token payload, useful for debugging
|
||||
# - id: jwt-debug
|
||||
# name: Print GITHUB_TOKEN payload
|
||||
# shell: python -u {0}
|
||||
# run: |
|
||||
# import base64
|
||||
# import json
|
||||
#
|
||||
# token = '${{ secrets.GITHUB_TOKEN }}'
|
||||
# payload_text = token.split('.')[1]
|
||||
# payload = json.loads(base64.urlsafe_b64decode(payload_text + '=' * (4-len(payload_text) %4)))
|
||||
# print(json.dumps(payload, indent=2))
|
||||
|
||||
# set up SSH key authentication to the modules repository
|
||||
- id: ssh-config
|
||||
name: Configure SSH authentication
|
||||
|
|
|
@ -34,16 +34,16 @@ variable "cicd_repositories" {
|
|||
description = "CI/CD repository configuration. Identity providers reference keys in the `federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed."
|
||||
type = object({
|
||||
bootstrap = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
resman = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
|
|
|
@ -357,7 +357,7 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
|
|||
| [billing_account](variables.tf#L39) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | <code title="object({ id = string is_org_level = optional(bool, true) no_iam = optional(bool, false) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [organization](variables.tf#L198) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L214) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [cicd_repositories](variables.tf#L50) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object({ data_platform_dev = optional(object({ branch = string identity_provider = string name = string type = string })) data_platform_prod = optional(object({ branch = string identity_provider = string name = string type = string })) gke_dev = optional(object({ branch = string identity_provider = string name = string type = string })) gke_prod = optional(object({ branch = string identity_provider = string name = string type = string })) networking = optional(object({ branch = string identity_provider = string name = string type = string })) project_factory_dev = optional(object({ branch = string identity_provider = string name = string type = string })) project_factory_prod = optional(object({ branch = string identity_provider = string name = string type = string })) security = optional(object({ branch = string identity_provider = string name = string type = string })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [cicd_repositories](variables.tf#L50) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object({ data_platform_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) data_platform_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gke_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gke_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) networking = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) project_factory_prod = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) security = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [custom_roles](variables.tf#L132) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [fast_features](variables.tf#L141) | Selective control for top-level FAST features. | <code title="object({ data_platform = optional(bool, false) gke = optional(bool, false) project_factory = optional(bool, false) sandbox = optional(bool, false) teams = optional(bool, false) })">object({…})</code> | | <code>{}</code> | <code>0-0-bootstrap</code> |
|
||||
| [groups](variables.tf#L155) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | <code title="object({ gcp-devops = optional(string) gcp-network-admins = optional(string) gcp-security-admins = optional(string) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
|
|
|
@ -29,8 +29,10 @@ env:
|
|||
FAST_WIF_PROVIDER: ${identity_provider}
|
||||
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
|
||||
TF_PROVIDERS_FILE: ${tf_providers_file}
|
||||
TF_VAR_FILES: ${tf_var_files == [] ? "''" : join("\n ", tf_var_files)}
|
||||
TF_VERSION: 1.4.4
|
||||
%{~ if tf_var_files != [] ~}
|
||||
TF_VAR_FILES: ${join("\n ", tf_var_files)}
|
||||
%{~ endif ~}
|
||||
TF_VERSION: 1.5.1
|
||||
|
||||
jobs:
|
||||
fast-pr:
|
||||
|
@ -73,11 +75,13 @@ jobs:
|
|||
run: |
|
||||
gcloud alpha storage cp -r \
|
||||
"gs://$${{env.FAST_OUTPUTS_BUCKET}}/providers/$${{env.TF_PROVIDERS_FILE}}" ./
|
||||
%{~ if tf_var_files != [] ~}
|
||||
gcloud alpha storage cp -r \
|
||||
"gs://$${{env.FAST_OUTPUTS_BUCKET}}/tfvars" ./
|
||||
for f in $${{env.TF_VAR_FILES}}; do
|
||||
ln -s "tfvars/$f" ./
|
||||
done
|
||||
%{~ endif ~}
|
||||
|
||||
- id: tf-setup
|
||||
name: Set up Terraform
|
||||
|
|
|
@ -51,52 +51,52 @@ variable "cicd_repositories" {
|
|||
description = "CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed."
|
||||
type = object({
|
||||
data_platform_dev = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
data_platform_prod = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
gke_dev = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
gke_prod = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
networking = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
project_factory_dev = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
project_factory_prod = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
security = optional(object({
|
||||
branch = string
|
||||
identity_provider = string
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ terraform {
|
|||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
google-beta = {
|
||||
source = "hashicorp/google-beta"
|
||||
version = ">= 5.6.0, < 6.0.0" # tftest
|
||||
version = ">= 5.10.0, < 6.0.0" # tftest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|