FAST GCVE stage (#2191)
* GCVE stage prerequisites * fix gcve prereq * gcve stage first deploy * Updated readme filex * docs updated * some fixes after testing * updated readme files * elia fix * gcve net admin custom role * gcve net admin custom role * elia fix * ven peering deploy * elia fix * added blueprint and stage tests * Edits to Readme files * typo in outputs * clean-up * gcve stage tests fix * readme fix * fix sorting * fix copyrights and readme file * fix test * fix copyright * fixed gcve feature flag cond. * removed validation * fixed typo * fixed typo * fixed gcve tests * fixed typo * fixed typo * fixed sorting * fixed sorting --------- Co-authored-by: Konrad Schieban <kschieban@google.com>
This commit is contained in:
parent
fc23c9c387
commit
b80132a618
|
@ -0,0 +1,106 @@
|
|||
# GCVE Private Cloud Minimal
|
||||
|
||||
This blueprint presents an opinionated architecture to handle different Google VMware Engine deployment scenarios: from a simple single region private cloud to multi-region private clouds spread across different locations. The general idea behind this blueprint is to deploy a single project hosting one or more GCVE private clouds connected to a shared VMware Engine Network (VEN).
|
||||
Optionally this blueprint can deploy the VMWare Engine Network peerings to pre-existing VPCs.
|
||||
|
||||
Multiple deployments of this blueprint allow the user to achieve more complex design solutions as for example GCVE private clouds deployed on different projects or connected to indipendent VMWare Engine Networks.
|
||||
|
||||
This blueprint is used as part of the [FAST GCVE stage](../../../fast/stages/3-gcve/) but it can also be used independently if desired.
|
||||
|
||||
<p align="center">
|
||||
<img src="diagram.png" alt="GCVE single region private cloud">
|
||||
</p>
|
||||
|
||||
The blueprint manages:
|
||||
- project creation
|
||||
- project-level organization policy definitions
|
||||
- billing setup (billing account attachment)
|
||||
- API/services enablement
|
||||
- IAM role assignment for groups
|
||||
- VMware Engine private clouds creation
|
||||
- [VMware Engine Network](https://cloud.google.com/vmware-engine/docs/networking/vmware-engine-network#standard_networks) creation
|
||||
- VPC attachment (Optional)
|
||||
|
||||
### User groups
|
||||
|
||||
Based on our GCP best practices, a GCVE private cloud relies on user groups to assign roles to human identities. These are the specific groups bound to the main GCVE [predefined roles](https://cloud.google.com/vmware-engine/docs/iam#vmware-engine-roles):
|
||||
- *VMware Engine Administrators*. They have full access to the VMWare Engine Service.
|
||||
- *VMware Engine Viewers*. They have read-only access to the VMware Engine Service.
|
||||
|
||||
|
||||
### Network
|
||||
|
||||
This blueprints expects the user to provision a VPC upfront, either from one of the FAST networking stages (e.g. [Networking with separated single environment](../../../fast/stages/2-networking-d-separate-envs)) or from an external source.
|
||||
The blueprint can optionally configure the [VMware Engine Network peering](https://cloud.google.com/vmware-engine/docs/networking/peer-vpc-network) on the peer VPC by granting the following permissions on the project that hosts the VPC:
|
||||
- vmwareengine.networkPeerings.create
|
||||
- vmwareengine.networkPeerings.get
|
||||
- vmwareengine.networkPeerings.list
|
||||
- vmwareengine.operations.get
|
||||
The permissions can be assigned through the predefined role *vmwareengine.vmwareengineAdmin*. Anyway the creation of a dedicated custom roile is strogly recommended to comply with the least privilege principle.
|
||||
|
||||
## Basic usage
|
||||
|
||||
The following example shows how to deploy a CGVE private cloud and connect it to a VPC
|
||||
|
||||
```hcl
|
||||
module "gcve-pc" {
|
||||
source = "./fabric/blueprints/gcve/pc-minimal"
|
||||
billing_account_id = "000000-000000-000000"
|
||||
folder_id = "folders/000000000000"
|
||||
project_id = "myprojectid"
|
||||
groups = {
|
||||
gcp-gcve-admins = "group:gcp-gcve-admins@acme.com"
|
||||
gcp-gcve-viewers = "group:gcp-gcve-viewers@acme.com"
|
||||
}
|
||||
|
||||
prefix = "myprefix"
|
||||
|
||||
network_peerings = {
|
||||
dev-spoke-ven = {
|
||||
peer_network = "projects/spokeproject/regions/europe-west1/subnetworks/dev-default-ew1"
|
||||
peer_project_id = "peerprojectid"
|
||||
}
|
||||
}
|
||||
|
||||
private_cloud_configs = {
|
||||
dev-pc = {
|
||||
cidr = "172.26.16.0/22"
|
||||
zone = "europe-west1-a"
|
||||
management_cluster_config = {
|
||||
name = "mgmt-cluster"
|
||||
node_count = 1
|
||||
node_type_id = "standard-72"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=3 resources=7
|
||||
```
|
||||
|
||||
<!-- TFDOC OPTS files:1 -->
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Files
|
||||
|
||||
| name | description | modules | resources |
|
||||
|---|---|---|---|
|
||||
| [gcve-pc.tf](./gcve-pc.tf) | GCVE private cloud. | <code>gcve-private-cloud</code> | <code>google_vmwareengine_network_peering</code> |
|
||||
| [main.tf](./main.tf) | Project. | <code>project</code> | |
|
||||
| [output.tf](./output.tf) | Output variables. | | |
|
||||
| [variables.tf](./variables.tf) | Module variables. | | |
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L17) | Billing account ID. | <code>string</code> | ✓ | |
|
||||
| [folder_id](variables.tf#L22) | Folder used for the GCVE project in folders/nnnnnnnnnnn format. | <code>string</code> | ✓ | |
|
||||
| [groups](variables.tf#L27) | GCVE groups. | <code title="object({ gcp-gcve-admins = string gcp-gcve-viewers = string })">object({…})</code> | ✓ | |
|
||||
| [prefix](variables.tf#L81) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [private_cloud_configs](variables.tf#L90) | The VMware private cloud configurations. The key is the unique private cloud name suffix. | <code title="map(object({ cidr = string zone = string additional_cluster_configs = optional(map(object({ custom_core_count = optional(number) node_count = optional(number, 3) node_type_id = optional(string, "standard-72") })), {}) management_cluster_config = optional(object({ custom_core_count = optional(number) name = optional(string, "mgmt-cluster") node_count = optional(number, 3) node_type_id = optional(string, "standard-72") }), {}) description = optional(string, "Managed by Terraform.") }))">map(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L112) | ID of the project that will contain the GCVE private cloud. | <code>string</code> | ✓ | |
|
||||
| [iam](variables.tf#L36) | Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam_by_principals](variables.tf#L43) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L50) | Project-level labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [network_peerings](variables.tf#L56) | The network peerings between users' VPCs and the VMware Engine networks. The key is the peering name suffix. | <code title="map(object({ peer_network = string configure_peer_network = optional(bool, false) custom_routes = optional(object({ export_to_peer = optional(bool, false) import_from_peer = optional(bool, false) export_to_ven = optional(bool, false) import_from_ven = optional(bool, false) }), {}) custom_routes_with_public_ip = optional(object({ export_to_peer = optional(bool, false) import_from_peer = optional(bool, false) export_to_ven = optional(bool, false) import_from_ven = optional(bool, false) }), {}) description = optional(string, "Managed by Terraform.") peer_project_id = optional(string) peer_to_vmware_engine_network = optional(bool, false) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [project_services](variables.tf#L117) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||
<!-- END TFDOC -->
|
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright 2024 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 GCVE private cloud.
|
||||
locals {
|
||||
ven_peerings = {
|
||||
for k, v in var.network_peerings : k => {
|
||||
peer_network = v.peer_network
|
||||
description = v.description
|
||||
export_custom_routes = v.custom_routes.export_to_peer
|
||||
export_custom_routes_with_public_ip = v.custom_routes_with_public_ip.export_to_peer
|
||||
import_custom_routes = v.custom_routes.import_from_peer
|
||||
import_custom_routes_with_public_ip = v.custom_routes_with_public_ip.import_from_peer
|
||||
peer_to_vmware_engine_network = v.peer_to_vmware_engine_network
|
||||
}
|
||||
}
|
||||
}
|
||||
module "gcve-pc" {
|
||||
source = "../../../modules/gcve-private-cloud"
|
||||
prefix = var.prefix
|
||||
project_id = module.gcve-project-0.id
|
||||
|
||||
vmw_network_config = {
|
||||
create = true
|
||||
name = "default"
|
||||
}
|
||||
vmw_network_peerings = local.ven_peerings
|
||||
|
||||
vmw_private_cloud_configs = var.private_cloud_configs
|
||||
}
|
||||
|
||||
resource "google_vmwareengine_network_peering" "vmw_engine_network_peerings" {
|
||||
provider = google-beta
|
||||
for_each = { for k, v in var.network_peerings : k => v if v.configure_peer_network }
|
||||
peer_network = each.value.peer_network
|
||||
name = "${var.prefix}-${each.key}"
|
||||
description = each.value.description
|
||||
export_custom_routes = each.value.custom_routes.export_to_ven
|
||||
export_custom_routes_with_public_ip = each.value.custom_routes_with_public_ip.export_to_ven
|
||||
import_custom_routes = each.value.custom_routes.import_from_ven
|
||||
import_custom_routes_with_public_ip = each.value.custom_routes_with_public_ip.import_from_ven
|
||||
peer_network_type = "STANDARD"
|
||||
project = each.value.peer_project_id
|
||||
vmware_engine_network = module.gcve-pc.vmw_private_cloud_network.id
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Copyright 2024 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.
|
||||
|
||||
module "gcve-project-0" {
|
||||
source = "../../../modules/project"
|
||||
billing_account = var.billing_account_id
|
||||
name = var.project_id
|
||||
parent = var.folder_id
|
||||
prefix = var.prefix
|
||||
iam_by_principals = merge({
|
||||
(var.groups.gcp-gcve-admins) = ["roles/vmwareengine.vmwareengineAdmin"]
|
||||
(var.groups.gcp-gcve-viewers) = ["roles/vmwareengine.vmwareengineViewer"]
|
||||
},
|
||||
var.iam_by_principals
|
||||
)
|
||||
iam = var.iam
|
||||
labels = var.labels
|
||||
services = concat([
|
||||
"vmwareengine.googleapis.com",
|
||||
],
|
||||
var.project_services
|
||||
)
|
||||
# specify project-level org policies here if you need them
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright 2024 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
|
||||
#
|
||||
# https://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 Output variables.
|
||||
|
||||
output "project_id" {
|
||||
description = "GCVE project id."
|
||||
value = module.gcve-project-0.project_id
|
||||
}
|
||||
|
||||
output "vmw_engine_network_config" {
|
||||
description = "VMware engine network configuration."
|
||||
value = module.gcve-pc.vmw_engine_network_config
|
||||
}
|
||||
|
||||
output "vmw_engine_network_peerings" {
|
||||
description = "The peerings created towards the user VPC or other VMware engine networks."
|
||||
value = module.gcve-pc.vmw_engine_network_peerings
|
||||
}
|
||||
|
||||
output "vmw_engine_private_clouds" {
|
||||
description = "VMware engine private cloud resources."
|
||||
value = module.gcve-pc.vmw_engine_private_clouds
|
||||
}
|
||||
|
||||
output "vmw_private_cloud_network" {
|
||||
description = "VMware engine network."
|
||||
value = module.gcve-pc.vmw_private_cloud_network
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* Copyright 2024 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 "billing_account_id" {
|
||||
description = "Billing account ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "folder_id" {
|
||||
description = "Folder used for the GCVE project in folders/nnnnnnnnnnn format."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "groups" {
|
||||
description = "GCVE groups."
|
||||
type = object({
|
||||
gcp-gcve-admins = string
|
||||
gcp-gcve-viewers = string
|
||||
})
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "iam" {
|
||||
description = "Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "iam_by_principals" {
|
||||
description = "Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "labels" {
|
||||
description = "Project-level labels."
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "network_peerings" {
|
||||
description = "The network peerings between users' VPCs and the VMware Engine networks. The key is the peering name suffix."
|
||||
type = map(object({
|
||||
peer_network = string
|
||||
configure_peer_network = optional(bool, false)
|
||||
custom_routes = optional(object({
|
||||
export_to_peer = optional(bool, false)
|
||||
import_from_peer = optional(bool, false)
|
||||
export_to_ven = optional(bool, false)
|
||||
import_from_ven = optional(bool, false)
|
||||
}), {})
|
||||
custom_routes_with_public_ip = optional(object({
|
||||
export_to_peer = optional(bool, false)
|
||||
import_from_peer = optional(bool, false)
|
||||
export_to_ven = optional(bool, false)
|
||||
import_from_ven = optional(bool, false)
|
||||
}), {})
|
||||
description = optional(string, "Managed by Terraform.")
|
||||
peer_project_id = optional(string)
|
||||
peer_to_vmware_engine_network = optional(bool, false)
|
||||
}))
|
||||
nullable = false
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "private_cloud_configs" {
|
||||
description = "The VMware private cloud configurations. The key is the unique private cloud name suffix."
|
||||
type = map(object({
|
||||
cidr = string
|
||||
zone = string
|
||||
# The key is the unique additional cluster name suffix
|
||||
additional_cluster_configs = optional(map(object({
|
||||
custom_core_count = optional(number)
|
||||
node_count = optional(number, 3)
|
||||
node_type_id = optional(string, "standard-72")
|
||||
})), {})
|
||||
management_cluster_config = optional(object({
|
||||
custom_core_count = optional(number)
|
||||
name = optional(string, "mgmt-cluster")
|
||||
node_count = optional(number, 3)
|
||||
node_type_id = optional(string, "standard-72")
|
||||
}), {})
|
||||
description = optional(string, "Managed by Terraform.")
|
||||
}))
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "ID of the project that will contain the GCVE private cloud."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "project_services" {
|
||||
description = "Additional project services to enable."
|
||||
type = list(string)
|
||||
default = []
|
||||
nullable = false
|
||||
}
|
|
@ -626,26 +626,26 @@ The `fast_features` variable consists of 4 toggles:
|
|||
| name | description | type | required | default | producer |
|
||||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [billing_account](variables.tf#L17) | 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> | ✓ | | |
|
||||
| [organization](variables.tf#L229) | Organization details. | <code title="object({ id = number domain = optional(string) customer_id = optional(string) })">object({…})</code> | ✓ | | |
|
||||
| [prefix](variables.tf#L244) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
|
||||
| [organization](variables.tf#L230) | Organization details. | <code title="object({ id = number domain = optional(string) customer_id = optional(string) })">object({…})</code> | ✓ | | |
|
||||
| [prefix](variables.tf#L245) | 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({ 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> | |
|
||||
| [essential_contacts](variables.tf#L86) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
|
||||
| [factories_config](variables.tf#L92) | Configuration for the resource factories or external data. | <code title="object({ checklist_data = optional(string) checklist_org_iam = optional(string) custom_roles = optional(string, "data/custom-roles") org_policy = optional(string, "data/org-policies") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [fast_features](variables.tf#L104) | 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> | |
|
||||
| [group_iam](variables.tf#L117) | Organization-level authoritative IAM binding for groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [groups](variables.tf#L124) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") gcp-support = optional(string, "gcp-devops") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [iam](variables.tf#L140) | Organization-level custom IAM settings in role => [principal] format. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [iam_bindings_additive](variables.tf#L147) | Organization-level custom additive IAM bindings. Keys are arbitrary. | <code title="map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [iam_by_principals](variables.tf#L162) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [locations](variables.tf#L169) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = optional(string, "EU") gcs = optional(string, "EU") logging = optional(string, "global") pubsub = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [log_sinks](variables.tf#L183) | Org-level log sinks, in name => {type, filter} format. | <code title="map(object({ filter = string type = string }))">map(object({…}))</code> | | <code title="{ audit-logs = { filter = "logName:\"/logs/cloudaudit.googleapis.com%2Factivity\" OR logName:\"/logs/cloudaudit.googleapis.com%2Fsystem_event\" OR protoPayload.metadata.@type=\"type.googleapis.com/google.cloud.audit.TransparencyLog\"" type = "logging" } vpc-sc = { filter = "protoPayload.metadata.@type=\"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata\"" type = "logging" } workspace-audit-logs = { filter = "logName:\"/logs/cloudaudit.googleapis.com%2Fdata_access\" and protoPayload.serviceName:\"login.googleapis.com\"" type = "logging" } }">{…}</code> | |
|
||||
| [org_policies_config](variables.tf#L212) | Organization policies customization. | <code title="object({ constraints = optional(object({ allowed_policy_member_domains = optional(list(string), []) }), {}) import_defaults = optional(bool, false) tag_name = optional(string, "org-policies") tag_values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) })), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L238) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_parent_ids](variables.tf#L253) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | <code title="object({ automation = optional(string) billing = optional(string) logging = optional(string) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [workforce_identity_providers](variables.tf#L264) | Workforce Identity Federation pools. | <code title="map(object({ attribute_condition = optional(string) issuer = string display_name = string description = string disabled = optional(bool, false) saml = optional(object({ idp_metadata_xml = string }), null) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [workload_identity_providers](variables.tf#L280) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | <code title="map(object({ attribute_condition = optional(string) issuer = string custom_settings = optional(object({ issuer_uri = optional(string) audiences = optional(list(string), []) jwks_json = optional(string) }), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [fast_features](variables.tf#L104) | Selective control for top-level FAST features. | <code title="object({ data_platform = optional(bool, false) gcve = optional(bool, false) gke = optional(bool, false) project_factory = optional(bool, false) sandbox = optional(bool, false) teams = optional(bool, false) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [group_iam](variables.tf#L118) | Organization-level authoritative IAM binding for groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [groups](variables.tf#L125) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") gcp-support = optional(string, "gcp-devops") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [iam](variables.tf#L141) | Organization-level custom IAM settings in role => [principal] format. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [iam_bindings_additive](variables.tf#L148) | Organization-level custom additive IAM bindings. Keys are arbitrary. | <code title="map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [iam_by_principals](variables.tf#L163) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [locations](variables.tf#L170) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = optional(string, "EU") gcs = optional(string, "EU") logging = optional(string, "global") pubsub = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [log_sinks](variables.tf#L184) | Org-level log sinks, in name => {type, filter} format. | <code title="map(object({ filter = string type = string }))">map(object({…}))</code> | | <code title="{ audit-logs = { filter = "logName:\"/logs/cloudaudit.googleapis.com%2Factivity\" OR logName:\"/logs/cloudaudit.googleapis.com%2Fsystem_event\" OR protoPayload.metadata.@type=\"type.googleapis.com/google.cloud.audit.TransparencyLog\"" type = "logging" } vpc-sc = { filter = "protoPayload.metadata.@type=\"type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata\"" type = "logging" } workspace-audit-logs = { filter = "logName:\"/logs/cloudaudit.googleapis.com%2Fdata_access\" and protoPayload.serviceName:\"login.googleapis.com\"" type = "logging" } }">{…}</code> | |
|
||||
| [org_policies_config](variables.tf#L213) | Organization policies customization. | <code title="object({ constraints = optional(object({ allowed_policy_member_domains = optional(list(string), []) }), {}) import_defaults = optional(bool, false) tag_name = optional(string, "org-policies") tag_values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) })), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L239) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_parent_ids](variables.tf#L254) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | <code title="object({ automation = optional(string) billing = optional(string) logging = optional(string) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [workforce_identity_providers](variables.tf#L265) | Workforce Identity Federation pools. | <code title="map(object({ attribute_condition = optional(string) issuer = string display_name = string description = string disabled = optional(bool, false) saml = optional(object({ idp_metadata_xml = string }), null) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [workload_identity_providers](variables.tf#L281) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | <code title="map(object({ attribute_condition = optional(string) issuer = string custom_settings = optional(object({ issuer_uri = optional(string) audiences = optional(list(string), []) jwks_json = optional(string) }), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# 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.
|
||||
|
||||
name: gcveNetworkAdmin
|
||||
includedPermissions:
|
||||
- vmwareengine.networkPeerings.create
|
||||
- vmwareengine.networkPeerings.delete
|
||||
- vmwareengine.networkPeerings.get
|
||||
- vmwareengine.networkPeerings.list
|
||||
- vmwareengine.operations.get
|
|
@ -105,6 +105,7 @@ variable "fast_features" {
|
|||
description = "Selective control for top-level FAST features."
|
||||
type = object({
|
||||
data_platform = optional(bool, false)
|
||||
gcve = optional(bool, false)
|
||||
gke = optional(bool, false)
|
||||
project_factory = optional(bool, false)
|
||||
sandbox = optional(bool, false)
|
||||
|
|
|
@ -327,6 +327,7 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
|
|||
|---|---|---|---|
|
||||
| [billing.tf](./billing.tf) | Billing resources for external billing use cases. | | <code>google_billing_account_iam_member</code> |
|
||||
| [branch-data-platform.tf](./branch-data-platform.tf) | Data Platform stages resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-gcve.tf](./branch-gcve.tf) | GCVE stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-gke.tf](./branch-gke.tf) | GKE multitenant stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-networking.tf](./branch-networking.tf) | Networking stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
| [branch-project-factory.tf](./branch-project-factory.tf) | Project factory stage resources. | <code>gcs</code> · <code>iam-service-account</code> | |
|
||||
|
@ -336,6 +337,7 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
|
|||
| [branch-tenants.tf](./branch-tenants.tf) | Lightweight tenant resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> · <code>project</code> | |
|
||||
| [checklist.tf](./checklist.tf) | None | <code>folder</code> | |
|
||||
| [cicd-data-platform.tf](./cicd-data-platform.tf) | CI/CD resources for the data platform branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
|
||||
| [cicd-gcve.tf](./cicd-gcve.tf) | CI/CD resources for the GCVE branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
|
||||
| [cicd-gke.tf](./cicd-gke.tf) | CI/CD resources for the GKE multitenant branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
|
||||
| [cicd-networking.tf](./cicd-networking.tf) | CI/CD resources for the networking branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
|
||||
| [cicd-project-factory.tf](./cicd-project-factory.tf) | CI/CD resources for the teams branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
|
||||
|
@ -356,35 +358,36 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L20) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string project_id = string project_number = string federated_identity_pool = string federated_identity_providers = map(object({ audiences = list(string) issuer = string issuer_uri = string name = string principal_branch = string principal_repo = string })) service_accounts = object({ resman-r = string }) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L42) | 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#L213) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L229) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [cicd_repositories](variables.tf#L53) | 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#L135) | Custom roles defined at the org level, in key => id format. | <code title="object({ service_project_network_admin = string storage_viewer = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [factories_config](variables.tf#L145) | Configuration for the resource factories or external data. | <code title="object({ checklist_data = optional(string) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [fast_features](variables.tf#L154) | 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#L168) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [locations](variables.tf#L183) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = string gcs = string logging = string pubsub = list(string) })">object({…})</code> | | <code title="{ bq = "EU" gcs = "EU" logging = "global" pubsub = [] }">{…}</code> | <code>0-bootstrap</code> |
|
||||
| [org_policy_tags](variables.tf#L201) | Resource management tags for organization policy exceptions. | <code title="object({ key_id = optional(string) key_name = optional(string) values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L223) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [tag_names](variables.tf#L240) | Customized names for resource management tags. | <code title="object({ context = optional(string, "context") environment = optional(string, "environment") tenant = optional(string, "tenant") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [tags](variables.tf#L255) | Custome secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) })), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [team_folders](variables.tf#L276) | Team folders to be created. Format is described in a code comment. | <code title="map(object({ descriptive_name = string iam_by_principals = map(list(string)) impersonation_principals = list(string) cicd = optional(object({ branch = string identity_provider = string name = string type = string })) }))">map(object({…}))</code> | | <code>null</code> | |
|
||||
| [tenants](variables.tf#L292) | Lightweight tenant definitions. | <code title="map(object({ admin_principal = string descriptive_name = string billing_account = optional(string) organization = optional(object({ customer_id = string domain = string id = number })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [tenants_config](variables.tf#L308) | Lightweight tenants shared configuration. Roles will be assigned to tenant admin group and service accounts. | <code title="object({ core_folder_roles = optional(list(string), []) tenant_folder_roles = optional(list(string), []) top_folder_roles = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [organization](variables.tf#L227) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L243) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [cicd_repositories](variables.tf#L53) | 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) })) gcve_dev = optional(object({ name = string type = string branch = optional(string) identity_provider = optional(string) })) gcve_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#L147) | Custom roles defined at the org level, in key => id format. | <code title="object({ gcve_network_admin = string service_project_network_admin = string storage_viewer = string })">object({…})</code> | | <code>null</code> | <code>0-bootstrap</code> |
|
||||
| [factories_config](variables.tf#L158) | Configuration for the resource factories or external data. | <code title="object({ checklist_data = optional(string) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [fast_features](variables.tf#L167) | Selective control for top-level FAST features. | <code title="object({ data_platform = optional(bool, false) gke = optional(bool, false) gcve = 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#L182) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object({ gcp-billing-admins = optional(string, "gcp-billing-admins") gcp-devops = optional(string, "gcp-devops") gcp-network-admins = optional(string, "gcp-network-admins") gcp-organization-admins = optional(string, "gcp-organization-admins") gcp-security-admins = optional(string, "gcp-security-admins") })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [locations](variables.tf#L197) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object({ bq = string gcs = string logging = string pubsub = list(string) })">object({…})</code> | | <code title="{ bq = "EU" gcs = "EU" logging = "global" pubsub = [] }">{…}</code> | <code>0-bootstrap</code> |
|
||||
| [org_policy_tags](variables.tf#L215) | Resource management tags for organization policy exceptions. | <code title="object({ key_id = optional(string) key_name = optional(string) values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> | <code>0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L237) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [tag_names](variables.tf#L254) | Customized names for resource management tags. | <code title="object({ context = optional(string, "context") environment = optional(string, "environment") tenant = optional(string, "tenant") })">object({…})</code> | | <code>{}</code> | |
|
||||
| [tags](variables.tf#L269) | Custome secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) id = optional(string) })), {}) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [team_folders](variables.tf#L290) | Team folders to be created. Format is described in a code comment. | <code title="map(object({ descriptive_name = string iam_by_principals = map(list(string)) impersonation_principals = list(string) cicd = optional(object({ branch = string identity_provider = string name = string type = string })) }))">map(object({…}))</code> | | <code>null</code> | |
|
||||
| [tenants](variables.tf#L306) | Lightweight tenant definitions. | <code title="map(object({ admin_principal = string descriptive_name = string billing_account = optional(string) organization = optional(object({ customer_id = string domain = string id = number })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [tenants_config](variables.tf#L322) | Lightweight tenants shared configuration. Roles will be assigned to tenant admin group and service accounts. | <code title="object({ core_folder_roles = optional(list(string), []) tenant_folder_roles = optional(list(string), []) top_folder_roles = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive | consumers |
|
||||
|---|---|:---:|---|
|
||||
| [cicd_repositories](outputs.tf#L337) | WIF configuration for CI/CD repositories. | | |
|
||||
| [dataplatform](outputs.tf#L351) | Data for the Data Platform stage. | | |
|
||||
| [gke_multitenant](outputs.tf#L367) | Data for the GKE multitenant stage. | | <code>03-gke-multitenant</code> |
|
||||
| [networking](outputs.tf#L388) | Data for the networking stage. | | |
|
||||
| [project_factories](outputs.tf#L397) | Data for the project factories stage. | | |
|
||||
| [providers](outputs.tf#L412) | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>03-dataplatform</code> · <code>xx-sandbox</code> · <code>xx-teams</code> |
|
||||
| [sandbox](outputs.tf#L419) | Data for the sandbox stage. | | <code>xx-sandbox</code> |
|
||||
| [security](outputs.tf#L433) | Data for the networking stage. | | <code>02-security</code> |
|
||||
| [team_cicd_repositories](outputs.tf#L443) | WIF configuration for Team CI/CD repositories. | | |
|
||||
| [teams](outputs.tf#L457) | Data for the teams stage. | | |
|
||||
| [tfvars](outputs.tf#L469) | Terraform variable files for the following stages. | ✓ | |
|
||||
| [cicd_repositories](outputs.tf#L391) | WIF configuration for CI/CD repositories. | | |
|
||||
| [dataplatform](outputs.tf#L405) | Data for the Data Platform stage. | | |
|
||||
| [gcve](outputs.tf#L421) | Data for the GCVE stage. | | <code>03-gke-multitenant</code> |
|
||||
| [gke_multitenant](outputs.tf#L442) | Data for the GKE multitenant stage. | | <code>03-gke-multitenant</code> |
|
||||
| [networking](outputs.tf#L463) | Data for the networking stage. | | |
|
||||
| [project_factories](outputs.tf#L472) | Data for the project factories stage. | | |
|
||||
| [providers](outputs.tf#L487) | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>03-dataplatform</code> · <code>xx-sandbox</code> · <code>xx-teams</code> |
|
||||
| [sandbox](outputs.tf#L494) | Data for the sandbox stage. | | <code>xx-sandbox</code> |
|
||||
| [security](outputs.tf#L508) | Data for the networking stage. | | <code>02-security</code> |
|
||||
| [team_cicd_repositories](outputs.tf#L518) | WIF configuration for Team CI/CD repositories. | | |
|
||||
| [teams](outputs.tf#L532) | Data for the teams stage. | | |
|
||||
| [tfvars](outputs.tf#L544) | Terraform variable files for the following stages. | ✓ | |
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -27,6 +27,8 @@ locals {
|
|||
local.branch_optional_sa_lists.dp-prod,
|
||||
local.branch_optional_sa_lists.gke-dev,
|
||||
local.branch_optional_sa_lists.gke-prod,
|
||||
local.branch_optional_sa_lists.gcve-dev,
|
||||
local.branch_optional_sa_lists.gcve-prod,
|
||||
local.branch_optional_sa_lists.pf-dev,
|
||||
local.branch_optional_sa_lists.pf-prod,
|
||||
)
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
/**
|
||||
* 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 GCVE stage resources.
|
||||
|
||||
module "branch-gcve-folder" {
|
||||
source = "../../../modules/folder"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
parent = "organizations/${var.organization.id}"
|
||||
name = "GCVE"
|
||||
tag_bindings = {
|
||||
context = try(
|
||||
module.organization.tag_values["${var.tag_names.context}/gcve"].id, null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module "branch-gcve-dev-folder" {
|
||||
source = "../../../modules/folder"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
parent = module.branch-gcve-folder.0.id
|
||||
name = "Development"
|
||||
iam = {
|
||||
# read-write (apply) automation service account
|
||||
"roles/owner" = [module.branch-gcve-dev-sa.0.iam_email]
|
||||
"roles/logging.admin" = [module.branch-gcve-dev-sa.0.iam_email]
|
||||
"roles/resourcemanager.folderAdmin" = [module.branch-gcve-dev-sa.0.iam_email]
|
||||
"roles/resourcemanager.projectCreator" = [module.branch-gcve-dev-sa.0.iam_email]
|
||||
"roles/compute.xpnAdmin" = [module.branch-gcve-dev-sa.0.iam_email]
|
||||
# read-only (plan) automation service account
|
||||
"roles/viewer" = [module.branch-gcve-dev-r-sa.0.iam_email]
|
||||
"roles/resourcemanager.folderViewer" = [module.branch-gcve-dev-r-sa.0.iam_email]
|
||||
}
|
||||
tag_bindings = {
|
||||
context = try(
|
||||
module.organization.tag_values["${var.tag_names.environment}/development"].id,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module "branch-gcve-prod-folder" {
|
||||
source = "../../../modules/folder"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
parent = module.branch-gcve-folder.0.id
|
||||
name = "Production"
|
||||
iam = {
|
||||
# read-write (apply) automation service account
|
||||
"roles/owner" = [module.branch-gcve-prod-sa.0.iam_email]
|
||||
"roles/logging.admin" = [module.branch-gcve-prod-sa.0.iam_email]
|
||||
"roles/resourcemanager.folderAdmin" = [module.branch-gcve-prod-sa.0.iam_email]
|
||||
"roles/resourcemanager.projectCreator" = [module.branch-gcve-prod-sa.0.iam_email]
|
||||
"roles/compute.xpnAdmin" = [module.branch-gcve-prod-sa.0.iam_email]
|
||||
# read-only (plan) automation service account
|
||||
"roles/viewer" = [module.branch-gcve-prod-r-sa.0.iam_email]
|
||||
"roles/resourcemanager.folderViewer" = [module.branch-gcve-prod-r-sa.0.iam_email]
|
||||
}
|
||||
tag_bindings = {
|
||||
context = try(
|
||||
module.organization.tag_values["${var.tag_names.environment}/production"].id,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
# automation service accounts
|
||||
|
||||
module "branch-gcve-dev-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
project_id = var.automation.project_id
|
||||
name = "dev-resman-gcve-0"
|
||||
display_name = "Terraform GCVE development service account."
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.serviceAccountTokenCreator" = concat(
|
||||
[local.principals.gcp-devops],
|
||||
compact([
|
||||
try(module.branch-gcve-dev-sa-cicd.0.iam_email, null)
|
||||
])
|
||||
)
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
|
||||
}
|
||||
}
|
||||
|
||||
module "branch-gcve-prod-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-gcve-0"
|
||||
display_name = "Terraform GCVE production service account."
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.serviceAccountTokenCreator" = concat(
|
||||
[local.principals.gcp-devops],
|
||||
compact([
|
||||
try(module.branch-gcve-prod-sa-cicd.0.iam_email, null)
|
||||
])
|
||||
)
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
|
||||
}
|
||||
}
|
||||
|
||||
# automation read-only service accounts
|
||||
|
||||
module "branch-gcve-dev-r-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
project_id = var.automation.project_id
|
||||
name = "dev-resman-gcve-0r"
|
||||
display_name = "Terraform GCVE development service account (read-only)."
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.serviceAccountTokenCreator" = compact([
|
||||
try(module.branch-gcve-dev-r-sa-cicd.0.iam_email, null)
|
||||
])
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = [var.custom_roles["storage_viewer"]]
|
||||
}
|
||||
}
|
||||
|
||||
module "branch-gcve-prod-r-sa" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-gcve-0r"
|
||||
display_name = "Terraform GCVE production service account (read-only)."
|
||||
prefix = var.prefix
|
||||
iam = {
|
||||
"roles/iam.serviceAccountTokenCreator" = compact([
|
||||
try(module.branch-gcve-prod-r-sa-cicd.0.iam_email, null)
|
||||
])
|
||||
}
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = [var.custom_roles["storage_viewer"]]
|
||||
}
|
||||
}
|
||||
|
||||
# automation buckets
|
||||
|
||||
module "branch-gcve-dev-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
project_id = var.automation.project_id
|
||||
name = "dev-resman-gcve-0"
|
||||
prefix = var.prefix
|
||||
location = var.locations.gcs
|
||||
storage_class = local.gcs_storage_class
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-gcve-dev-sa.0.iam_email]
|
||||
"roles/storage.objectViewer" = [module.branch-gcve-dev-r-sa.0.iam_email]
|
||||
}
|
||||
}
|
||||
|
||||
module "branch-gcve-prod-gcs" {
|
||||
source = "../../../modules/gcs"
|
||||
count = var.fast_features.gcve ? 1 : 0
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-gcve-0"
|
||||
prefix = var.prefix
|
||||
location = var.locations.gcs
|
||||
storage_class = local.gcs_storage_class
|
||||
versioning = true
|
||||
iam = {
|
||||
"roles/storage.objectAdmin" = [module.branch-gcve-prod-sa.0.iam_email]
|
||||
"roles/storage.objectViewer" = [module.branch-gcve-prod-r-sa.0.iam_email]
|
||||
}
|
||||
}
|
|
@ -54,14 +54,17 @@ module "branch-network-prod-folder" {
|
|||
(local.custom_roles.service_project_network_admin) = concat(
|
||||
local.branch_optional_sa_lists.dp-prod,
|
||||
local.branch_optional_sa_lists.gke-prod,
|
||||
local.branch_optional_sa_lists.gcve-prod,
|
||||
local.branch_optional_sa_lists.pf-prod,
|
||||
)
|
||||
# read-only (plan) automation service accounts
|
||||
"roles/compute.networkViewer" = concat(
|
||||
local.branch_optional_r_sa_lists.dp-prod,
|
||||
local.branch_optional_r_sa_lists.gke-prod,
|
||||
local.branch_optional_r_sa_lists.gcve-prod,
|
||||
local.branch_optional_r_sa_lists.pf-prod,
|
||||
)
|
||||
(local.custom_roles.gcve_network_admin) = local.branch_optional_sa_lists.gcve-prod
|
||||
}
|
||||
tag_bindings = {
|
||||
environment = try(
|
||||
|
@ -80,14 +83,17 @@ module "branch-network-dev-folder" {
|
|||
(local.custom_roles.service_project_network_admin) = concat(
|
||||
local.branch_optional_sa_lists.dp-dev,
|
||||
local.branch_optional_sa_lists.gke-dev,
|
||||
local.branch_optional_sa_lists.gcve-dev,
|
||||
local.branch_optional_sa_lists.pf-dev,
|
||||
)
|
||||
# read-only (plan) automation service accounts
|
||||
"roles/compute.networkViewer" = concat(
|
||||
local.branch_optional_r_sa_lists.dp-prod,
|
||||
local.branch_optional_r_sa_lists.gke-prod,
|
||||
local.branch_optional_r_sa_lists.gcve-dev,
|
||||
local.branch_optional_r_sa_lists.pf-prod,
|
||||
)
|
||||
(local.custom_roles.gcve_network_admin) = local.branch_optional_sa_lists.gcve-dev
|
||||
}
|
||||
tag_bindings = {
|
||||
environment = try(
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
/**
|
||||
* 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 CI/CD resources for the GCVE branch.
|
||||
|
||||
# source repositories
|
||||
|
||||
module "branch-gcve-dev-cicd-repo" {
|
||||
source = "../../../modules/source-repository"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.gcve_dev.type, null) == "sourcerepo"
|
||||
? { 0 = local.cicd_repositories.gcve_dev }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = each.value.name
|
||||
iam = {
|
||||
"roles/source.admin" = compact([
|
||||
try(module.branch-gcve-dev-sa.0.iam_email, "")
|
||||
])
|
||||
"roles/source.reader" = compact([
|
||||
try(module.branch-gcve-dev-sa-cicd.0.iam_email, "")
|
||||
])
|
||||
}
|
||||
triggers = {
|
||||
fast-03-gcve-dev = {
|
||||
filename = ".cloudbuild/workflow.yaml"
|
||||
included_files = [
|
||||
"**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml"
|
||||
]
|
||||
service_account = module.branch-gcve-dev-sa-cicd.0.id
|
||||
substitutions = {}
|
||||
template = {
|
||||
project_id = null
|
||||
branch_name = each.value.branch
|
||||
repo_name = each.value.name
|
||||
tag_name = null
|
||||
}
|
||||
}
|
||||
}
|
||||
depends_on = [module.branch-gcve-dev-sa-cicd]
|
||||
}
|
||||
|
||||
module "branch-gcve-prod-cicd-repo" {
|
||||
source = "../../../modules/source-repository"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.gcve_prod.type, null) == "sourcerepo"
|
||||
? { 0 = local.cicd_repositories.gcve_prod }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = each.value.name
|
||||
iam = {
|
||||
"roles/source.admin" = [module.branch-gcve-prod-sa.0.iam_email]
|
||||
"roles/source.reader" = [module.branch-gcve-prod-sa-cicd.0.iam_email]
|
||||
}
|
||||
triggers = {
|
||||
fast-03-gcve-prod = {
|
||||
filename = ".cloudbuild/workflow.yaml"
|
||||
included_files = [
|
||||
"**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml"
|
||||
]
|
||||
service_account = module.branch-gcve-prod-sa-cicd.0.id
|
||||
substitutions = {}
|
||||
template = {
|
||||
project_id = null
|
||||
branch_name = each.value.branch
|
||||
repo_name = each.value.name
|
||||
tag_name = null
|
||||
}
|
||||
}
|
||||
}
|
||||
depends_on = [module.branch-gcve-prod-sa-cicd]
|
||||
}
|
||||
|
||||
# read-write (apply) SAs used by CI/CD workflows to impersonate automation SAs
|
||||
|
||||
module "branch-gcve-dev-sa-cicd" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.gcve_dev.name, null) != null
|
||||
? { 0 = local.cicd_repositories.gcve_dev }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = "dev-resman-gcve-1"
|
||||
display_name = "Terraform CI/CD GCVE development service account."
|
||||
prefix = var.prefix
|
||||
iam = (
|
||||
each.value.type == "sourcerepo"
|
||||
# used directly from the cloud build trigger for source repos
|
||||
? {
|
||||
"roles/iam.serviceAccountUser" = local.automation_resman_sa_iam
|
||||
}
|
||||
# impersonated via workload identity federation for external repos
|
||||
: {
|
||||
"roles/iam.workloadIdentityUser" = [
|
||||
each.value.branch == null
|
||||
? format(
|
||||
local.identity_providers[each.value.identity_provider].principal_repo,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name
|
||||
)
|
||||
: format(
|
||||
local.identity_providers[each.value.identity_provider].principal_branch,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name,
|
||||
each.value.branch
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/logging.logWriter"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
|
||||
}
|
||||
}
|
||||
|
||||
module "branch-gcve-prod-sa-cicd" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.gcve_prod.name, null) != null
|
||||
? { 0 = local.cicd_repositories.gcve_prod }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-gcve-1"
|
||||
display_name = "Terraform CI/CD GCVE production service account."
|
||||
prefix = var.prefix
|
||||
iam = (
|
||||
each.value.type == "sourcerepo"
|
||||
# used directly from the cloud build trigger for source repos
|
||||
? {
|
||||
"roles/iam.serviceAccountUser" = local.automation_resman_sa_iam
|
||||
}
|
||||
# impersonated via workload identity federation for external repos
|
||||
: {
|
||||
"roles/iam.workloadIdentityUser" = [
|
||||
each.value.branch == null
|
||||
? format(
|
||||
local.identity_providers[each.value.identity_provider].principal_repo,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name
|
||||
)
|
||||
: format(
|
||||
local.identity_providers[each.value.identity_provider].principal_branch,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name,
|
||||
each.value.branch
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/logging.logWriter"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
|
||||
}
|
||||
}
|
||||
|
||||
# read-only (plan) SAs used by CI/CD workflows to impersonate automation SAs
|
||||
|
||||
module "branch-gcve-dev-r-sa-cicd" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.gcve_dev.name, null) != null
|
||||
? { 0 = local.cicd_repositories.gcve_dev }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = "dev-resman-gcve-1r"
|
||||
display_name = "Terraform CI/CD GCVE development service account (read-only)."
|
||||
prefix = var.prefix
|
||||
iam = (
|
||||
each.value.type == "sourcerepo"
|
||||
# build trigger for read-only SA is optionally defined by users
|
||||
? {}
|
||||
# impersonated via workload identity federation for external repos
|
||||
: {
|
||||
"roles/iam.workloadIdentityUser" = [
|
||||
format(
|
||||
local.identity_providers[each.value.identity_provider].principal_repo,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/logging.logWriter"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
|
||||
}
|
||||
}
|
||||
|
||||
module "branch-gcve-prod-r-sa-cicd" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
for_each = (
|
||||
try(local.cicd_repositories.gcve_prod.name, null) != null
|
||||
? { 0 = local.cicd_repositories.gcve_prod }
|
||||
: {}
|
||||
)
|
||||
project_id = var.automation.project_id
|
||||
name = "prod-resman-gcve-1r"
|
||||
display_name = "Terraform CI/CD GCVE production service account (read-only)."
|
||||
prefix = var.prefix
|
||||
iam = (
|
||||
each.value.type == "sourcerepo"
|
||||
# build trigger for read-only SA is optionally defined by users
|
||||
? {}
|
||||
# impersonated via workload identity federation for external repos
|
||||
: {
|
||||
"roles/iam.workloadIdentityUser" = [
|
||||
format(
|
||||
local.identity_providers[each.value.identity_provider].principal_repo,
|
||||
var.automation.federated_identity_pool,
|
||||
each.value.name
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
iam_project_roles = {
|
||||
(var.automation.project_id) = ["roles/logging.logWriter"]
|
||||
}
|
||||
iam_storage_roles = {
|
||||
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
|
||||
}
|
||||
}
|
|
@ -26,20 +26,24 @@ locals {
|
|||
)
|
||||
# service accounts that receive additional grants on networking/security
|
||||
branch_optional_sa_lists = {
|
||||
dp-dev = compact([try(module.branch-dp-dev-sa.0.iam_email, "")])
|
||||
dp-prod = compact([try(module.branch-dp-prod-sa.0.iam_email, "")])
|
||||
gke-dev = compact([try(module.branch-gke-dev-sa.0.iam_email, "")])
|
||||
gke-prod = compact([try(module.branch-gke-prod-sa.0.iam_email, "")])
|
||||
pf-dev = compact([try(module.branch-pf-dev-sa.0.iam_email, "")])
|
||||
pf-prod = compact([try(module.branch-pf-prod-sa.0.iam_email, "")])
|
||||
dp-dev = compact([try(module.branch-dp-dev-sa.0.iam_email, "")])
|
||||
dp-prod = compact([try(module.branch-dp-prod-sa.0.iam_email, "")])
|
||||
gcve-dev = compact([try(module.branch-gcve-dev-sa.0.iam_email, "")])
|
||||
gcve-prod = compact([try(module.branch-gcve-prod-sa.0.iam_email, "")])
|
||||
gke-dev = compact([try(module.branch-gke-dev-sa.0.iam_email, "")])
|
||||
gke-prod = compact([try(module.branch-gke-prod-sa.0.iam_email, "")])
|
||||
pf-dev = compact([try(module.branch-pf-dev-sa.0.iam_email, "")])
|
||||
pf-prod = compact([try(module.branch-pf-prod-sa.0.iam_email, "")])
|
||||
}
|
||||
branch_optional_r_sa_lists = {
|
||||
dp-dev = compact([try(module.branch-dp-dev-r-sa.0.iam_email, "")])
|
||||
dp-prod = compact([try(module.branch-dp-prod-r-sa.0.iam_email, "")])
|
||||
gke-dev = compact([try(module.branch-gke-dev-r-sa.0.iam_email, "")])
|
||||
gke-prod = compact([try(module.branch-gke-prod-r-sa.0.iam_email, "")])
|
||||
pf-dev = compact([try(module.branch-pf-dev-r-sa.0.iam_email, "")])
|
||||
pf-prod = compact([try(module.branch-pf-prod-r-sa.0.iam_email, "")])
|
||||
dp-dev = compact([try(module.branch-dp-dev-r-sa.0.iam_email, "")])
|
||||
dp-prod = compact([try(module.branch-dp-prod-r-sa.0.iam_email, "")])
|
||||
gcve-dev = compact([try(module.branch-gcve-dev-r-sa.0.iam_email, "")])
|
||||
gcve-prod = compact([try(module.branch-gcve-prod-r-sa.0.iam_email, "")])
|
||||
gke-dev = compact([try(module.branch-gke-dev-r-sa.0.iam_email, "")])
|
||||
gke-prod = compact([try(module.branch-gke-prod-r-sa.0.iam_email, "")])
|
||||
pf-dev = compact([try(module.branch-pf-dev-r-sa.0.iam_email, "")])
|
||||
pf-prod = compact([try(module.branch-pf-prod-r-sa.0.iam_email, "")])
|
||||
}
|
||||
# normalize CI/CD repositories
|
||||
cicd_repositories = {
|
||||
|
|
|
@ -50,6 +50,7 @@ module "organization" {
|
|||
values = {
|
||||
data = {}
|
||||
gke = {}
|
||||
gcve = {}
|
||||
networking = {}
|
||||
sandbox = {}
|
||||
security = {}
|
||||
|
|
|
@ -39,6 +39,28 @@ locals {
|
|||
}
|
||||
tf_var_files = local.cicd_workflow_var_files.stage_3
|
||||
}
|
||||
gcve_dev = {
|
||||
service_accounts = {
|
||||
apply = try(module.branch-gcve-dev-sa-cicd.0.email, null)
|
||||
plan = try(module.branch-gcve-dev-r-sa-cicd.0.email, null)
|
||||
}
|
||||
tf_providers_files = {
|
||||
apply = "3-gcve-dev-providers.tf"
|
||||
plan = "3-gcve-dev-r-providers.tf"
|
||||
}
|
||||
tf_var_files = local.cicd_workflow_var_files.stage_3
|
||||
}
|
||||
gcve_prod = {
|
||||
service_accounts = {
|
||||
apply = try(module.branch-gcve-prod-sa-cicd.0.email, null)
|
||||
plan = try(module.branch-gcve-prod-r-sa-cicd.0.email, null)
|
||||
}
|
||||
tf_providers_files = {
|
||||
apply = "3-gcve-prod-providers.tf"
|
||||
plan = "3-gcve-prod-r-providers.tf"
|
||||
}
|
||||
tf_var_files = local.cicd_workflow_var_files.stage_3
|
||||
}
|
||||
gke_dev = {
|
||||
service_accounts = {
|
||||
apply = try(module.branch-gke-dev-sa-cicd.0.email, null)
|
||||
|
@ -125,6 +147,8 @@ locals {
|
|||
{
|
||||
data-platform-dev = try(module.branch-dp-dev-folder.0.id, null)
|
||||
data-platform-prod = try(module.branch-dp-prod-folder.0.id, null)
|
||||
gcve-dev = try(module.branch-gcve-dev-folder.0.id, null)
|
||||
gcve-prod = try(module.branch-gcve-prod-folder.0.id, null)
|
||||
gke-dev = try(module.branch-gke-dev-folder.0.id, null)
|
||||
gke-prod = try(module.branch-gke-prod-folder.0.id, null)
|
||||
networking = try(module.branch-network-folder.id, null)
|
||||
|
@ -226,6 +250,32 @@ locals {
|
|||
sa = module.branch-gke-prod-r-sa.0.email
|
||||
})
|
||||
},
|
||||
!var.fast_features.gcve ? {} : {
|
||||
"3-gcve-dev" = templatefile(local._tpl_providers, {
|
||||
backend_extra = null
|
||||
bucket = module.branch-gcve-dev-gcs.0.name
|
||||
name = "gcve-dev"
|
||||
sa = module.branch-gcve-dev-sa.0.email
|
||||
})
|
||||
"3-gcve-dev-r" = templatefile(local._tpl_providers, {
|
||||
backend_extra = null
|
||||
bucket = module.branch-gcve-dev-gcs.0.name
|
||||
name = "gcve-dev"
|
||||
sa = module.branch-gcve-dev-r-sa.0.email
|
||||
})
|
||||
"3-gcve-prod" = templatefile(local._tpl_providers, {
|
||||
backend_extra = null
|
||||
bucket = module.branch-gcve-prod-gcs.0.name
|
||||
name = "gcve-prod"
|
||||
sa = module.branch-gcve-prod-sa.0.email
|
||||
})
|
||||
"3-gcve-prod-r" = templatefile(local._tpl_providers, {
|
||||
backend_extra = null
|
||||
bucket = module.branch-gcve-prod-gcs.0.name
|
||||
name = "gcve-prod"
|
||||
sa = module.branch-gcve-prod-r-sa.0.email
|
||||
})
|
||||
},
|
||||
!var.fast_features.project_factory ? {} : {
|
||||
"3-project-factory-dev" = templatefile(local._tpl_providers, {
|
||||
backend_extra = null
|
||||
|
@ -286,6 +336,10 @@ locals {
|
|||
data-platform-dev-r = try(module.branch-dp-dev-r-sa.0.email, null)
|
||||
data-platform-prod = try(module.branch-dp-prod-sa.0.email, null)
|
||||
data-platform-prod-r = try(module.branch-dp-prod-r-sa.0.email, null)
|
||||
gcve-dev = try(module.branch-gcve-dev-sa.0.email, null)
|
||||
gcve-dev-r = try(module.branch-gcve-dev-r-sa.0.email, null)
|
||||
gcve-prod = try(module.branch-gcve-prod-sa.0.email, null)
|
||||
gcve-prod-r = try(module.branch-gcve-prod-r-sa.0.email, null)
|
||||
gke-dev = try(module.branch-gke-dev-sa.0.email, null)
|
||||
gke-dev-r = try(module.branch-gke-dev-r-sa.0.email, null)
|
||||
gke-prod = try(module.branch-gke-prod-sa.0.email, null)
|
||||
|
@ -364,6 +418,27 @@ output "dataplatform" {
|
|||
}
|
||||
}
|
||||
|
||||
output "gcve" {
|
||||
# tfdoc:output:consumers 03-gke-multitenant
|
||||
description = "Data for the GCVE stage."
|
||||
value = (
|
||||
var.fast_features.gcve
|
||||
? {
|
||||
"dev" = {
|
||||
folder = module.branch-gcve-dev-folder.0.id
|
||||
gcs_bucket = module.branch-gcve-dev-gcs.0.name
|
||||
service_account = module.branch-gcve-dev-sa.0.email
|
||||
}
|
||||
"prod" = {
|
||||
folder = module.branch-gcve-prod-folder.0.id
|
||||
gcs_bucket = module.branch-gcve-prod-gcs.0.name
|
||||
service_account = module.branch-gcve-prod-sa.0.email
|
||||
}
|
||||
}
|
||||
: {}
|
||||
)
|
||||
}
|
||||
|
||||
output "gke_multitenant" {
|
||||
# tfdoc:output:consumers 03-gke-multitenant
|
||||
description = "Data for the GKE multitenant stage."
|
||||
|
|
|
@ -77,6 +77,18 @@ variable "cicd_repositories" {
|
|||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
gcve_dev = optional(object({
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
gcve_prod = optional(object({
|
||||
name = string
|
||||
type = string
|
||||
branch = optional(string)
|
||||
identity_provider = optional(string)
|
||||
}))
|
||||
networking = optional(object({
|
||||
name = string
|
||||
type = string
|
||||
|
@ -136,6 +148,7 @@ variable "custom_roles" {
|
|||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
type = object({
|
||||
gcve_network_admin = string
|
||||
service_project_network_admin = string
|
||||
storage_viewer = string
|
||||
})
|
||||
|
@ -157,6 +170,7 @@ variable "fast_features" {
|
|||
type = object({
|
||||
data_platform = optional(bool, false)
|
||||
gke = optional(bool, false)
|
||||
gcve = optional(bool, false)
|
||||
project_factory = optional(bool, false)
|
||||
sandbox = optional(bool, false)
|
||||
teams = optional(bool, false)
|
||||
|
|
|
@ -389,21 +389,22 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L116) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L126) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L142) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L126) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L136) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L152) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | 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> |
|
||||
| [dns](variables.tf#L72) | DNS configuration. | <code title="object({ enable_logging = optional(bool, true) resolvers = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [enable_cloud_nat](variables.tf#L82) | Deploy Cloud NAT. | <code>bool</code> | | <code>false</code> | |
|
||||
| [essential_contacts](variables.tf#L89) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
|
||||
| [factories_config](variables.tf#L95) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L136) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [fast_features](variables.tf#L116) | Selective control for top-level FAST features. | <code title="object({ gcve = optional(bool, false) })">object({…})</code> | | <code>{}</code> | <code>0-0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L146) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [peering_configs](variables-peerings.tf#L19) | Peering configurations. | <code title="object({ dev = optional(object({ export = optional(bool, true) import = optional(bool, true) public_export = optional(bool) public_import = optional(bool) }), {}) prod = optional(object({ export = optional(bool, true) import = optional(bool, true) public_export = optional(bool) public_import = optional(bool) }), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [psa_ranges](variables.tf#L153) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L172) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L184) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L198) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L163) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L182) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L194) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L208) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -22,16 +22,23 @@ module "dev-spoke-project" {
|
|||
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",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
services = concat(
|
||||
[
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -22,16 +22,23 @@ module "prod-spoke-project" {
|
|||
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",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
services = concat(
|
||||
[
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -113,6 +113,16 @@ variable "factories_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "fast_features" {
|
||||
# tfdoc:variable:source 0-0-bootstrap
|
||||
description = "Selective control for top-level FAST features."
|
||||
type = object({
|
||||
gcve = optional(bool, false)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created."
|
||||
|
|
|
@ -413,21 +413,22 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L116) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L126) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L142) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L126) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L136) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L152) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | 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> |
|
||||
| [dns](variables.tf#L72) | DNS configuration. | <code title="object({ enable_logging = optional(bool, true) resolvers = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [enable_cloud_nat](variables.tf#L82) | Deploy Cloud NAT. | <code>bool</code> | | <code>false</code> | |
|
||||
| [essential_contacts](variables.tf#L89) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
|
||||
| [factories_config](variables.tf#L95) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L136) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L153) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L172) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L184) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [fast_features](variables.tf#L116) | Selective control for top-level FAST features. | <code title="object({ gcve = optional(bool, false) })">object({…})</code> | | <code>{}</code> | <code>0-0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L146) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L163) | IP ranges used for Private Service Access (CloudSQL, etc.). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L182) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L194) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_configs](variables-vpn.tf#L17) | Hub to spokes VPN configurations. | <code title="object({ dev = optional(object({ asn = optional(number, 65501) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }), {}) landing = optional(object({ asn = optional(number, 65500) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }), {}) prod = optional(object({ asn = optional(number, 65502) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }), {}) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [vpn_onprem_primary_config](variables.tf#L198) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_primary_config](variables.tf#L208) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -22,16 +22,23 @@ module "dev-spoke-project" {
|
|||
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",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
services = concat(
|
||||
[
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -22,16 +22,23 @@ module "prod-spoke-project" {
|
|||
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",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
services = concat(
|
||||
[
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
"networkmanagement.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -113,6 +113,16 @@ variable "factories_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "fast_features" {
|
||||
# tfdoc:variable:source 0-0-bootstrap
|
||||
description = "Selective control for top-level FAST features."
|
||||
type = object({
|
||||
gcve = optional(bool, false)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created."
|
||||
|
|
|
@ -458,23 +458,24 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L116) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L149) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L165) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L126) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L159) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L175) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | 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> |
|
||||
| [dns](variables.tf#L72) | DNS configuration. | <code title="object({ enable_logging = optional(bool, true) resolvers = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [enable_cloud_nat](variables.tf#L82) | Deploy Cloud NAT. | <code>bool</code> | | <code>false</code> | |
|
||||
| [essential_contacts](variables.tf#L89) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
|
||||
| [factories_config](variables.tf#L95) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [gcp_ranges](variables.tf#L126) | GCP address ranges in name => range format. | <code>map(string)</code> | | <code title="{ gcp_dev_primary = "10.68.0.0/16" gcp_dev_secondary = "10.84.0.0/16" gcp_landing_landing_primary = "10.64.0.0/17" gcp_landing_landing_secondary = "10.80.0.0/17" gcp_dmz_primary = "10.64.127.0/17" gcp_dmz_secondary = "10.80.127.0/17" gcp_prod_primary = "10.72.0.0/16" gcp_prod_secondary = "10.88.0.0/16" }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L141) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L159) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L176) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L195) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L207) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L221) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L264) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [fast_features](variables.tf#L116) | Selective control for top-level FAST features. | <code title="object({ gcve = optional(bool, false) })">object({…})</code> | | <code>{}</code> | <code>0-0-bootstrap</code> |
|
||||
| [gcp_ranges](variables.tf#L136) | GCP address ranges in name => range format. | <code>map(string)</code> | | <code title="{ gcp_dev_primary = "10.68.0.0/16" gcp_dev_secondary = "10.84.0.0/16" gcp_landing_landing_primary = "10.64.0.0/17" gcp_landing_landing_secondary = "10.80.0.0/17" gcp_dmz_primary = "10.64.127.0/17" gcp_dmz_secondary = "10.80.127.0/17" gcp_prod_primary = "10.72.0.0/16" gcp_prod_secondary = "10.88.0.0/16" }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L151) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L169) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L186) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L205) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L217) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L231) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L274) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ module "dev-spoke-project" {
|
|||
name = "dev-net-spoke-0"
|
||||
parent = var.folder_ids.networking-dev
|
||||
prefix = var.prefix
|
||||
services = [
|
||||
services = concat([
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
|
@ -31,7 +31,13 @@ module "dev-spoke-project" {
|
|||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ module "prod-spoke-project" {
|
|||
name = "prod-net-spoke-0"
|
||||
parent = var.folder_ids.networking-prod
|
||||
prefix = var.prefix
|
||||
services = [
|
||||
services = concat([
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
|
@ -31,7 +31,13 @@ module "prod-spoke-project" {
|
|||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -113,6 +113,16 @@ variable "factories_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "fast_features" {
|
||||
# tfdoc:variable:source 0-0-bootstrap
|
||||
description = "Selective control for top-level FAST features."
|
||||
type = object({
|
||||
gcve = optional(bool, false)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created."
|
||||
|
|
|
@ -332,21 +332,22 @@ Regions are defined via the `regions` variable which sets up a mapping between t
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L117) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L127) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L143) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L127) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L137) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L153) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | 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> |
|
||||
| [dns](variables.tf#L72) | DNS configuration. | <code title="object({ dev_resolvers = optional(list(string), []) enable_logging = optional(bool, true) prod_resolvers = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [enable_cloud_nat](variables.tf#L83) | Deploy Cloud NAT. | <code>bool</code> | | <code>false</code> | |
|
||||
| [essential_contacts](variables.tf#L90) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
|
||||
| [factories_config](variables.tf#L96) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L137) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L154) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L173) | Region definitions. | <code title="object({ primary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L183) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_dev_primary_config](variables.tf#L197) | VPN gateway configuration for onprem interconnection from dev in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_prod_primary_config](variables.tf#L240) | VPN gateway configuration for onprem interconnection from prod in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [fast_features](variables.tf#L117) | Selective control for top-level FAST features. | <code title="object({ gcve = optional(bool, false) })">object({…})</code> | | <code>{}</code> | <code>0-0-bootstrap</code> |
|
||||
| [outputs_location](variables.tf#L147) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L164) | IP ranges used for Private Service Access (e.g. CloudSQL). | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L183) | Region definitions. | <code title="object({ primary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L193) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_dev_primary_config](variables.tf#L207) | VPN gateway configuration for onprem interconnection from dev in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_prod_primary_config](variables.tf#L250) | VPN gateway configuration for onprem interconnection from prod in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ module "dev-spoke-project" {
|
|||
name = "dev-net-spoke-0"
|
||||
parent = var.folder_ids.networking-dev
|
||||
prefix = var.prefix
|
||||
services = [
|
||||
services = concat([
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
|
@ -31,7 +31,13 @@ module "dev-spoke-project" {
|
|||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
service_projects = []
|
||||
|
|
|
@ -22,7 +22,7 @@ module "prod-spoke-project" {
|
|||
name = "prod-net-spoke-0"
|
||||
parent = var.folder_ids.networking-prod
|
||||
prefix = var.prefix
|
||||
services = [
|
||||
services = concat([
|
||||
"container.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
|
@ -31,7 +31,13 @@ module "prod-spoke-project" {
|
|||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
service_projects = []
|
||||
|
|
|
@ -114,6 +114,16 @@ variable "factories_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "fast_features" {
|
||||
# tfdoc:variable:source 0-0-bootstrap
|
||||
description = "Selective control for top-level FAST features."
|
||||
type = object({
|
||||
gcve = optional(bool, false)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created."
|
||||
|
|
|
@ -484,25 +484,26 @@ DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L42) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L50) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L116) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L160) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L176) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L126) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ networking = string networking-dev = string networking-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [organization](variables.tf#L170) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [prefix](variables.tf#L186) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [alert_config](variables.tf#L17) | Configuration for monitoring alerts. | <code title="object({ vpn_tunnel_established = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) user_labels = optional(map(string), {}) })) vpn_tunnel_bandwidth = optional(object({ auto_close = optional(string, null) duration = optional(string, "120s") enabled = optional(bool, true) notification_channels = optional(list(string), []) threshold_mbys = optional(string, "187.5") user_labels = optional(map(string), {}) })) })">object({…})</code> | | <code title="{ vpn_tunnel_established = {} vpn_tunnel_bandwidth = {} }">{…}</code> | |
|
||||
| [custom_roles](variables.tf#L63) | 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> |
|
||||
| [dns](variables.tf#L72) | DNS configuration. | <code title="object({ enable_logging = optional(bool, true) resolvers = optional(list(string), []) })">object({…})</code> | | <code>{}</code> | |
|
||||
| [enable_cloud_nat](variables.tf#L82) | Deploy Cloud NAT. | <code>bool</code> | | <code>false</code> | |
|
||||
| [essential_contacts](variables.tf#L89) | Email used for essential contacts, unset if null. | <code>string</code> | | <code>null</code> | |
|
||||
| [factories_config](variables.tf#L95) | Configuration for network resource factories. | <code title="object({ data_dir = optional(string, "data") dns_policy_rules_file = optional(string, "data/dns-policy-rules.yaml") firewall_policy_name = optional(string, "net-default") })">object({…})</code> | | <code title="{ data_dir = "data" }">{…}</code> | |
|
||||
| [gcp_ranges](variables.tf#L126) | GCP address ranges in name => range format. | <code>map(string)</code> | | <code title="{ gcp_dev_primary = "10.68.0.0/16" gcp_dev_secondary = "10.84.0.0/16" gcp_landing_primary = "10.64.0.0/17" gcp_landing_secondary = "10.80.0.0/17" gcp_dmz_primary = "10.64.127.0/17" gcp_dmz_secondary = "10.80.127.0/17" gcp_prod_primary = "10.72.0.0/16" gcp_prod_secondary = "10.88.0.0/16" }">{…}</code> | |
|
||||
| [ncc_asn](variables.tf#L141) | The NCC Cloud Routers ASN configuration. | <code>map(number)</code> | | <code title="{ nva_primary = 64513 nva_secondary = 64514 landing = 64515 dmz = 64512 }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L152) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L170) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L187) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L206) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L218) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L232) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L275) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [zones](variables.tf#L318) | Zones in which NVAs are deployed. | <code>list(string)</code> | | <code>["b", "c"]</code> | |
|
||||
| [fast_features](variables.tf#L116) | Selective control for top-level FAST features. | <code title="object({ gcve = optional(bool, false) })">object({…})</code> | | <code>{}</code> | <code>0-0-bootstrap</code> |
|
||||
| [gcp_ranges](variables.tf#L136) | GCP address ranges in name => range format. | <code>map(string)</code> | | <code title="{ gcp_dev_primary = "10.68.0.0/16" gcp_dev_secondary = "10.84.0.0/16" gcp_landing_primary = "10.64.0.0/17" gcp_landing_secondary = "10.80.0.0/17" gcp_dmz_primary = "10.64.127.0/17" gcp_dmz_secondary = "10.80.127.0/17" gcp_prod_primary = "10.72.0.0/16" gcp_prod_secondary = "10.88.0.0/16" }">{…}</code> | |
|
||||
| [ncc_asn](variables.tf#L151) | The NCC Cloud Routers ASN configuration. | <code>map(number)</code> | | <code title="{ nva_primary = 64513 nva_secondary = 64514 landing = 64515 dmz = 64512 }">{…}</code> | |
|
||||
| [onprem_cidr](variables.tf#L162) | Onprem addresses in name => range format. | <code>map(string)</code> | | <code title="{ main = "10.0.0.0/24" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L180) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [psa_ranges](variables.tf#L197) | IP ranges used for Private Service Access (e.g. CloudSQL). Ranges is in name => range format. | <code title="object({ dev = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) prod = object({ ranges = map(string) export_routes = optional(bool, false) import_routes = optional(bool, false) peered_domains = optional(list(string), []) }) })">object({…})</code> | | <code>null</code> | |
|
||||
| [regions](variables.tf#L216) | Region definitions. | <code title="object({ primary = string secondary = string })">object({…})</code> | | <code title="{ primary = "europe-west1" secondary = "europe-west4" }">{…}</code> | |
|
||||
| [service_accounts](variables.tf#L228) | Automation service accounts in name => email format. | <code title="object({ data-platform-dev = string data-platform-prod = string gke-dev = string gke-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | | <code>null</code> | <code>1-resman</code> |
|
||||
| [vpn_onprem_primary_config](variables.tf#L242) | VPN gateway configuration for onprem interconnection in the primary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpn_onprem_secondary_config](variables.tf#L285) | VPN gateway configuration for onprem interconnection in the secondary region. | <code title="object({ peer_external_gateways = map(object({ redundancy_type = string interfaces = list(string) })) router_config = object({ create = optional(bool, true) asn = number name = optional(string) keepalive = optional(number) custom_advertise = optional(object({ all_subnets = bool ip_ranges = map(string) })) }) tunnels = map(object({ bgp_peer = object({ address = string asn = number route_priority = optional(number, 1000) custom_advertise = optional(object({ all_subnets = bool all_vpc_subnets = bool all_peer_vpc_subnets = bool ip_ranges = map(string) })) }) bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number })) })">object({…})</code> | | <code>null</code> | |
|
||||
| [zones](variables.tf#L328) | Zones in which NVAs are deployed. | <code>list(string)</code> | | <code>["b", "c"]</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ module "dev-spoke-project" {
|
|||
name = "dev-net-spoke-0"
|
||||
parent = var.folder_ids.networking-dev
|
||||
prefix = var.prefix
|
||||
services = [
|
||||
services = concat([
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
|
@ -30,7 +30,13 @@ module "dev-spoke-project" {
|
|||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ module "prod-spoke-project" {
|
|||
name = "prod-net-spoke-0"
|
||||
parent = var.folder_ids.networking-prod
|
||||
prefix = var.prefix
|
||||
services = [
|
||||
services = concat([
|
||||
"compute.googleapis.com",
|
||||
"dns.googleapis.com",
|
||||
"iap.googleapis.com",
|
||||
|
@ -30,7 +30,13 @@ module "prod-spoke-project" {
|
|||
"servicenetworking.googleapis.com",
|
||||
"stackdriver.googleapis.com",
|
||||
"vpcaccess.googleapis.com"
|
||||
]
|
||||
],
|
||||
(
|
||||
var.fast_features.gcve
|
||||
? ["vmwareengine.googleapis.com"]
|
||||
: []
|
||||
)
|
||||
)
|
||||
shared_vpc_host_config = {
|
||||
enabled = true
|
||||
}
|
||||
|
|
|
@ -113,6 +113,16 @@ variable "factories_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "fast_features" {
|
||||
# tfdoc:variable:source 0-0-bootstrap
|
||||
description = "Selective control for top-level FAST features."
|
||||
type = object({
|
||||
gcve = optional(bool, false)
|
||||
})
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created."
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# Google Cloud VMware Engine Stage
|
||||
|
||||
The GCVE stage builds on top of your foundations to create and set up projects and related resources, used for your Google Cloud VMware Engine (GCVE) private cloud environments.
|
||||
It is organized in folders representing environments (e.g. `dev`, `prod`), each implemented by a stand-alone Terraform setup.
|
||||
|
||||
This directory contains a [GCVE single region private cloud for the `prod` environment](./prod/) that can be used as-is or cloned with few changes to implement further environments. Refer to the example [`prod`/README.md](./prod/README.md) for configuration details.
|
||||
|
||||
With this stage and the [GCVE blueprints](./../../../blueprints/gcve/), you can rapidly deploy production-ready GCVE environments. These environments are fully optimized to integrate seamlessly with your Fabric FAST network topology. Explore the deployment patterns below to find the perfect fit for your use case."
|
||||
|
||||
## TOC
|
||||
|
||||
<!-- BEGIN TOC -->
|
||||
- [TOC](#toc)
|
||||
- [Deployment Patterns](#deployment-patterns)
|
||||
- [Single Region](#single-region)
|
||||
- [Standalone VPC for a sigle region GCVE deployment](#standalone-vpc-for-a-sigle-region-gcve-deployment)
|
||||
- [Separate VPC Environments for individual dedicated GCVE deployments](#separate-vpc-environments-for-individual-dedicated-gcve-deployments)
|
||||
<!-- END TOC -->
|
||||
|
||||
## Deployment Patterns
|
||||
### Single Region
|
||||
#### Standalone VPC for a sigle region GCVE deployment
|
||||
<p align="center">
|
||||
<img src="diagram0.png" alt="Standalone Shared VPC for a sigle region GCVE deployment">
|
||||
</p>
|
||||
|
||||
#### Separate VPC Environments for individual dedicated GCVE deployments
|
||||
<p align="center">
|
||||
<img src="diagram1.png" alt="Separate VPC Environments for individual dedicated GCVE deployments">
|
||||
</p>
|
||||
|
||||
|
||||
<!-- BEGIN TFDOC -->
|
||||
<!-- END TFDOC -->
|
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
|
@ -0,0 +1,134 @@
|
|||
# GCVE Private Clouds for Production Environment
|
||||
|
||||
This stage provides the Terraform content for the creation and management of multiple GCVE private clouds which are connected to an existing network. The network infrastructure needs to be deployed before executing this stage by executing the respective Fabric FAST stage (`2-networking-*`). This stage can be replicated for complex GCVE designs requiring a separate management of the network infrastructure (VEN) and the access domain or for other constraints which make you decide to have indipendent GCVE environments (e.g dev/prod, region or team serparation).
|
||||
|
||||
## Design overview and choices
|
||||
|
||||
> A more comprehensive description of the GCVE architecture and approach can be found in the [GCVE Private Cloud Minimal blueprint](../../../../blueprints/gcve/pc-minimal/). The blueprint is wrapped and configured here to leverage the FAST flow.
|
||||
|
||||
The GCVE stage creates a project and all the expected resources in a well-defined context, usually an ad-hoc folder managed by the resource management stage. Resources are organized by environment within this folder.
|
||||
|
||||
|
||||
## How to run this stage
|
||||
|
||||
This stage is meant to be executed after the FAST "foundational" stages: bootstrap, resource management, security and networking stages.
|
||||
|
||||
It is also possible to run this stage in isolation. Refer to the *[Running in isolation](#running-in-isolation)* section below for details.
|
||||
|
||||
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.
|
||||
|
||||
### Provider and Terraform variables
|
||||
|
||||
As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here.
|
||||
|
||||
The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run.
|
||||
|
||||
```bash
|
||||
../../../stage-links.sh ~/fast-config
|
||||
|
||||
# copy and paste the following commands for '3-gcve'
|
||||
|
||||
ln -s ~/fast-config/providers/3-gcve-dev-providers.tf ./
|
||||
ln -s ~/fast-config/tfvars/0-globals.auto.tfvars.json ./
|
||||
ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./
|
||||
ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./
|
||||
ln -s ~/fast-config/tfvars/2-networking.auto.tfvars.json ./
|
||||
```
|
||||
|
||||
```bash
|
||||
../../../stage-links.sh gs://xxx-prod-iac-core-outputs-0
|
||||
|
||||
# copy and paste the following commands for '3-gcve'
|
||||
|
||||
gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/3-gcve-dev-providers.tf ./
|
||||
gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-globals.auto.tfvars.json ./
|
||||
gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./
|
||||
gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./
|
||||
gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-networking.auto.tfvars.json ./
|
||||
```
|
||||
|
||||
### Impersonating the automation service account
|
||||
|
||||
The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups.
|
||||
|
||||
### Variable configuration
|
||||
|
||||
Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets:
|
||||
|
||||
- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `0-globals.auto.tfvars.json` file linked or copied above
|
||||
- variables which refer to resources managed by previous stage, which are prepopulated here via the `*.auto.tfvars.json` files linked or copied above
|
||||
- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file
|
||||
|
||||
The full list can be found in the [Variables](#variables) table at the bottom of this document.
|
||||
|
||||
### Running the stage
|
||||
|
||||
Once provider and variable values are in place and the correct user is configured, the stage can be run:
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
terraform apply
|
||||
```
|
||||
|
||||
### Running in isolation
|
||||
|
||||
This stage can be run in isolation by providing the necessary variables, but it's really meant to be used as part of the FAST flow after the "foundational stages" ([`0-bootstrap`](../../0-bootstrap), [`1-resman`](../../1-resman), [`2-networking`](../../2-networking-b-vpn).
|
||||
|
||||
When running in isolation, the following roles are needed on the principal used to apply Terraform:
|
||||
|
||||
- on the organization or network folder level
|
||||
- `roles/xpnAdmin` or a custom role which includes the following permissions
|
||||
- `"compute.organizations.enableXpnResource"`,
|
||||
- `"compute.organizations.disableXpnResource"`,
|
||||
- `"compute.subnetworks.setIamPolicy"`,
|
||||
- on each folder where projects are created
|
||||
- `"roles/logging.admin"`
|
||||
- `"roles/owner"`
|
||||
- `"roles/resourcemanager.folderAdmin"`
|
||||
- `"roles/resourcemanager.projectCreator"`
|
||||
- on the host project for the Shared VPC
|
||||
- `"roles/browser"`
|
||||
- `"roles/compute.viewer"`
|
||||
- on the organization or billing account
|
||||
- `roles/billing.admin`
|
||||
|
||||
The VPC host project, VPC and subnets should already exist.
|
||||
|
||||
<!-- TFDOC OPTS files:1 show_extra:1 -->
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Files
|
||||
|
||||
| name | description | modules | resources |
|
||||
|---|---|---|---|
|
||||
| [main.tf](./main.tf) | GCVE private cloud for development environment. | <code>pc-minimal</code> | |
|
||||
| [outputs.tf](./outputs.tf) | Output variables. | | <code>google_storage_bucket_object</code> · <code>local_file</code> |
|
||||
| [variables.tf](./variables.tf) | Module variables. | | |
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default | producer |
|
||||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L25) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | <code title="object({ id = string is_org_level = optional(bool, true) })">object({…})</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L38) | Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created. | <code title="object({ gcve-prod = string })">object({…})</code> | ✓ | | <code>1-resman</code> |
|
||||
| [host_project_ids](variables.tf#L59) | Host project for the shared VPC. | <code title="object({ prod-spoke-0 = string })">object({…})</code> | ✓ | | <code>2-networking</code> |
|
||||
| [organization](variables.tf#L80) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-globals</code> |
|
||||
| [prefix](variables.tf#L96) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
|
||||
| [private_cloud_configs](variables.tf#L102) | The VMware private cloud configurations. The key is the unique private cloud name suffix. | <code title="map(object({ cidr = string zone = string additional_cluster_configs = optional(map(object({ custom_core_count = optional(number) node_count = optional(number, 3) node_type_id = optional(string, "standard-72") })), {}) management_cluster_config = optional(object({ custom_core_count = optional(number) name = optional(string, "mgmt-cluster") node_count = optional(number, 3) node_type_id = optional(string, "standard-72") }), {}) description = optional(string, "Managed by Terraform.") }))">map(object({…}))</code> | ✓ | | |
|
||||
| [vpc_self_links](variables.tf#L131) | Self link for the shared VPC. | <code title="object({ prod-spoke-0 = string })">object({…})</code> | ✓ | | <code>2-networking</code> |
|
||||
| [groups_gcve](variables.tf#L46) | GCVE groups. | <code title="object({ gcp-gcve-admins = string gcp-gcve-viewers = string })">object({…})</code> | | <code title="{ gcp-gcve-admins = "gcp-gcve-admins" gcp-gcve-viewers = "gcp-gcve-viewers" }">{…}</code> | |
|
||||
| [iam](variables.tf#L67) | Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [labels](variables.tf#L74) | Project-level labels. | <code>map(string)</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L90) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_services](variables.tf#L124) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive | consumers |
|
||||
|---|---|:---:|---|
|
||||
| [project_id](outputs.tf#L46) | GCVE project id. | | |
|
||||
| [vmw_engine_network_config](outputs.tf#L51) | VMware engine network configuration. | | |
|
||||
| [vmw_engine_network_peerings](outputs.tf#L56) | The peerings created towards the user VPC or other VMware engine networks. | | |
|
||||
| [vmw_engine_private_clouds](outputs.tf#L61) | VMware engine private cloud resources. | | |
|
||||
| [vmw_private_cloud_network](outputs.tf#L66) | VMware engine network. | | |
|
||||
<!-- END TFDOC -->
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Copyright 2024 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 GCVE private cloud for development environment.
|
||||
locals {
|
||||
groups_gcve = {
|
||||
for k, v in var.groups_gcve : k => (
|
||||
can(regex("^[a-zA-Z]+:", v))
|
||||
? v
|
||||
: "group:${v}@${var.organization.domain}"
|
||||
)
|
||||
}
|
||||
peer_network = {
|
||||
for k, v in var.vpc_self_links : k => (
|
||||
trimprefix(v, "https://www.googleapis.com/compute/v1/")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module "gcve-pc" {
|
||||
source = "../../../../blueprints/gcve/pc-minimal"
|
||||
billing_account_id = var.billing_account.id
|
||||
folder_id = var.folder_ids.gcve-prod
|
||||
project_id = "gcve-0"
|
||||
groups = local.groups_gcve
|
||||
iam = var.iam
|
||||
labels = merge(var.labels, { environment = "prod" })
|
||||
prefix = "${var.prefix}-prod"
|
||||
project_services = var.project_services
|
||||
|
||||
network_peerings = {
|
||||
prod-spoke-ven = {
|
||||
peer_network = local.peer_network.prod-spoke-0
|
||||
peer_project_id = var.host_project_ids.prod-spoke-0
|
||||
configure_peer_network = true
|
||||
custom_routes = {
|
||||
export_to_peer = true
|
||||
import_from_peer = true
|
||||
export_to_ven = true
|
||||
import_from_ven = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private_cloud_configs = var.private_cloud_configs
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
# Copyright 2024 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
|
||||
#
|
||||
# https://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 Output variables.
|
||||
|
||||
locals {
|
||||
tfvars = {
|
||||
project_ids = {
|
||||
gcve-dev = module.gcve-pc.project_id
|
||||
}
|
||||
vmw_engine_network_config = module.gcve-pc.vmw_engine_network_config
|
||||
vmw_engine_network_peerings = module.gcve-pc.vmw_engine_network_peerings
|
||||
vmw_engine_private_clouds = module.gcve-pc.vmw_engine_private_clouds
|
||||
vmw_private_cloud_network = module.gcve-pc.vmw_private_cloud_network
|
||||
}
|
||||
}
|
||||
|
||||
# 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/3-gcve-dev.auto.tfvars.json"
|
||||
content = jsonencode(local.tfvars)
|
||||
}
|
||||
|
||||
resource "google_storage_bucket_object" "tfvars" {
|
||||
bucket = var.automation.outputs_bucket
|
||||
name = "tfvars/3-gcve-dev.auto.tfvars.json"
|
||||
content = jsonencode(local.tfvars)
|
||||
}
|
||||
|
||||
# outputs
|
||||
|
||||
output "project_id" {
|
||||
description = "GCVE project id."
|
||||
value = module.gcve-pc.project_id
|
||||
}
|
||||
|
||||
output "vmw_engine_network_config" {
|
||||
description = "VMware engine network configuration."
|
||||
value = module.gcve-pc.vmw_engine_network_config
|
||||
}
|
||||
|
||||
output "vmw_engine_network_peerings" {
|
||||
description = "The peerings created towards the user VPC or other VMware engine networks."
|
||||
value = module.gcve-pc.vmw_engine_network_peerings
|
||||
}
|
||||
|
||||
output "vmw_engine_private_clouds" {
|
||||
description = "VMware engine private cloud resources."
|
||||
value = module.gcve-pc.vmw_engine_private_clouds
|
||||
}
|
||||
|
||||
output "vmw_private_cloud_network" {
|
||||
description = "VMware engine network."
|
||||
value = module.gcve-pc.vmw_private_cloud_network
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* Copyright 2024 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 "automation" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Automation resources created by the bootstrap stage."
|
||||
type = object({
|
||||
outputs_bucket = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "billing_account" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Billing account id. If billing account is not part of the same org set `is_org_level` to false."
|
||||
type = object({
|
||||
id = string
|
||||
is_org_level = optional(bool, true)
|
||||
})
|
||||
validation {
|
||||
condition = var.billing_account.is_org_level != null
|
||||
error_message = "Invalid `null` value for `billing_account.is_org_level`."
|
||||
}
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 1-resman
|
||||
description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created."
|
||||
type = object({
|
||||
gcve-prod = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "groups_gcve" {
|
||||
description = "GCVE groups."
|
||||
type = object({
|
||||
gcp-gcve-admins = string
|
||||
gcp-gcve-viewers = string
|
||||
})
|
||||
default = {
|
||||
gcp-gcve-admins = "gcp-gcve-admins"
|
||||
gcp-gcve-viewers = "gcp-gcve-viewers"
|
||||
}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "host_project_ids" {
|
||||
# tfdoc:variable:source 2-networking
|
||||
description = "Host project for the shared VPC."
|
||||
type = object({
|
||||
prod-spoke-0 = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "iam" {
|
||||
description = "Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "labels" {
|
||||
description = "Project-level labels."
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
# tfdoc:variable:source 00-globals
|
||||
description = "Organization details."
|
||||
type = object({
|
||||
domain = string
|
||||
id = number
|
||||
customer_id = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "outputs_location" {
|
||||
description = "Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
# tfdoc:variable:source 0-bootstrap
|
||||
description = "Prefix used for resources that need unique names. Use 9 characters or less."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "private_cloud_configs" {
|
||||
description = "The VMware private cloud configurations. The key is the unique private cloud name suffix."
|
||||
type = map(object({
|
||||
cidr = string
|
||||
zone = string
|
||||
# The key is the unique additional cluster name suffix
|
||||
additional_cluster_configs = optional(map(object({
|
||||
custom_core_count = optional(number)
|
||||
node_count = optional(number, 3)
|
||||
node_type_id = optional(string, "standard-72")
|
||||
})), {})
|
||||
management_cluster_config = optional(object({
|
||||
custom_core_count = optional(number)
|
||||
name = optional(string, "mgmt-cluster")
|
||||
node_count = optional(number, 3)
|
||||
node_type_id = optional(string, "standard-72")
|
||||
}), {})
|
||||
description = optional(string, "Managed by Terraform.")
|
||||
}))
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "project_services" {
|
||||
description = "Additional project services to enable."
|
||||
type = list(string)
|
||||
default = []
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "vpc_self_links" {
|
||||
# tfdoc:variable:source 2-networking
|
||||
description = "Self link for the shared VPC."
|
||||
type = object({
|
||||
prod-spoke-0 = string
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -160,4 +160,5 @@ module "gcve-pc" {
|
|||
| [vmw_engine_network_peerings](outputs.tf#L22) | The peerings created towards the user VPC or other VMware engine networks. | |
|
||||
| [vmw_engine_network_policies](outputs.tf#L27) | The network policies associated to the VMware engine network. | |
|
||||
| [vmw_engine_private_clouds](outputs.tf#L32) | VMware engine private cloud resources. | |
|
||||
| [vmw_private_cloud_network](outputs.tf#L37) | VMware engine network. | |
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -92,6 +92,8 @@ resource "google_vmwareengine_private_cloud" "vmw_engine_private_clouds" {
|
|||
name = "${var.prefix}-${each.key}"
|
||||
description = each.value.description
|
||||
|
||||
type = each.value.management_cluster_config.node_count == 1 ? "TIME_LIMITED" : "STANDARD"
|
||||
|
||||
network_config {
|
||||
management_cidr = each.value.cidr
|
||||
vmware_engine_network = local.vmw_network.id
|
||||
|
|
|
@ -33,3 +33,8 @@ output "vmw_engine_private_clouds" {
|
|||
description = "VMware engine private cloud resources."
|
||||
value = google_vmwareengine_private_cloud.vmw_engine_private_clouds
|
||||
}
|
||||
|
||||
output "vmw_private_cloud_network" {
|
||||
description = "VMware engine network."
|
||||
value = google_vmwareengine_network.private_cloud_network.0
|
||||
}
|
||||
|
|
|
@ -364,7 +364,7 @@ counts:
|
|||
google_logging_project_bucket_config: 3
|
||||
google_org_policy_policy: 20
|
||||
google_organization_iam_binding: 27
|
||||
google_organization_iam_custom_role: 6
|
||||
google_organization_iam_custom_role: 7
|
||||
google_organization_iam_member: 35
|
||||
google_project: 3
|
||||
google_project_iam_binding: 19
|
||||
|
@ -381,4 +381,4 @@ counts:
|
|||
google_tags_tag_key: 1
|
||||
google_tags_tag_value: 1
|
||||
modules: 17
|
||||
resources: 192
|
||||
resources: 193
|
||||
|
|
|
@ -43,7 +43,7 @@ counts:
|
|||
google_logging_project_bucket_config: 3
|
||||
google_org_policy_policy: 20
|
||||
google_organization_iam_binding: 27
|
||||
google_organization_iam_custom_role: 6
|
||||
google_organization_iam_custom_role: 7
|
||||
google_organization_iam_member: 22
|
||||
google_project: 3
|
||||
google_project_iam_binding: 19
|
||||
|
@ -61,10 +61,11 @@ counts:
|
|||
google_tags_tag_value: 1
|
||||
local_file: 7
|
||||
modules: 16
|
||||
resources: 183
|
||||
resources: 184
|
||||
|
||||
outputs:
|
||||
custom_roles:
|
||||
gcve_network_admin: organizations/123456789012/roles/gcveNetworkAdmin
|
||||
organization_admin_viewer: organizations/123456789012/roles/organizationAdminViewer
|
||||
organization_iam_admin: organizations/123456789012/roles/organizationIamAdmin
|
||||
service_project_network_admin: organizations/123456789012/roles/serviceProjectNetworkAdmin
|
||||
|
|
|
@ -13,6 +13,7 @@ billing_account = {
|
|||
}
|
||||
custom_roles = {
|
||||
# organization_iam_admin = "organizations/123456789012/roles/organizationIamAdmin",
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
}
|
||||
|
|
|
@ -416,7 +416,7 @@ values:
|
|||
|
||||
counts:
|
||||
google_folder: 57
|
||||
google_folder_iam_binding: 67
|
||||
google_folder_iam_binding: 69
|
||||
google_organization_iam_member: 5
|
||||
google_project_iam_member: 4
|
||||
google_service_account: 4
|
||||
|
@ -427,6 +427,6 @@ counts:
|
|||
google_storage_bucket_object: 5
|
||||
google_tags_tag_binding: 5
|
||||
google_tags_tag_key: 3
|
||||
google_tags_tag_value: 9
|
||||
google_tags_tag_value: 10
|
||||
modules: 64
|
||||
resources: 173
|
||||
resources: 176
|
||||
|
|
|
@ -13,6 +13,7 @@ billing_account = {
|
|||
}
|
||||
custom_roles = {
|
||||
# organization_iam_admin = "organizations/123456789012/roles/organizationIamAdmin",
|
||||
gcve_network_admin = "organizations/123456789012/roles/gcveNetworkAdmin"
|
||||
service_project_network_admin = "organizations/123456789012/roles/xpnServiceAdmin"
|
||||
storage_viewer = "organizations/123456789012/roles/storageViewer"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
counts:
|
||||
google_folder: 5
|
||||
google_folder_iam_binding: 19
|
||||
google_folder_iam_binding: 21
|
||||
google_organization_iam_member: 5
|
||||
google_project_iam_member: 4
|
||||
google_service_account: 4
|
||||
|
@ -25,6 +25,6 @@ counts:
|
|||
google_storage_bucket_object: 5
|
||||
google_tags_tag_binding: 5
|
||||
google_tags_tag_key: 3
|
||||
google_tags_tag_value: 9
|
||||
google_tags_tag_value: 10
|
||||
modules: 12
|
||||
resources: 73
|
||||
resources: 76
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# 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.
|
|
@ -0,0 +1,53 @@
|
|||
automation = {
|
||||
federated_identity_pool = null
|
||||
federated_identity_providers = null
|
||||
project_id = "fast-prod-automation"
|
||||
project_number = 123456
|
||||
outputs_bucket = "test"
|
||||
service_accounts = {
|
||||
resman-r = "em-dev-gcve-0r@fast2-prod-iac-core-0.iam.gserviceaccount.com"
|
||||
}
|
||||
}
|
||||
|
||||
billing_account = {
|
||||
id = "000000-111111-222222"
|
||||
}
|
||||
|
||||
folder_ids = {
|
||||
gcve-prod = "folders/00000000000000"
|
||||
}
|
||||
|
||||
groups_gcve = {
|
||||
gcp-gcve-admins = "gcp-gcve-admins",
|
||||
gcp-gcve-viewers = "gcp-gcve-viewers"
|
||||
}
|
||||
|
||||
host_project_ids = {
|
||||
prod-spoke-0 = "prod-spoke-0"
|
||||
}
|
||||
|
||||
organization = {
|
||||
domain = "fast.example.com"
|
||||
id = 123456789012
|
||||
customer_id = "C00000000"
|
||||
}
|
||||
|
||||
prefix = "fast3"
|
||||
|
||||
private_cloud_configs = {
|
||||
dev-pc = {
|
||||
cidr = "172.26.16.0/22"
|
||||
zone = "europe-west8-a"
|
||||
management_cluster_config = {
|
||||
name = "mgmt-cluster"
|
||||
node_count = 1
|
||||
node_type_id = "standard-72"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vpc_self_links = {
|
||||
"prod-spoke-0" = "https://www.googleapis.com/compute/v1/projects/em-prod-net-spoke-0/global/networks/prod-spoke-0",
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Copyright 2024 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.
|
||||
|
||||
counts:
|
||||
google_project: 1
|
||||
google_project_iam_binding: 2
|
||||
google_project_service: 1
|
||||
google_storage_bucket_object: 1
|
||||
google_vmwareengine_network: 1
|
||||
google_vmwareengine_network_peering: 2
|
||||
google_vmwareengine_private_cloud: 1
|
||||
modules: 3
|
||||
resources: 9
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# Copyright 2024 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: fast/stages/3-gcve/prod
|
||||
|
||||
tests:
|
||||
simple:
|
||||
tfvars:
|
||||
- simple.tfvars
|
||||
inventory:
|
||||
- simple.yaml
|
Loading…
Reference in New Issue