diff --git a/.gitignore b/.gitignore
index cbf110dd29..a4e6b621fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+venv/*
+*/venv/*
**/.terraform
**/terraform.tfstate*
**/terraform.tfvars
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5a71669a2d..609382f2c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
### BLUEPRINTS
+- [[#1838](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1838)] Simplify #1836 fix, Avoid map-related casting errors in project factory ([wiktorn](https://github.com/wiktorn))
+- [[#1836](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1836)] **incompatible change:** Avoid map-related casting errors in project factory ([ludoo](https://github.com/ludoo))
+- [[#1832](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1832)] [Minimal Data Platform] Fix Landing and curated IAM ([lcaggio](https://github.com/lcaggio))
+- [[#1825](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1825)] Handling SQL IP address issue ([aurelienlegrand](https://github.com/aurelienlegrand))
- [[#1821](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1821)] [net-address] enable ipv6 ([LucaPrete](https://github.com/LucaPrete))
- [[#1814](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1814)] **incompatible change:** Allow specifying arbitrary project roles for service accounts in project factory ([ludoo](https://github.com/ludoo))
- [[#1812](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1812)] Stop wrapping yamldecode with try() ([sruffilli](https://github.com/sruffilli))
@@ -21,12 +25,15 @@ All notable changes to this project will be documented in this file.
### DOCUMENTATION
+- [[#1832](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1832)] [Minimal Data Platform] Fix Landing and curated IAM ([lcaggio](https://github.com/lcaggio))
+- [[#1831](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1831)] Update wording in FAST and gcve module READMEs ([bluPhy](https://github.com/bluPhy))
- [[#1782](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1782)] Add upper cap to versions, update copyright notices ([sruffilli](https://github.com/sruffilli))
- [[#1773](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1773)] Add service usage consumer role to IaC SAs, refactor delegated grants in FAST ([ludoo](https://github.com/ludoo))
- [[#1743](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1743)] Billing account module ([ludoo](https://github.com/ludoo))
### FAST
+- [[#1836](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1836)] **incompatible change:** Avoid map-related casting errors in project factory ([ludoo](https://github.com/ludoo))
- [[#1818](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1818)] FAST: rename VPC-related files to `net-*` ([sruffilli](https://github.com/sruffilli))
- [[#1812](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1812)] Stop wrapping yamldecode with try() ([sruffilli](https://github.com/sruffilli))
- [[#1810](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1810)] FAST: Add access transparency logs to the default sinks ([sruffilli](https://github.com/sruffilli))
@@ -49,6 +56,14 @@ All notable changes to this project will be documented in this file.
### MODULES
+- [[#1841](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1841)] Fix modules to support new Apigee X environment types ([Teodelas](https://github.com/Teodelas))
+- [[#1842](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1842)] Bump provider version to 5.4.0 ([wiktorn](https://github.com/wiktorn))
+- [[#1823](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1823)] Add end-to-end tests for project module ([wiktorn](https://github.com/wiktorn))
+- [[#1837](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1837)] Added envoy as SNI dynamic forward proxy to cloud-config-container ([apichick](https://github.com/apichick))
+- [[#1839](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1839)] Added create_before_destroy = true for self-managed certificates ([apichick](https://github.com/apichick))
+- [[#1833](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1833)] Net VPC Peering: added stack_type field ([cmalpe](https://github.com/cmalpe))
+- [[#1826](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1826)] Add public_access_prevention field to GCS module ([devuonocar](https://github.com/devuonocar))
+- [[#1817](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1817)] KMS module: Import job feature ([cmalpe](https://github.com/cmalpe))
- [[#1822](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1822)] Billing budget factory ([ludoo](https://github.com/ludoo))
- [[#1821](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1821)] [net-address] enable ipv6 ([LucaPrete](https://github.com/LucaPrete))
- [[#1820](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1820)] Added iam_bindings and iam_bindings_additive to apigee module ([apichick](https://github.com/apichick))
diff --git a/blueprints/data-solutions/cloudsql-multiregion/cloudsql.tf b/blueprints/data-solutions/cloudsql-multiregion/cloudsql.tf
index e25812df5b..5dab5d6b60 100644
--- a/blueprints/data-solutions/cloudsql-multiregion/cloudsql.tf
+++ b/blueprints/data-solutions/cloudsql-multiregion/cloudsql.tf
@@ -34,7 +34,9 @@ module "db" {
}
databases = [var.postgres_database]
users = {
- postgres = var.postgres_user_password
+ postgres = {
+ password = var.postgres_user_password
+ }
}
}
diff --git a/blueprints/data-solutions/data-platform-minimal/01-landing.tf b/blueprints/data-solutions/data-platform-minimal/01-landing.tf
index 2b4d5165fa..3539e001ac 100644
--- a/blueprints/data-solutions/data-platform-minimal/01-landing.tf
+++ b/blueprints/data-solutions/data-platform-minimal/01-landing.tf
@@ -22,8 +22,9 @@ locals {
"roles/storage.objectViewer" = [
module.processing-sa-cmp-0.iam_email
]
- "roles/storage.objectAdmin" = [
- module.processing-sa-0.iam_email
+ "roles/storage.admin" = [
+ module.processing-sa-0.iam_email,
+ local.groups_iam.data-engineers
]
}
# this only works because the service account module uses a static output
diff --git a/blueprints/data-solutions/data-platform-minimal/03-curated.tf b/blueprints/data-solutions/data-platform-minimal/03-curated.tf
index 81112c9b88..faf9301129 100644
--- a/blueprints/data-solutions/data-platform-minimal/03-curated.tf
+++ b/blueprints/data-solutions/data-platform-minimal/03-curated.tf
@@ -58,11 +58,11 @@ locals {
]
"roles/storage.objectViewer" = [
module.cur-sa-0.iam_email,
- local.groups_iam.data-analysts,
- local.groups_iam.data-engineers
+ local.groups_iam.data-analysts
]
- "roles/storage.objectAdmin" = [
- module.processing-sa-0.iam_email
+ "roles/storage.admin" = [
+ module.processing-sa-0.iam_email,
+ local.groups_iam.data-engineers
]
}
# this only works because the service account module uses a static output
diff --git a/blueprints/data-solutions/data-platform-minimal/IAM.md b/blueprints/data-solutions/data-platform-minimal/IAM.md
index d5c1ccbb34..ea796fbf0b 100644
--- a/blueprints/data-solutions/data-platform-minimal/IAM.md
+++ b/blueprints/data-solutions/data-platform-minimal/IAM.md
@@ -16,15 +16,16 @@ Legend: +
additive, •
conditional.
| members | roles |
|---|---|
|gcp-data-analysts
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) |
-|gcp-data-engineers
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) |
+|gcp-data-engineers
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) |
|SERVICE_IDENTITY_service-networking
serviceAccount|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) +
|
|cur-sa-0
serviceAccount|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) |
-|prc-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) |
+|prc-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) |
## Project lnd
| members | roles |
|---|---|
+|gcp-data-engineers
group|[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) |
|lnd-sa-0
serviceAccount|[roles/storage.objectCreator](https://cloud.google.com/iam/docs/understanding-roles#storage.objectCreator) |
|prc-0
serviceAccount|[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) |
|prc-cmp-0
serviceAccount|[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) |
diff --git a/blueprints/data-solutions/sqlserver-alwayson/secrets.tf b/blueprints/data-solutions/sqlserver-alwayson/secrets.tf
index 2a0bba8d6c..f25871deb8 100644
--- a/blueprints/data-solutions/sqlserver-alwayson/secrets.tf
+++ b/blueprints/data-solutions/sqlserver-alwayson/secrets.tf
@@ -19,7 +19,9 @@ module "secret-manager" {
source = "../../../modules/secret-manager"
project_id = var.project_id
secrets = {
- (local.ad_user_password_secret) = null
+ (local.ad_user_password_secret) = {
+ locations = null
+ }
}
versions = {
(local.ad_user_password_secret) = {
diff --git a/blueprints/data-solutions/vertex-mlops/ci-cd.tf b/blueprints/data-solutions/vertex-mlops/ci-cd.tf
index 3c7c863151..28fb320bc1 100644
--- a/blueprints/data-solutions/vertex-mlops/ci-cd.tf
+++ b/blueprints/data-solutions/vertex-mlops/ci-cd.tf
@@ -57,10 +57,12 @@ module "secret-manager" {
project_id = module.project.project_id
source = "../../../modules/secret-manager"
secrets = {
- github-key = [var.region]
- }
- encryption_key = {
- "${var.region}" = var.service_encryption_keys.secretmanager
+ github-key = {
+ locations = [var.region]
+ keys = {
+ "${var.region}" = var.service_encryption_keys.secretmanager
+ }
+ }
}
iam = {
github-key = {
diff --git a/blueprints/factories/project-factory/README.md b/blueprints/factories/project-factory/README.md
index d2d07c43d6..2e67158277 100644
--- a/blueprints/factories/project-factory/README.md
+++ b/blueprints/factories/project-factory/README.md
@@ -55,11 +55,9 @@ module "project-factory" {
prefix = "test-pf"
}
# location where the yaml files are read from
- factory_data = {
- data_path = "data"
- }
+ factory_data_path = "data"
}
-# tftest modules=6 resources=17 files=prj-app-1,prj-app-2
+# tftest modules=7 resources=26 files=prj-app-1,prj-app-2,prj-app-3 inventory=example.yaml
```
```yaml
@@ -72,7 +70,8 @@ service_encryption_key_ids:
compute:
- projects/kms-central-prj/locations/europe-west3/keyRings/my-keyring/cryptoKeys/europe3-gce
services:
-- storage.googleapis.com
+ - container.googleapis.com
+ - storage.googleapis.com
service_accounts:
app-1-be:
iam_project_roles:
@@ -86,29 +85,35 @@ service_accounts:
```yaml
labels:
- app: app-1
+ app: app-2
team: foo
parent: folders/12345678
service_accounts:
app-2-be: {}
-org_policies:
- compute.disableGuestAttributesAccess:
- rules:
- - enforce: false
- iam.disableServiceAccountKeyCreation:
- rules:
- - enforce: false
+services:
+- compute.googleapis.com
+- run.googleapis.com
+- storage.googleapis.com
shared_vpc_service_config:
host_project: foo-host
# tftest-file id=prj-app-2 path=data/prj-app-2.yaml
```
+
+```yaml
+parent: folders/12345678
+services:
+- run.googleapis.com
+- storage.googleapis.com
+
+# tftest-file id=prj-app-3 path=data/prj-app-3.yaml
+```
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [factory_data](variables.tf#L88) | Project data from either YAML files or externally parsed data. | object({…})
| ✓ | |
+| [factory_data_path](variables.tf#L88) | Path to folder with YAML project description data files. | string
| ✓ | |
| [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | object({…})
| | {}
|
| [data_merges](variables.tf#L46) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | object({…})
| | {}
|
| [data_overrides](variables.tf#L66) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | object({…})
| | {}
|
@@ -120,3 +125,53 @@ shared_vpc_service_config:
| [projects](outputs.tf#L17) | Project module outputs. | |
| [service_accounts](outputs.tf#L22) | Service account emails. | |
+## Tests
+
+These tests validate fixes to the project factory.
+
+```hcl
+module "project-factory" {
+ source = "./fabric/blueprints/factories/project-factory"
+ data_defaults = {
+ billing_account = "012345-67890A-ABCDEF"
+ }
+ data_merges = {
+ labels = {
+ owner = "foo"
+ }
+ services = [
+ "compute.googleapis.com"
+ ]
+ }
+ data_overrides = {
+ prefix = "foo"
+ }
+ factory_data_path = "data"
+}
+# tftest modules=4 resources=14 files=test-0,test-1,test-2
+```
+
+```yaml
+parent: folders/1234567890
+services:
+ - iam.googleapis.com
+ - contactcenteraiplatform.googleapis.com
+ - container.googleapis.com
+# tftest-file id=test-0 path=data/test-0.yaml
+```
+
+```yaml
+parent: folders/1234567890
+services:
+ - iam.googleapis.com
+ - contactcenteraiplatform.googleapis.com
+# tftest-file id=test-1 path=data/test-1.yaml
+```
+
+```yaml
+parent: folders/1234567890
+services:
+ - iam.googleapis.com
+ - storage.googleapis.com
+# tftest-file id=test-2 path=data/test-2.yaml
+```
diff --git a/blueprints/factories/project-factory/factory.tf b/blueprints/factories/project-factory/factory.tf
index e0351a0aa1..eabb551ad1 100644
--- a/blueprints/factories/project-factory/factory.tf
+++ b/blueprints/factories/project-factory/factory.tf
@@ -16,15 +16,13 @@
locals {
_data = (
- var.factory_data.data != null
- ? var.factory_data.data
- : {
- for f in fileset("${local._data_path}", "**/*.yaml") :
+ {
+ for f in fileset(local._data_path, "**/*.yaml") :
trimsuffix(f, ".yaml") => yamldecode(file("${local._data_path}/${f}"))
}
)
- _data_path = var.factory_data.data_path == null ? null : pathexpand(
- var.factory_data.data_path
+ _data_path = var.factory_data_path == null ? null : pathexpand(
+ var.factory_data_path
)
projects = {
for k, v in local._data : k => merge(v, {
diff --git a/blueprints/factories/project-factory/variables.tf b/blueprints/factories/project-factory/variables.tf
index 55578562f9..a0ff81ebd3 100644
--- a/blueprints/factories/project-factory/variables.tf
+++ b/blueprints/factories/project-factory/variables.tf
@@ -85,18 +85,8 @@ variable "data_overrides" {
default = {}
}
-variable "factory_data" {
- description = "Project data from either YAML files or externally parsed data."
- type = object({
- data = optional(map(any))
- data_path = optional(string)
- })
- nullable = false
- validation {
- condition = (
- (var.factory_data.data != null ? 1 : 0) +
- (var.factory_data.data_path != null ? 1 : 0)
- ) == 1
- error_message = "One of data or data_path needs to be set."
- }
+variable "factory_data_path" {
+ description = "Path to folder with YAML project description data files."
+ type = string
+ nullable = false
}
diff --git a/blueprints/third-party-solutions/phpipam/cloudsql.tf b/blueprints/third-party-solutions/phpipam/cloudsql.tf
index 24a47b661c..f3b7a78665 100644
--- a/blueprints/third-party-solutions/phpipam/cloudsql.tf
+++ b/blueprints/third-party-solutions/phpipam/cloudsql.tf
@@ -27,6 +27,8 @@ module "cloudsql" {
region = var.region
tier = local.cloudsql_conf.tier
users = {
- "${local.cloudsql_conf.user}" = var.cloudsql_password
+ "${local.cloudsql_conf.user}" = {
+ password = var.cloudsql_password
+ }
}
}
diff --git a/blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf b/blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf
index 4ed2ed1992..2ebe9e1436 100644
--- a/blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf
+++ b/blueprints/third-party-solutions/wordpress/cloudrun/cloudsql.tf
@@ -61,7 +61,9 @@ module "cloudsql" {
tier = local.cloudsql_conf.tier
databases = [local.cloudsql_conf.db]
users = {
- "${local.cloudsql_conf.user}" = var.cloudsql_password
+ "${local.cloudsql_conf.user}" = {
+ password = var.cloudsql_password
+ }
}
deletion_protection = false
}
diff --git a/default-versions.tf b/default-versions.tf
index af3463955f..3adb51d3bd 100644
--- a/default-versions.tf
+++ b/default-versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/fast/stages/0-bootstrap/README.md b/fast/stages/0-bootstrap/README.md
index 1a9f1bbbd8..9ed7528916 100644
--- a/fast/stages/0-bootstrap/README.md
+++ b/fast/stages/0-bootstrap/README.md
@@ -72,7 +72,7 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md
It's often desirable to have organization policies deployed before any other resource in the org, so as to ensure compliance with specific requirements (e.g. location restrictions), or control the configuration of specific resources (e.g. default network at project creation or service account grants).
-To cover this use case, organization policies have been moved from the resource management to the bootstrap stage in FAST versions after 26.0.0. They are managed via the usual factory approach, and a [sample set of data files](./data/org-policies/) is included with this stage. They are not applied during the initial run when the `bootstrap_user` variable is set, to work around incompatibilies with user credentials.
+To cover this use case, organization policies have been moved from the resource management to the bootstrap stage in FAST versions after 26.0.0. They are managed via the usual factory approach, and a [sample set of data files](./data/org-policies/) is included with this stage. They are not applied during the initial run when the `bootstrap_user` variable is set, to work around incompatibilities with user credentials.
The only current exception to the factory approach is the `iam.allowedPolicyMemberDomains` constraint, which is managed in code so as to be able to auto-allow the organization's domain. More domains can be added via the `org_policies_config` variable, which also serves as an umbrella for future policies that will need to be managed in code.
diff --git a/fast/stages/3-project-factory/dev/README.md b/fast/stages/3-project-factory/dev/README.md
index 03bfa86c5e..07b748c50f 100644
--- a/fast/stages/3-project-factory/dev/README.md
+++ b/fast/stages/3-project-factory/dev/README.md
@@ -79,8 +79,8 @@ terraform apply
| name | description | type | required | default | producer |
|---|---|:---:|:---:|:---:|:---:|
| [billing_account](variables.tf#L19) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…})
| ✓ | | 0-bootstrap
|
-| [prefix](variables.tf#L51) | Prefix used for resources that need unique names. Use 9 characters or less. | string
| ✓ | | 0-bootstrap
|
-| [factory_data](variables.tf#L32) | Project data from either YAML files or externally parsed data. | object({…})
| | {…}
| |
+| [prefix](variables.tf#L39) | Prefix used for resources that need unique names. Use 9 characters or less. | string
| ✓ | | 0-bootstrap
|
+| [factory_data_path](variables.tf#L32) | Path to folder containing YAML project data files. | string
| | "data/projects"
| |
## Outputs
diff --git a/fast/stages/3-project-factory/dev/main.tf b/fast/stages/3-project-factory/dev/main.tf
index 4f23b49281..48867a9984 100644
--- a/fast/stages/3-project-factory/dev/main.tf
+++ b/fast/stages/3-project-factory/dev/main.tf
@@ -33,7 +33,7 @@ module "projects" {
data_overrides = {
prefix = "${var.prefix}-dev"
}
- factory_data = var.factory_data
+ factory_data_path = var.factory_data_path
}
diff --git a/fast/stages/3-project-factory/dev/variables.tf b/fast/stages/3-project-factory/dev/variables.tf
index c7165e3ced..5a8ef4f870 100644
--- a/fast/stages/3-project-factory/dev/variables.tf
+++ b/fast/stages/3-project-factory/dev/variables.tf
@@ -29,23 +29,11 @@ variable "billing_account" {
}
}
-variable "factory_data" {
- description = "Project data from either YAML files or externally parsed data."
- type = object({
- data = optional(map(any))
- data_path = optional(string)
- })
- nullable = false
- default = {
- data_path = "data/projects"
- }
- validation {
- condition = (
- (var.factory_data.data != null ? 1 : 0) +
- (var.factory_data.data_path != null ? 1 : 0)
- ) == 1
- error_message = "One of data or data_path needs to be set."
- }
+variable "factory_data_path" {
+ description = "Path to folder containing YAML project data files."
+ type = string
+ nullable = false
+ default = "data/projects"
}
variable "prefix" {
diff --git a/modules/README.md b/modules/README.md
index 03c5cf65bc..cefc5e5592 100644
--- a/modules/README.md
+++ b/modules/README.md
@@ -21,7 +21,7 @@ These modules are used in the examples included in this repository. If you are u
```terraform
module "project" {
- source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/project?ref=v13.0.0"
+ source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/project?ref=v13.0.0&depth=1"
name = "my-project"
billing_account = "123456-123456-123456"
parent = "organizations/123456"
diff --git a/modules/__experimental/alloydb-instance/versions.tf b/modules/__experimental/alloydb-instance/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/__experimental/alloydb-instance/versions.tf
+++ b/modules/__experimental/alloydb-instance/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/__experimental/net-neg/versions.tf b/modules/__experimental/net-neg/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/__experimental/net-neg/versions.tf
+++ b/modules/__experimental/net-neg/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/__experimental/project-iam-magic/versions.tf b/modules/__experimental/project-iam-magic/versions.tf
new file mode 100644
index 0000000000..2ce9578209
--- /dev/null
+++ b/modules/__experimental/project-iam-magic/versions.tf
@@ -0,0 +1,29 @@
+# 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
+#
+# 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.
+
+terraform {
+ required_version = ">= 1.4.4"
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ version = ">= 4.71.0" # tftest
+ }
+ google-beta = {
+ source = "hashicorp/google-beta"
+ version = ">= 4.71.0" # tftest
+ }
+ }
+}
+
+
diff --git a/modules/api-gateway/versions.tf b/modules/api-gateway/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/api-gateway/versions.tf
+++ b/modules/api-gateway/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/apigee/README.md b/modules/apigee/README.md
index 5a05ecb353..24c6f4166a 100644
--- a/modules/apigee/README.md
+++ b/modules/apigee/README.md
@@ -354,19 +354,18 @@ module "apigee" {
}
# tftest modules=1 resources=10
```
-
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [project_id](variables.tf#L125) | Project ID. | string
| ✓ | |
+| [project_id](variables.tf#L126) | Project ID. | string
| ✓ | |
| [addons_config](variables.tf#L17) | Addons configuration. | object({…})
| | null
|
| [endpoint_attachments](variables.tf#L29) | Endpoint attachments. | map(object({…}))
| | {}
|
| [envgroups](variables.tf#L39) | Environment groups (NAME => [HOSTNAMES]). | map(list(string))
| | {}
|
-| [environments](variables.tf#L46) | Environments. | map(object({…}))
| | {}
|
-| [instances](variables.tf#L72) | Instances ([REGION] => [INSTANCE]). | map(object({…}))
| | {}
|
-| [organization](variables.tf#L97) | Apigee organization. If set to null the organization must already exist. | object({…})
| | null
|
+| [environments](variables.tf#L46) | Environments. | map(object({…}))
| | {}
|
+| [instances](variables.tf#L73) | Instances ([REGION] => [INSTANCE]). | map(object({…}))
| | {}
|
+| [organization](variables.tf#L98) | Apigee organization. If set to null the organization must already exist. | object({…})
| | null
|
## Outputs
diff --git a/modules/apigee/main.tf b/modules/apigee/main.tf
index be571a8ae2..4db47ee0fd 100644
--- a/modules/apigee/main.tf
+++ b/modules/apigee/main.tf
@@ -40,11 +40,11 @@ resource "google_apigee_envgroup" "envgroups" {
resource "google_apigee_environment" "environments" {
for_each = var.environments
- name = each.key
- display_name = each.value.display_name
- description = each.value.description
- deployment_type = each.value.deployment_type
api_proxy_type = each.value.api_proxy_type
+ deployment_type = each.value.deployment_type
+ description = each.value.description
+ display_name = each.value.display_name
+ name = each.key
dynamic "node_config" {
for_each = try(each.value.node_config, null) != null ? [""] : []
content {
@@ -53,6 +53,7 @@ resource "google_apigee_environment" "environments" {
}
}
org_id = local.org_id
+ type = each.value.type
lifecycle {
ignore_changes = [
node_config["current_aggregate_node_count"]
diff --git a/modules/apigee/variables.tf b/modules/apigee/variables.tf
index 7ec2cc2d64..027ad05e47 100644
--- a/modules/apigee/variables.tf
+++ b/modules/apigee/variables.tf
@@ -50,6 +50,7 @@ variable "environments" {
description = optional(string, "Terraform-managed")
deployment_type = optional(string)
api_proxy_type = optional(string)
+ type = optional(string)
node_config = optional(object({
min_node_count = optional(number)
max_node_count = optional(number)
diff --git a/modules/apigee/versions.tf b/modules/apigee/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/apigee/versions.tf
+++ b/modules/apigee/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/artifact-registry/versions.tf b/modules/artifact-registry/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/artifact-registry/versions.tf
+++ b/modules/artifact-registry/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/bigquery-dataset/versions.tf b/modules/bigquery-dataset/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/bigquery-dataset/versions.tf
+++ b/modules/bigquery-dataset/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/bigtable-instance/versions.tf b/modules/bigtable-instance/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/bigtable-instance/versions.tf
+++ b/modules/bigtable-instance/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/billing-account/versions.tf b/modules/billing-account/versions.tf
index 0cc9b9727b..cee7f9c764 100644
--- a/modules/billing-account/versions.tf
+++ b/modules/billing-account/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/binauthz/versions.tf b/modules/binauthz/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/binauthz/versions.tf
+++ b/modules/binauthz/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/__need_fixing/onprem/versions.tf b/modules/cloud-config-container/__need_fixing/onprem/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/__need_fixing/onprem/versions.tf
+++ b/modules/cloud-config-container/__need_fixing/onprem/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/coredns/versions.tf b/modules/cloud-config-container/coredns/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/coredns/versions.tf
+++ b/modules/cloud-config-container/coredns/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/cos-generic-metadata/versions.tf b/modules/cloud-config-container/cos-generic-metadata/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/cos-generic-metadata/versions.tf
+++ b/modules/cloud-config-container/cos-generic-metadata/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/README.md b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/README.md
new file mode 100644
index 0000000000..76d1b19d4c
--- /dev/null
+++ b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/README.md
@@ -0,0 +1,57 @@
+# Containerized Envoy as SNI dynamic forward proxy on Container Optimized OS
+
+This module manages a `cloud-config` configuration that starts a containerized [Envoy SNI Dynamic forward proxy]https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/sni_dynamic_forward_proxy_filter) service on Container Optimized OS running on port 443.
+
+This module depends on the cos-generic-metadata module being in the parent folder. If you change its location be sure to adjust the source attribute in main.tf.
+
+Logging and monitoring are enabled via the [Google Cloud Logging agent](https://cloud.google.com/container-optimized-os/docs/how-to/logging) configured for the instance via the `google-logging-enabled` metadata property, and the [Node Problem Detector](https://cloud.google.com/container-optimized-os/docs/how-to/monitoring) service started by default on boot.
+
+## Examples
+
+### Default configuration
+
+This example will create a `cloud-config` that uses the module's defaults, creating a simple hello web server showing host name and request id.
+
+```hcl
+module "cos-envoy-sni-dyn-fwd-proxy" {
+ source = "./fabric/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy"
+ envoy_image = "envoyproxy/envoy:v1.28-latest"
+}
+
+module "vm-envoy-sni-dyn-fwd-proxy" {
+ source = "./fabric/modules/compute-vm"
+ project_id = "my-project"
+ zone = "europe-west8-b"
+ name = "cos-envoy-sni-dyn-fw-proxy"
+ network_interfaces = [{
+ network = "default"
+ subnetwork = "gce"
+ }]
+ metadata = {
+ user-data = module.cos-envoy-sni-dyn-fwd-proxy.cloud_config
+ google-logging-enabled = true
+ }
+ boot_disk = {
+ initialize_params = {
+ image = "projects/cos-cloud/global/images/family/cos-stable"
+ type = "pd-ssd"
+ size = 10
+ }
+ }
+ tags = ["https-server", "ssh"]
+}
+# tftest modules=1 resources=1
+```
+
+## Variables
+
+| name | description | type | required | default |
+|---|---|:---:|:---:|:---:|
+| [envoy_image](variables.tf#L17) | Image. | string
| ✓ | |
+
+## Outputs
+
+| name | description | sensitive |
+|---|---|:---:|
+| [cloud_config](outputs.tf#L17) | Rendered cloud-config file to be passed as user-data instance metadata. | |
+
diff --git a/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/files/envoy.yaml b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/files/envoy.yaml
new file mode 100644
index 0000000000..55a5e08fb1
--- /dev/null
+++ b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/files/envoy.yaml
@@ -0,0 +1,56 @@
+# 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
+#
+# 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.
+
+admin:
+ address:
+ socket_address:
+ protocol: TCP
+ address: 127.0.0.1
+ port_value: 9991
+static_resources:
+ listeners:
+ - name: listener
+ address:
+ socket_address:
+ protocol: TCP
+ address: 0.0.0.0
+ port_value: 8443
+ listener_filters:
+ - name: envoy.filters.listener.tls_inspector
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+ filter_chains:
+ - filters:
+ - name: envoy.filters.network.sni_dynamic_forward_proxy
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.network.sni_dynamic_forward_proxy.v3.FilterConfig
+ port_value: 443
+ dns_cache_config:
+ name: dynamic_forward_proxy_cache_config
+ dns_lookup_family: V4_ONLY
+ - name: envoy.tcp_proxy
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
+ stat_prefix: tcp
+ cluster: dynamic_forward_proxy_cluster
+ clusters:
+ - name: dynamic_forward_proxy_cluster
+ lb_policy: CLUSTER_PROVIDED
+ cluster_type:
+ name: envoy.clusters.dynamic_forward_proxy
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig
+ dns_cache_config:
+ name: dynamic_forward_proxy_cache_config
+ dns_lookup_family: V4_ONLY%
diff --git a/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/main.tf b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/main.tf
new file mode 100644
index 0000000000..f0b7cdfb2c
--- /dev/null
+++ b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/main.tf
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module "cos-envoy" {
+ source = "../cos-generic-metadata"
+ container_image = var.envoy_image
+ container_name = "envoy"
+ container_args = "-c /etc/envoy/envoy.yaml --log-level info --allow-unknown-static-fields"
+ container_volumes = [
+ { host = "/etc/envoy/", container = "/etc/envoy/" }
+ ]
+ docker_args = "--network host --pid host"
+ files = {
+ "/etc/envoy/envoy.yaml" = {
+ content = file("${path.module}/files/envoy.yaml")
+ owner = "root"
+ permissions = "0644"
+ }
+ }
+ run_commands = [
+ "iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443",
+ "iptables -A INPUT -p tcp --dport 8443 -j ACCEPT",
+ "iptables -t mangle -I PREROUTING -p tcp --dport 8443 -j DROP",
+ "systemctl daemon-reload",
+ "systemctl start envoy",
+ ]
+ users = [{
+ username = "envoy",
+ uid = 1337
+ }]
+}
diff --git a/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/outputs.tf b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/outputs.tf
new file mode 100644
index 0000000000..417c73e7d7
--- /dev/null
+++ b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/outputs.tf
@@ -0,0 +1,20 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+output "cloud_config" {
+ description = "Rendered cloud-config file to be passed as user-data instance metadata."
+ value = module.cos-envoy.cloud_config
+}
diff --git a/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/variables.tf b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/variables.tf
new file mode 100644
index 0000000000..3868a17424
--- /dev/null
+++ b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/variables.tf
@@ -0,0 +1,20 @@
+/**
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+variable "envoy_image" {
+ description = "Image."
+ type = string
+}
diff --git a/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/versions.tf b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/versions.tf
new file mode 100644
index 0000000000..ceb6930fb3
--- /dev/null
+++ b/modules/cloud-config-container/envoy-sni-dyn-fwd-proxy/versions.tf
@@ -0,0 +1,28 @@
+# 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
+#
+# 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.
+
+terraform {
+ required_version = ">= 1.4.4"
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ version = ">= 5.4.0, < 6.0.0" # tftest
+ }
+ google-beta = {
+ source = "hashicorp/google-beta"
+ version = ">= 5.4.0, < 6.0.0" # tftest
+ }
+ }
+}
+
diff --git a/modules/cloud-config-container/envoy-traffic-director/versions.tf b/modules/cloud-config-container/envoy-traffic-director/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/envoy-traffic-director/versions.tf
+++ b/modules/cloud-config-container/envoy-traffic-director/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/mysql/versions.tf b/modules/cloud-config-container/mysql/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/mysql/versions.tf
+++ b/modules/cloud-config-container/mysql/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/nginx-tls/versions.tf b/modules/cloud-config-container/nginx-tls/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/nginx-tls/versions.tf
+++ b/modules/cloud-config-container/nginx-tls/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/nginx/versions.tf b/modules/cloud-config-container/nginx/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/nginx/versions.tf
+++ b/modules/cloud-config-container/nginx/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/simple-nva/versions.tf b/modules/cloud-config-container/simple-nva/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/simple-nva/versions.tf
+++ b/modules/cloud-config-container/simple-nva/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-config-container/squid/versions.tf b/modules/cloud-config-container/squid/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-config-container/squid/versions.tf
+++ b/modules/cloud-config-container/squid/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-function-v1/versions.tf b/modules/cloud-function-v1/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-function-v1/versions.tf
+++ b/modules/cloud-function-v1/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-function-v2/versions.tf b/modules/cloud-function-v2/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-function-v2/versions.tf
+++ b/modules/cloud-function-v2/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-identity-group/versions.tf b/modules/cloud-identity-group/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-identity-group/versions.tf
+++ b/modules/cloud-identity-group/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloud-run/versions.tf b/modules/cloud-run/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloud-run/versions.tf
+++ b/modules/cloud-run/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/cloudsql-instance/README.md b/modules/cloudsql-instance/README.md
index c0f72cae08..1a9347691d 100644
--- a/modules/cloudsql-instance/README.md
+++ b/modules/cloudsql-instance/README.md
@@ -86,9 +86,13 @@ module "db" {
users = {
# generatea password for user1
- user1 = null
+ user1 = {
+ password = null
+ }
# assign a password to user2
- user2 = "mypassword"
+ user2 = {
+ password = "mypassword"
+ }
}
}
# tftest modules=1 resources=6 inventory=custom.yaml
@@ -212,7 +216,7 @@ module "db" {
| [replicas](variables.tf#L179) | Map of NAME=> {REGION, KMS_KEY} for additional read replicas. Set to null to disable replica creation. | map(object({…}))
| | {}
|
| [require_ssl](variables.tf#L188) | Enable SSL connections only. | bool
| | null
|
| [root_password](variables.tf#L194) | Root password of the Cloud SQL instance. Required for MS SQL Server. | string
| | null
|
-| [users](variables.tf#L205) | Map of users to create in the primary instance (and replicated to other replicas) in the format USER=>PASSWORD. For MySQL, anything afterr the first `@` (if persent) will be used as the user's host. Set PASSWORD to null if you want to get an autogenerated password. | map(string)
| | null
|
+| [users](variables.tf#L205) | Map of users to create in the primary instance (and replicated to other replicas). For MySQL, anything afterr the first `@` (if persent) will be used as the user's host. Set PASSWORD to null if you want to get an autogenerated password. The user types available are: 'BUILT_IN', 'CLOUD_IAM_USER' or 'CLOUD_IAM_SERVICE_ACCOUNT'. | map(object({…}))
| | null
|
## Outputs
diff --git a/modules/cloudsql-instance/main.tf b/modules/cloudsql-instance/main.tf
index fd3d9abdbd..cc6e62af8f 100644
--- a/modules/cloudsql-instance/main.tf
+++ b/modules/cloudsql-instance/main.tf
@@ -1,4 +1,4 @@
-/**
+/** TO MOD
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +17,7 @@
locals {
prefix = var.prefix == null ? "" : "${var.prefix}-"
is_mysql = can(regex("^MYSQL", var.database_version))
+ is_postgres = can(regex("^POSTGRES", var.database_version))
has_replicas = try(length(var.replicas) > 0, false)
is_regional = var.availability_type == "REGIONAL" ? true : false
@@ -25,20 +26,20 @@ locals {
enable_backup = var.backup_configuration.enabled || (local.is_mysql && local.has_replicas) || (local.is_mysql && local.is_regional)
users = {
- for user, password in coalesce(var.users, {}) :
- (user) => (
- local.is_mysql
- ? {
- name = split("@", user)[0]
- host = try(split("@", user)[1], null)
- password = try(random_password.passwords[user].result, password)
- }
- : {
- name = user
- host = null
- password = try(random_password.passwords[user].result, password)
- }
- )
+ for k, v in coalesce(var.users, {}) :
+ k =>
+ local.is_mysql ?
+ {
+ name = try(v.type, "BUILT_IN") == "BUILT_IN" ? split("@", k)[0] : k
+ host = try(v.type, "BUILT_IN") == "BUILT_IN" ? try(split("@", k)[1], null) : null
+ password = try(v.type, "BUILT_IN") == "BUILT_IN" ? try(random_password.passwords[k].result, v.password) : null
+ type = try(v.type, "BUILT_IN")
+ } : {
+ name = local.is_postgres ? try(trimsuffix(k, ".gserviceaccount.com"), k) : k
+ host = null
+ password = try(v.type, "BUILT_IN") == "BUILT_IN" ? try(random_password.passwords[k].result, v.password) : null
+ type = try(v.type, "BUILT_IN")
+ }
}
}
@@ -178,14 +179,15 @@ resource "google_sql_database" "databases" {
resource "random_password" "passwords" {
for_each = toset([
- for user, password in coalesce(var.users, {}) :
- user
- if password == null
+ for k, v in coalesce(var.users, {}) :
+ k
+ if v.password == null
])
length = 16
special = true
}
+
resource "google_sql_user" "users" {
for_each = local.users
project = var.project_id
@@ -193,6 +195,7 @@ resource "google_sql_user" "users" {
name = each.value.name
host = each.value.host
password = each.value.password
+ type = each.value.type
}
resource "google_sql_ssl_cert" "postgres_client_certificates" {
diff --git a/modules/cloudsql-instance/variables.tf b/modules/cloudsql-instance/variables.tf
index d13889b0c4..7fda3e9b02 100644
--- a/modules/cloudsql-instance/variables.tf
+++ b/modules/cloudsql-instance/variables.tf
@@ -203,8 +203,11 @@ variable "tier" {
}
variable "users" {
- description = "Map of users to create in the primary instance (and replicated to other replicas) in the format USER=>PASSWORD. For MySQL, anything afterr the first `@` (if persent) will be used as the user's host. Set PASSWORD to null if you want to get an autogenerated password."
- type = map(string)
- default = null
+ description = "Map of users to create in the primary instance (and replicated to other replicas). For MySQL, anything afterr the first `@` (if persent) will be used as the user's host. Set PASSWORD to null if you want to get an autogenerated password. The user types available are: 'BUILT_IN', 'CLOUD_IAM_USER' or 'CLOUD_IAM_SERVICE_ACCOUNT'."
+ type = map(object({
+ password = optional(string)
+ type = optional(string)
+ }))
+ default = null
}
diff --git a/modules/cloudsql-instance/versions.tf b/modules/cloudsql-instance/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/cloudsql-instance/versions.tf
+++ b/modules/cloudsql-instance/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/compute-mig/versions.tf b/modules/compute-mig/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/compute-mig/versions.tf
+++ b/modules/compute-mig/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/compute-vm/README.md b/modules/compute-vm/README.md
index 052d71b76b..450ccad730 100644
--- a/modules/compute-vm/README.md
+++ b/modules/compute-vm/README.md
@@ -516,7 +516,7 @@ module "kms-vm-example" {
}
encryption = {
encrypt_boot = true
- kms_key_self_link = var.kms_key.self_link
+ kms_key_self_link = var.kms_key.id
}
}
# tftest modules=1 resources=3 inventory=cmek.yaml
diff --git a/modules/compute-vm/versions.tf b/modules/compute-vm/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/compute-vm/versions.tf
+++ b/modules/compute-vm/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/container-registry/versions.tf b/modules/container-registry/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/container-registry/versions.tf
+++ b/modules/container-registry/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/data-catalog-policy-tag/versions.tf b/modules/data-catalog-policy-tag/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/data-catalog-policy-tag/versions.tf
+++ b/modules/data-catalog-policy-tag/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/datafusion/versions.tf b/modules/datafusion/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/datafusion/versions.tf
+++ b/modules/datafusion/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/dataplex-datascan/versions.tf b/modules/dataplex-datascan/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/dataplex-datascan/versions.tf
+++ b/modules/dataplex-datascan/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/dataplex/versions.tf b/modules/dataplex/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/dataplex/versions.tf
+++ b/modules/dataplex/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/dataproc/README.md b/modules/dataproc/README.md
index 5cd220cbaa..f00101345c 100644
--- a/modules/dataproc/README.md
+++ b/modules/dataproc/README.md
@@ -149,7 +149,7 @@ module "processing-dp-cluster" {
| [name](variables.tf#L235) | Cluster name. | string
| ✓ | |
| [project_id](variables.tf#L250) | Project ID. | string
| ✓ | |
| [region](variables.tf#L255) | Dataproc region. | string
| ✓ | |
-| [dataproc_config](variables.tf#L17) | Dataproc cluster config. | object({…})
| | {}
|
+| [dataproc_config](variables.tf#L17) | Dataproc cluster config. | object({…})
| | {}
|
| [group_iam](variables.tf#L185) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | map(list(string))
| | {}
|
| [iam](variables.tf#L192) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string))
| | {}
|
| [iam_bindings](variables.tf#L199) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | map(object({…}))
| | {}
|
diff --git a/modules/dataproc/main.tf b/modules/dataproc/main.tf
index 55bef5c70e..f229d7c7ae 100644
--- a/modules/dataproc/main.tf
+++ b/modules/dataproc/main.tf
@@ -108,8 +108,8 @@ resource "google_dataproc_cluster" "cluster" {
dynamic "accelerators" {
for_each = var.dataproc_config.cluster_config.worker_config.accelerators == null ? [] : [""]
content {
- accelerator_type = var.dataproc_config.cluster_config.accelerators.accelerator_type
- accelerator_count = var.dataproc_config.cluster_config.accelerators.accelerator_count
+ accelerator_type = var.dataproc_config.cluster_config.worker_config.accelerators.accelerator_type
+ accelerator_count = var.dataproc_config.cluster_config.worker_config.accelerators.accelerator_count
}
}
}
@@ -185,10 +185,10 @@ resource "google_dataproc_cluster" "cluster" {
for_each = var.dataproc_config.cluster_config.dataproc_metric_config == null ? [] : [""]
content {
dynamic "metrics" {
- for_each = var.dataproc_config.cluster_config.dataproc_metric_config.metrics == null ? [] : [""]
+ for_each = coalesce(var.dataproc_config.cluster_config.dataproc_metric_config.metrics, [])
content {
- metric_source = var.dataproc_config.cluster_config.dataproc_metric_config.metrics.metric_source
- metric_overrides = var.dataproc_config.cluster_config.dataproc_metric_config.metrics.metric_overrides
+ metric_source = metrics.value.metric_source
+ metric_overrides = metrics.value.metric_overrides
}
}
}
diff --git a/modules/dataproc/variables.tf b/modules/dataproc/variables.tf
index 8b77c5b96b..f4170a94f0 100644
--- a/modules/dataproc/variables.tf
+++ b/modules/dataproc/variables.tf
@@ -128,7 +128,7 @@ variable "dataproc_config" {
dataproc_metric_config = optional(object({
metrics = list(object({
metric_source = string
- metric_overrides = optional(string)
+ metric_overrides = optional(list(string))
}))
}))
metastore_config = optional(object({
diff --git a/modules/dataproc/versions.tf b/modules/dataproc/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/dataproc/versions.tf
+++ b/modules/dataproc/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/dns-response-policy/versions.tf b/modules/dns-response-policy/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/dns-response-policy/versions.tf
+++ b/modules/dns-response-policy/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/dns/versions.tf b/modules/dns/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/dns/versions.tf
+++ b/modules/dns/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/endpoints/versions.tf b/modules/endpoints/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/endpoints/versions.tf
+++ b/modules/endpoints/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/folder/README.md b/modules/folder/README.md
index 2ba7e9107a..8c75cadd5e 100644
--- a/modules/folder/README.md
+++ b/modules/folder/README.md
@@ -295,12 +295,12 @@ module "folder" {
| [id](variables.tf#L83) | Folder ID in case you use folder_create=false. | string
| | null
|
| [logging_data_access](variables.tf#L89) | Control activation of data access logs. Format is service => { log type => [exempted members]}. The special 'allServices' key denotes configuration for all services. | map(map(list(string)))
| | {}
|
| [logging_exclusions](variables.tf#L104) | Logging exclusions for this folder in the form {NAME -> FILTER}. | map(string)
| | {}
|
-| [logging_sinks](variables.tf#L111) | Logging sinks to create for the folder. | map(object({…}))
| | {}
|
-| [name](variables.tf#L141) | Folder name. | string
| | null
|
-| [org_policies](variables.tf#L147) | Organization policies applied to this folder keyed by policy name. | map(object({…}))
| | {}
|
-| [org_policies_data_path](variables.tf#L174) | Path containing org policies in YAML format. | string
| | null
|
-| [parent](variables.tf#L180) | Parent in folders/folder_id or organizations/org_id format. | string
| | null
|
-| [tag_bindings](variables.tf#L190) | Tag bindings for this folder, in key => tag value id format. | map(string)
| | null
|
+| [logging_sinks](variables.tf#L111) | Logging sinks to create for the folder. | map(object({…}))
| | {}
|
+| [name](variables.tf#L142) | Folder name. | string
| | null
|
+| [org_policies](variables.tf#L148) | Organization policies applied to this folder keyed by policy name. | map(object({…}))
| | {}
|
+| [org_policies_data_path](variables.tf#L175) | Path containing org policies in YAML format. | string
| | null
|
+| [parent](variables.tf#L181) | Parent in folders/folder_id or organizations/org_id format. | string
| | null
|
+| [tag_bindings](variables.tf#L191) | Tag bindings for this folder, in key => tag value id format. | map(string)
| | null
|
## Outputs
diff --git a/modules/folder/logging.tf b/modules/folder/logging.tf
index 8000a02145..033113ff2e 100644
--- a/modules/folder/logging.tf
+++ b/modules/folder/logging.tf
@@ -22,7 +22,7 @@ locals {
type => {
for name, sink in var.logging_sinks :
name => sink
- if sink.type == type
+ if sink.iam == true && sink.type == type
}
}
}
diff --git a/modules/folder/variables.tf b/modules/folder/variables.tf
index 1c55168187..91e8e11e81 100644
--- a/modules/folder/variables.tf
+++ b/modules/folder/variables.tf
@@ -117,6 +117,7 @@ variable "logging_sinks" {
disabled = optional(bool, false)
exclusions = optional(map(string), {})
filter = string
+ iam = optional(bool, true)
include_children = optional(bool, true)
type = string
}))
diff --git a/modules/folder/versions.tf b/modules/folder/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/folder/versions.tf
+++ b/modules/folder/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/gcs/README.md b/modules/gcs/README.md
index 8a26958d62..993e0435ff 100644
--- a/modules/gcs/README.md
+++ b/modules/gcs/README.md
@@ -196,12 +196,13 @@ module "bucket" {
| [notification_config](variables.tf#L169) | GCS Notification configuration. | object({…})
| | null
|
| [objects_to_upload](variables.tf#L183) | Objects to be uploaded to bucket. | map(object({…}))
| | {}
|
| [prefix](variables.tf#L209) | Optional prefix used to generate the bucket name. | string
| | null
|
-| [requester_pays](variables.tf#L224) | Enables Requester Pays on a storage bucket. | bool
| | null
|
-| [retention_policy](variables.tf#L230) | Bucket retention policy. | object({…})
| | null
|
-| [storage_class](variables.tf#L239) | Bucket storage class. | string
| | "MULTI_REGIONAL"
|
-| [uniform_bucket_level_access](variables.tf#L249) | Allow using object ACLs (false) or not (true, this is the recommended behavior) , defaults to true (which is the recommended practice, but not the behavior of storage API). | bool
| | true
|
-| [versioning](variables.tf#L255) | Enable versioning, defaults to false. | bool
| | false
|
-| [website](variables.tf#L261) | Bucket website. | object({…})
| | null
|
+| [public_access_prevention](variables.tf#L224) | Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint. | string
| | null
|
+| [requester_pays](variables.tf#L230) | Enables Requester Pays on a storage bucket. | bool
| | null
|
+| [retention_policy](variables.tf#L236) | Bucket retention policy. | object({…})
| | null
|
+| [storage_class](variables.tf#L245) | Bucket storage class. | string
| | "MULTI_REGIONAL"
|
+| [uniform_bucket_level_access](variables.tf#L255) | Allow using object ACLs (false) or not (true, this is the recommended behavior) , defaults to true (which is the recommended practice, but not the behavior of storage API). | bool
| | true
|
+| [versioning](variables.tf#L261) | Enable versioning, defaults to false. | bool
| | false
|
+| [website](variables.tf#L267) | Bucket website. | object({…})
| | null
|
## Outputs
diff --git a/modules/gcs/main.tf b/modules/gcs/main.tf
index 1341e707cd..c19c7912e0 100644
--- a/modules/gcs/main.tf
+++ b/modules/gcs/main.tf
@@ -29,6 +29,7 @@ resource "google_storage_bucket" "bucket" {
labels = var.labels
default_event_based_hold = var.default_event_based_hold
requester_pays = var.requester_pays
+ public_access_prevention = var.public_access_prevention
versioning {
enabled = var.versioning
}
diff --git a/modules/gcs/variables.tf b/modules/gcs/variables.tf
index 350c74baf5..de8a6abd83 100644
--- a/modules/gcs/variables.tf
+++ b/modules/gcs/variables.tf
@@ -221,6 +221,12 @@ variable "project_id" {
type = string
}
+variable "public_access_prevention" {
+ description = "Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."
+ type = string
+ default = null
+}
+
variable "requester_pays" {
description = "Enables Requester Pays on a storage bucket."
type = bool
diff --git a/modules/gcs/versions.tf b/modules/gcs/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/gcs/versions.tf
+++ b/modules/gcs/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/gcve-private-cloud/README.md b/modules/gcve-private-cloud/README.md
index 901b307971..0e3a9ef7b3 100644
--- a/modules/gcve-private-cloud/README.md
+++ b/modules/gcve-private-cloud/README.md
@@ -2,7 +2,7 @@
This module implements the creation and management of a Google Cloud VMWare Engine Private Cloud with its management cluster. If configured, it also creates the VMWare engine network or it can work with an existing one. The creation of the private connection with the user VPC requires the execution of the [Google SDK command](https://cloud.google.com/sdk/gcloud/reference/vmware/private-connections/create#--routing-mode) the module provides as an output.
-To understand the limits and to propertly configure the vSphere/vSAN subnets CIDR range please refer to the [GCVE public documetation](https://cloud.google.com/vmware-engine/docs/quickstart-networking-requirements).
+To understand the limits and to properly configure the vSphere/vSAN subnets CIDR range please refer to the [GCVE public documentation](https://cloud.google.com/vmware-engine/docs/quickstart-networking-requirements).
Be aware that the deployment of this module might require up to 2 hours depending on the selected private cloud target zone.
diff --git a/modules/gcve-private-cloud/versions.tf b/modules/gcve-private-cloud/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/gcve-private-cloud/versions.tf
+++ b/modules/gcve-private-cloud/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/gke-cluster-autopilot/versions.tf b/modules/gke-cluster-autopilot/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/gke-cluster-autopilot/versions.tf
+++ b/modules/gke-cluster-autopilot/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/gke-cluster-standard/README.md b/modules/gke-cluster-standard/README.md
index 53b57e8f80..e895b4819c 100644
--- a/modules/gke-cluster-standard/README.md
+++ b/modules/gke-cluster-standard/README.md
@@ -310,28 +310,28 @@ module "cluster-1" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [location](variables.tf#L154) | Cluster zone or region. | string
| ✓ | |
-| [name](variables.tf#L265) | Cluster name. | string
| ✓ | |
-| [project_id](variables.tf#L291) | Cluster project id. | string
| ✓ | |
-| [vpc_config](variables.tf#L314) | VPC-level configuration. | object({…})
| ✓ | |
+| [location](variables.tf#L178) | Cluster zone or region. | string
| ✓ | |
+| [name](variables.tf#L289) | Cluster name. | string
| ✓ | |
+| [project_id](variables.tf#L315) | Cluster project id. | string
| ✓ | |
+| [vpc_config](variables.tf#L338) | VPC-level configuration. | object({…})
| ✓ | |
| [backup_configs](variables.tf#L17) | Configuration for Backup for GKE. | object({…})
| | {}
|
-| [cluster_autoscaling](variables.tf#L38) | Enable and configure limits for Node Auto-Provisioning with Cluster Autoscaler. | object({…})
| | null
|
-| [deletion_protection](variables.tf#L59) | Whether or not to allow Terraform to destroy the cluster. Unless this field is set to false in Terraform state, a terraform destroy or terraform apply that would delete the cluster will fail. | bool
| | true
|
-| [description](variables.tf#L66) | Cluster description. | string
| | null
|
-| [enable_addons](variables.tf#L72) | Addons enabled in the cluster (true means enabled). | object({…})
| | {…}
|
-| [enable_features](variables.tf#L96) | Enable cluster-level features. Certain features allow configuration. | object({…})
| | {…}
|
-| [issue_client_certificate](variables.tf#L142) | Enable issuing client certificate. | bool
| | false
|
-| [labels](variables.tf#L148) | Cluster resource labels. | map(string)
| | null
|
-| [logging_config](variables.tf#L159) | Logging configuration. | object({…})
| | {}
|
-| [maintenance_config](variables.tf#L180) | Maintenance window configuration. | object({…})
| | {…}
|
-| [max_pods_per_node](variables.tf#L203) | Maximum number of pods per node in this cluster. | number
| | 110
|
-| [min_master_version](variables.tf#L209) | Minimum version of the master, defaults to the version of the most recent official release. | string
| | null
|
-| [monitoring_config](variables.tf#L215) | Monitoring configuration. Google Cloud Managed Service for Prometheus is enabled by default. | object({…})
| | {}
|
-| [node_locations](variables.tf#L270) | Zones in which the cluster's nodes are located. | list(string)
| | []
|
-| [private_cluster_config](variables.tf#L277) | Private cluster configuration. | object({…})
| | null
|
-| [release_channel](variables.tf#L296) | Release channel for GKE upgrades. | string
| | null
|
-| [service_account](variables.tf#L302) | Service account used for the default node pool, only useful if the default GCE service account has been disabled. | string
| | null
|
-| [tags](variables.tf#L308) | Network tags applied to nodes. | list(string)
| | null
|
+| [cluster_autoscaling](variables.tf#L38) | Enable and configure limits for Node Auto-Provisioning with Cluster Autoscaler. | object({…})
| | null
|
+| [deletion_protection](variables.tf#L83) | Whether or not to allow Terraform to destroy the cluster. Unless this field is set to false in Terraform state, a terraform destroy or terraform apply that would delete the cluster will fail. | bool
| | true
|
+| [description](variables.tf#L90) | Cluster description. | string
| | null
|
+| [enable_addons](variables.tf#L96) | Addons enabled in the cluster (true means enabled). | object({…})
| | {…}
|
+| [enable_features](variables.tf#L120) | Enable cluster-level features. Certain features allow configuration. | object({…})
| | {…}
|
+| [issue_client_certificate](variables.tf#L166) | Enable issuing client certificate. | bool
| | false
|
+| [labels](variables.tf#L172) | Cluster resource labels. | map(string)
| | null
|
+| [logging_config](variables.tf#L183) | Logging configuration. | object({…})
| | {}
|
+| [maintenance_config](variables.tf#L204) | Maintenance window configuration. | object({…})
| | {…}
|
+| [max_pods_per_node](variables.tf#L227) | Maximum number of pods per node in this cluster. | number
| | 110
|
+| [min_master_version](variables.tf#L233) | Minimum version of the master, defaults to the version of the most recent official release. | string
| | null
|
+| [monitoring_config](variables.tf#L239) | Monitoring configuration. Google Cloud Managed Service for Prometheus is enabled by default. | object({…})
| | {}
|
+| [node_locations](variables.tf#L294) | Zones in which the cluster's nodes are located. | list(string)
| | []
|
+| [private_cluster_config](variables.tf#L301) | Private cluster configuration. | object({…})
| | null
|
+| [release_channel](variables.tf#L320) | Release channel for GKE upgrades. | string
| | null
|
+| [service_account](variables.tf#L326) | Service account used for the default node pool, only useful if the default GCE service account has been disabled. | string
| | null
|
+| [tags](variables.tf#L332) | Network tags applied to nodes. | list(string)
| | null
|
## Outputs
diff --git a/modules/gke-cluster-standard/main.tf b/modules/gke-cluster-standard/main.tf
index f5d8fe7511..42f115e26b 100644
--- a/modules/gke-cluster-standard/main.tf
+++ b/modules/gke-cluster-standard/main.tf
@@ -123,13 +123,31 @@ resource "google_container_cluster" "cluster" {
content {
enabled = true
+ autoscaling_profile = var.cluster_autoscaling.autoscaling_profile
+
dynamic "auto_provisioning_defaults" {
for_each = var.cluster_autoscaling.auto_provisioning_defaults != null ? [""] : []
content {
boot_disk_kms_key = var.cluster_autoscaling.auto_provisioning_defaults.boot_disk_kms_key
+ disk_size = var.cluster_autoscaling.auto_provisioning_defaults.disk_size
+ disk_type = var.cluster_autoscaling.auto_provisioning_defaults.disk_type
image_type = var.cluster_autoscaling.auto_provisioning_defaults.image_type
oauth_scopes = var.cluster_autoscaling.auto_provisioning_defaults.oauth_scopes
service_account = var.cluster_autoscaling.auto_provisioning_defaults.service_account
+ dynamic "management" {
+ for_each = var.cluster_autoscaling.auto_provisioning_defaults.management != null ? [""] : []
+ content {
+ auto_repair = var.cluster_autoscaling.auto_provisioning_defaults.management.auto_repair
+ auto_upgrade = var.cluster_autoscaling.auto_provisioning_defaults.management.auto_upgrade
+ }
+ }
+ dynamic "shielded_instance_config" {
+ for_each = var.cluster_autoscaling.auto_provisioning_defaults.shielded_instance_config != null ? [""] : []
+ content {
+ enable_integrity_monitoring = var.cluster_autoscaling.auto_provisioning_defaults.shielded_instance_config.integrity_monitoring
+ enable_secure_boot = var.cluster_autoscaling.auto_provisioning_defaults.shielded_instance_config.secure_boot
+ }
+ }
}
}
dynamic "resource_limits" {
@@ -148,7 +166,19 @@ resource "google_container_cluster" "cluster" {
maximum = var.cluster_autoscaling.mem_limits.max
}
}
- // TODO: support GPUs too
+ dynamic "resource_limits" {
+ for_each = (
+ try(var.cluster_autoscaling.gpu_resources, null) == null
+ ? []
+ : var.cluster_autoscaling.gpu_resources
+ )
+ iterator = gpu_resources
+ content {
+ resource_type = gpu_resources.value.resource_type
+ minimum = gpu_resources.value.min
+ maximum = gpu_resources.value.max
+ }
+ }
}
}
diff --git a/modules/gke-cluster-standard/variables.tf b/modules/gke-cluster-standard/variables.tf
index 221f6b8a55..eebd595a05 100644
--- a/modules/gke-cluster-standard/variables.tf
+++ b/modules/gke-cluster-standard/variables.tf
@@ -38,11 +38,22 @@ variable "backup_configs" {
variable "cluster_autoscaling" {
description = "Enable and configure limits for Node Auto-Provisioning with Cluster Autoscaler."
type = object({
+ autoscaling_profile = optional(string, "BALANCED")
auto_provisioning_defaults = optional(object({
boot_disk_kms_key = optional(string)
+ disk_size = optional(number)
+ disk_type = optional(string, "pd-standard")
image_type = optional(string)
oauth_scopes = optional(list(string))
service_account = optional(string)
+ management = optional(object({
+ auto_repair = optional(bool, true)
+ auto_upgrade = optional(bool, true)
+ }))
+ shielded_instance_config = object({
+ integrity_monitoring = optional(bool, true)
+ secure_boot = optional(bool, false)
+ })
}))
cpu_limits = optional(object({
min = number
@@ -52,8 +63,21 @@ variable "cluster_autoscaling" {
min = number
max = number
}))
+ gpu_resources = optional(list(object({
+ resource_type = string
+ min = number
+ max = number
+ })))
})
default = null
+ validation {
+ condition = (var.cluster_autoscaling == null ? true : contains(["BALANCED", "OPTIMIZE_UTILIZATION"], var.cluster_autoscaling.autoscaling_profile))
+ error_message = "Invalid autoscaling_profile."
+ }
+ validation {
+ condition = (var.cluster_autoscaling == null ? true : contains(["pd-standard", "pd-ssd", "pd-balanced"], var.cluster_autoscaling.auto_provisioning_defaults.disk_type))
+ error_message = "Invalid disk_type."
+ }
}
variable "deletion_protection" {
diff --git a/modules/gke-cluster-standard/versions.tf b/modules/gke-cluster-standard/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/gke-cluster-standard/versions.tf
+++ b/modules/gke-cluster-standard/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/gke-hub/versions.tf b/modules/gke-hub/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/gke-hub/versions.tf
+++ b/modules/gke-hub/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/gke-nodepool/main.tf b/modules/gke-nodepool/main.tf
index 40f7fcf31c..20d4fcad16 100644
--- a/modules/gke-nodepool/main.tf
+++ b/modules/gke-nodepool/main.tf
@@ -168,10 +168,7 @@ resource "google_container_node_pool" "nodepool" {
gpu_partition_size = var.node_config.guest_accelerator.gpu_driver == null ? null : var.node_config.guest_accelerator.gpu_driver.partition_size
dynamic "gpu_sharing_config" {
- for_each = lookup(
- lookup(var.node_config.guest_accelerator, "gpu_driver", {}),
- "max_shared_clients_per_gpu"
- ) != null ? [""] : []
+ for_each = try(var.node_config.guest_accelerator.gpu_driver.max_shared_clients_per_gpu, null) != null ? [""] : []
content {
gpu_sharing_strategy = var.node_config.guest_accelerator.gpu_driver.max_shared_clients_per_gpu != null ? "TIME_SHARING" : null
max_shared_clients_per_gpu = var.node_config.guest_accelerator.gpu_driver.max_shared_clients_per_gpu
diff --git a/modules/gke-nodepool/variables.tf b/modules/gke-nodepool/variables.tf
index 17cfd88c5a..caa735884c 100644
--- a/modules/gke-nodepool/variables.tf
+++ b/modules/gke-nodepool/variables.tf
@@ -100,7 +100,7 @@ variable "node_config" {
validation {
condition = (
alltrue([
- for k, v in var.node_config.guest_accelerator[*].gpu_driver : contains([
+ for k, v in try(var.node_config.guest_accelerator[0].gpu_driver, {}) : contains([
"GPU_DRIVER_VERSION_UNSPECIFIED", "INSTALLATION_DISABLED",
"DEFAULT", "LATEST"
], v.version)
diff --git a/modules/gke-nodepool/versions.tf b/modules/gke-nodepool/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/gke-nodepool/versions.tf
+++ b/modules/gke-nodepool/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/iam-service-account/versions.tf b/modules/iam-service-account/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/iam-service-account/versions.tf
+++ b/modules/iam-service-account/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/kms/versions.tf b/modules/kms/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/kms/versions.tf
+++ b/modules/kms/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/logging-bucket/versions.tf b/modules/logging-bucket/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/logging-bucket/versions.tf
+++ b/modules/logging-bucket/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/ncc-spoke-ra/versions.tf b/modules/ncc-spoke-ra/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/ncc-spoke-ra/versions.tf
+++ b/modules/ncc-spoke-ra/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-address/versions.tf b/modules/net-address/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-address/versions.tf
+++ b/modules/net-address/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-cloudnat/versions.tf b/modules/net-cloudnat/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-cloudnat/versions.tf
+++ b/modules/net-cloudnat/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-firewall-policy/versions.tf b/modules/net-firewall-policy/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-firewall-policy/versions.tf
+++ b/modules/net-firewall-policy/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-ipsec-over-interconnect/versions.tf b/modules/net-ipsec-over-interconnect/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-ipsec-over-interconnect/versions.tf
+++ b/modules/net-ipsec-over-interconnect/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-lb-app-ext/main.tf b/modules/net-lb-app-ext/main.tf
index ebe438ec13..94a79d9996 100644
--- a/modules/net-lb-app-ext/main.tf
+++ b/modules/net-lb-app-ext/main.tf
@@ -53,6 +53,9 @@ resource "google_compute_ssl_certificate" "default" {
name = "${var.name}-${each.key}"
certificate = trimspace(each.value.certificate)
private_key = trimspace(each.value.private_key)
+ lifecycle {
+ create_before_destroy = true
+ }
}
resource "google_compute_managed_ssl_certificate" "default" {
diff --git a/modules/net-lb-app-ext/versions.tf b/modules/net-lb-app-ext/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-lb-app-ext/versions.tf
+++ b/modules/net-lb-app-ext/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-lb-app-int/README.md b/modules/net-lb-app-int/README.md
index dfc4f5eccb..3616494a7d 100644
--- a/modules/net-lb-app-int/README.md
+++ b/modules/net-lb-app-int/README.md
@@ -223,7 +223,9 @@ module "ilb-l7" {
backends = [{
balancing_mode = "RATE"
group = "projects/myprj/zones/europe-west1-a/networkEndpointGroups/my-neg"
- max_rate = { per_endpoint = 1 }
+ max_rate = {
+ per_endpoint = 1
+ }
}]
}
}
@@ -259,7 +261,9 @@ module "ilb-l7" {
backends = [{
balancing_mode = "RATE"
group = "my-neg"
- max_rate = { per_endpoint = 1 }
+ max_rate = {
+ per_endpoint = 1
+ }
}]
}
}
@@ -296,7 +300,13 @@ module "ilb-l7" {
region = "europe-west1"
backend_service_configs = {
default = {
- backends = [{ group = "my-neg" }]
+ backends = [{
+ balancing_mode = "RATE"
+ group = "my-neg"
+ max_rate = {
+ per_endpoint = 1
+ }
+ }]
}
}
neg_configs = {
@@ -518,7 +528,9 @@ module "ilb-l7" {
backends = [{
balancing_mode = "RATE"
group = "neg-nginx-ew8-c"
- max_rate = { per_endpoint = 1 }
+ max_rate = {
+ per_endpoint = 1
+ }
}]
}
home = {
@@ -625,7 +637,6 @@ module "ilb-l7" {
-
## Files
| name | description | resources |
@@ -651,7 +662,7 @@ module "ilb-l7" {
| [region](variables.tf#L156) | The region where to allocate the ILB resources. | string
| ✓ | |
| [vpc_config](variables.tf#L183) | VPC-level configuration. | object({…})
| ✓ | |
| [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | string
| | null
|
-| [backend_service_configs](variables-backend-service.tf#L19) | Backend service level configuration. | map(object({…}))
| | {}
|
+| [backend_service_configs](variables-backend-service.tf#L19) | Backend service level configuration. | map(object({…}))
| | {}
|
| [description](variables.tf#L23) | Optional description used for resources. | string
| | "Terraform managed."
|
| [global_access](variables.tf#L30) | Allow client access from all regions. | bool
| | null
|
| [group_configs](variables.tf#L36) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | map(object({…}))
| | {}
|
@@ -677,5 +688,4 @@ module "ilb-l7" {
| [health_check_ids](outputs.tf#L48) | Autogenerated health check ids. | |
| [id](outputs.tf#L55) | Fully qualified forwarding rule id. | |
| [neg_ids](outputs.tf#L60) | Autogenerated network endpoint group ids. | |
-
diff --git a/modules/net-lb-app-int/backend-service.tf b/modules/net-lb-app-int/backend-service.tf
index 669a291aff..0dcfa46a99 100644
--- a/modules/net-lb-app-int/backend-service.tf
+++ b/modules/net-lb-app-int/backend-service.tf
@@ -114,28 +114,6 @@ resource "google_compute_region_backend_service" "default" {
}
}
- dynamic "connection_tracking_policy" {
- for_each = (
- each.value.connection_tracking == null
- ? []
- : [each.value.connection_tracking]
- )
- iterator = cb
- content {
- connection_persistence_on_unhealthy_backends = (
- cb.value.persist_conn_on_unhealthy != null
- ? cb.value.persist_conn_on_unhealthy
- : null
- )
- idle_timeout_sec = cb.value.idle_timeout_sec
- tracking_mode = (
- cb.value.track_per_session != null
- ? cb.value.track_per_session
- : null
- )
- }
- }
-
dynamic "consistent_hash" {
for_each = (
each.value.consistent_hash == null ? [] : [each.value.consistent_hash]
diff --git a/modules/net-lb-app-int/variables-backend-service.tf b/modules/net-lb-app-int/variables-backend-service.tf
index 5cfe9a5aca..728e21dbc3 100644
--- a/modules/net-lb-app-int/variables-backend-service.tf
+++ b/modules/net-lb-app-int/variables-backend-service.tf
@@ -35,11 +35,6 @@ variable "backend_service_configs" {
capacity_scaler = optional(number, 1)
description = optional(string, "Terraform managed.")
failover = optional(bool, false)
- max_connections = optional(object({
- per_endpoint = optional(number)
- per_group = optional(number)
- per_instance = optional(number)
- }))
max_rate = optional(object({
per_endpoint = optional(number)
per_group = optional(number)
@@ -58,11 +53,6 @@ variable "backend_service_configs" {
nanos = optional(number)
}))
}))
- connection_tracking = optional(object({
- idle_timeout_sec = optional(number)
- persist_conn_on_unhealthy = optional(string)
- track_per_session = optional(bool)
- }))
consistent_hash = optional(object({
http_header_name = optional(string)
minimum_ring_size = optional(number)
@@ -79,7 +69,6 @@ variable "backend_service_configs" {
failover_config = optional(object({
disable_conn_drain = optional(bool)
drop_traffic_if_unhealthy = optional(bool)
- ratio = optional(number)
}))
iap_config = optional(object({
oauth2_client_id = string
diff --git a/modules/net-lb-app-int/versions.tf b/modules/net-lb-app-int/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-lb-app-int/versions.tf
+++ b/modules/net-lb-app-int/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-lb-ext/versions.tf b/modules/net-lb-ext/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-lb-ext/versions.tf
+++ b/modules/net-lb-ext/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-lb-int/versions.tf b/modules/net-lb-int/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-lb-int/versions.tf
+++ b/modules/net-lb-int/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-lb-proxy-int/versions.tf b/modules/net-lb-proxy-int/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-lb-proxy-int/versions.tf
+++ b/modules/net-lb-proxy-int/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-swp/versions.tf b/modules/net-swp/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-swp/versions.tf
+++ b/modules/net-swp/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-vlan-attachment/versions.tf b/modules/net-vlan-attachment/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-vlan-attachment/versions.tf
+++ b/modules/net-vlan-attachment/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-vpc-firewall/versions.tf b/modules/net-vpc-firewall/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-vpc-firewall/versions.tf
+++ b/modules/net-vpc-firewall/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-vpc-peering/README.md b/modules/net-vpc-peering/README.md
index 0998d7b3ed..1def1ad19a 100644
--- a/modules/net-vpc-peering/README.md
+++ b/modules/net-vpc-peering/README.md
@@ -82,6 +82,7 @@ module "peering" {
| [peer_create_peering](variables.tf#L22) | Create the peering on the remote side. If false, only the peering from this network to the remote network is created. | bool
| | true
|
| [prefix](variables.tf#L33) | Optional name prefix for the network peerings. | string
| | null
|
| [routes_config](variables.tf#L43) | Control import/export for local and remote peer. Remote configuration is only used when creating remote peering. | object({…})
| | {}
|
+| [stack_type](variables.tf#L63) | IP version(s) of traffic and routes that are allowed to be imported or exported between peer networks. Possible values: IPV4_ONLY, IPV4_IPV6. | string
| | null
|
## Outputs
diff --git a/modules/net-vpc-peering/main.tf b/modules/net-vpc-peering/main.tf
index 2d88a0b41b..bb754ae8c2 100644
--- a/modules/net-vpc-peering/main.tf
+++ b/modules/net-vpc-peering/main.tf
@@ -36,6 +36,7 @@ resource "google_compute_network_peering" "local_network_peering" {
import_subnet_routes_with_public_ip = try(
var.routes_config.local.public_import, null
)
+ stack_type = var.stack_type
}
resource "google_compute_network_peering" "peer_network_peering" {
@@ -55,5 +56,6 @@ resource "google_compute_network_peering" "peer_network_peering" {
import_subnet_routes_with_public_ip = try(
var.routes_config.peer.public_import, null
)
+ stack_type = var.stack_type
depends_on = [google_compute_network_peering.local_network_peering]
}
diff --git a/modules/net-vpc-peering/variables.tf b/modules/net-vpc-peering/variables.tf
index ade807415b..9058da1ded 100644
--- a/modules/net-vpc-peering/variables.tf
+++ b/modules/net-vpc-peering/variables.tf
@@ -59,3 +59,13 @@ variable "routes_config" {
nullable = false
default = {}
}
+
+variable "stack_type" {
+ description = "IP version(s) of traffic and routes that are allowed to be imported or exported between peer networks. Possible values: IPV4_ONLY, IPV4_IPV6."
+ type = string
+ default = null
+ validation {
+ condition = var.stack_type == "IPV4_ONLY" || var.stack_type == "IPV4_IPV6" || var.stack_type == null
+ error_message = "The stack_type must be either 'IPV4_ONLY' or 'IPV4_IPV6'."
+ }
+}
\ No newline at end of file
diff --git a/modules/net-vpc-peering/versions.tf b/modules/net-vpc-peering/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-vpc-peering/versions.tf
+++ b/modules/net-vpc-peering/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-vpc/versions.tf b/modules/net-vpc/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-vpc/versions.tf
+++ b/modules/net-vpc/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-vpn-dynamic/versions.tf b/modules/net-vpn-dynamic/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-vpn-dynamic/versions.tf
+++ b/modules/net-vpn-dynamic/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-vpn-ha/versions.tf b/modules/net-vpn-ha/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-vpn-ha/versions.tf
+++ b/modules/net-vpn-ha/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/net-vpn-static/versions.tf b/modules/net-vpn-static/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/net-vpn-static/versions.tf
+++ b/modules/net-vpn-static/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/organization/README.md b/modules/organization/README.md
index 86df8ab3ba..b760f03626 100644
--- a/modules/organization/README.md
+++ b/modules/organization/README.md
@@ -456,7 +456,7 @@ module "org" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [organization_id](variables.tf#L211) | Organization id in organizations/nnnnnn format. | string
| ✓ | |
+| [organization_id](variables.tf#L212) | Organization id in organizations/nnnnnn format. | string
| ✓ | |
| [contacts](variables.tf#L17) | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES. | map(list(string))
| | {}
|
| [custom_roles](variables.tf#L24) | Map of role name => list of permissions to create in this project. | map(list(string))
| | {}
|
| [firewall_policy](variables.tf#L31) | Hierarchical firewall policies to associate to the organization. | object({…})
| | null
|
@@ -466,14 +466,14 @@ module "org" {
| [iam_bindings_additive](variables.tf#L69) | Individual additive IAM bindings. Keys are arbitrary. | map(object({…}))
| | {}
|
| [logging_data_access](variables.tf#L84) | Control activation of data access logs. Format is service => { log type => [exempted members]}. The special 'allServices' key denotes configuration for all services. | map(map(list(string)))
| | {}
|
| [logging_exclusions](variables.tf#L99) | Logging exclusions for this organization in the form {NAME -> FILTER}. | map(string)
| | {}
|
-| [logging_sinks](variables.tf#L106) | Logging sinks to create for the organization. | map(object({…}))
| | {}
|
-| [network_tags](variables.tf#L136) | Network tags by key name. If `id` is provided, key creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…}))
| | {}
|
-| [org_policies](variables.tf#L158) | Organization policies applied to this organization keyed by policy name. | map(object({…}))
| | {}
|
-| [org_policies_data_path](variables.tf#L185) | Path containing org policies in YAML format. | string
| | null
|
-| [org_policy_custom_constraints](variables.tf#L191) | Organization policy custom constraints keyed by constraint name. | map(object({…}))
| | {}
|
-| [org_policy_custom_constraints_data_path](variables.tf#L205) | Path containing org policy custom constraints in YAML format. | string
| | null
|
-| [tag_bindings](variables.tf#L220) | Tag bindings for this organization, in key => tag value id format. | map(string)
| | null
|
-| [tags](variables.tf#L226) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…}))
| | {}
|
+| [logging_sinks](variables.tf#L106) | Logging sinks to create for the organization. | map(object({…}))
| | {}
|
+| [network_tags](variables.tf#L137) | Network tags by key name. If `id` is provided, key creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…}))
| | {}
|
+| [org_policies](variables.tf#L159) | Organization policies applied to this organization keyed by policy name. | map(object({…}))
| | {}
|
+| [org_policies_data_path](variables.tf#L186) | Path containing org policies in YAML format. | string
| | null
|
+| [org_policy_custom_constraints](variables.tf#L192) | Organization policy custom constraints keyed by constraint name. | map(object({…}))
| | {}
|
+| [org_policy_custom_constraints_data_path](variables.tf#L206) | Path containing org policy custom constraints in YAML format. | string
| | null
|
+| [tag_bindings](variables.tf#L221) | Tag bindings for this organization, in key => tag value id format. | map(string)
| | null
|
+| [tags](variables.tf#L227) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…}))
| | {}
|
## Outputs
diff --git a/modules/organization/logging.tf b/modules/organization/logging.tf
index 7719c0fb62..7f0665e3ab 100644
--- a/modules/organization/logging.tf
+++ b/modules/organization/logging.tf
@@ -21,7 +21,7 @@ locals {
for type in ["bigquery", "logging", "pubsub", "storage"] :
type => {
for name, sink in var.logging_sinks :
- name => sink if sink.type == type
+ name => sink if sink.iam && sink.type == type
}
}
}
diff --git a/modules/organization/variables.tf b/modules/organization/variables.tf
index c9899e2e1d..f664deaef1 100644
--- a/modules/organization/variables.tf
+++ b/modules/organization/variables.tf
@@ -112,6 +112,7 @@ variable "logging_sinks" {
disabled = optional(bool, false)
exclusions = optional(map(string), {})
filter = string
+ iam = optional(bool, true)
include_children = optional(bool, true)
type = string
}))
diff --git a/modules/organization/versions.tf b/modules/organization/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/organization/versions.tf
+++ b/modules/organization/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/project/README.md b/modules/project/README.md
index 43dfbc7044..9d94d9f2d1 100644
--- a/modules/project/README.md
+++ b/modules/project/README.md
@@ -11,15 +11,16 @@ This module implements the creation and management of one GCP project including
- [Authoritative IAM](#authoritative-iam)
- [Additive IAM](#additive-iam)
- [Service Identities and Authoritative IAM](#service-identities-and-authoritative-iam)
- - [Service Identities Requiring Manual Iam Grants](#service-identities-requiring-manual-iam-grants)
+ - [Service Identities Requiring Manual IAM Grants](#service-identities-requiring-manual-iam-grants)
- [Shared VPC](#shared-vpc)
- [Organization Policies](#organization-policies)
- [Organization Policy Factory](#organization-policy-factory)
- [Log Sinks](#log-sinks)
- [Data Access Logs](#data-access-logs)
-- [Cloud Kms Encryption Keys](#cloud-kms-encryption-keys)
+- [Cloud KMS Encryption Keys](#cloud-kms-encryption-keys)
- [Tags](#tags)
- [Outputs](#outputs)
+ - [Managing project related configuration without creating it](#managing-project-related-configuration-without-creating-it)
- [Files](#files)
- [Variables](#variables)
- [Outputs](#outputs)
@@ -30,16 +31,16 @@ This module implements the creation and management of one GCP project including
```hcl
module "project" {
source = "./fabric/modules/project"
- billing_account = "123456-123456-123456"
- name = "myproject"
- parent = "folders/1234567890"
- prefix = "foo"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
services = [
"container.googleapis.com",
"stackdriver.googleapis.com"
]
}
-# tftest modules=1 resources=3 inventory=basic.yaml
+# tftest modules=1 resources=3 inventory=basic.yaml e2e
```
## IAM
@@ -65,10 +66,10 @@ locals {
module "project" {
source = "./fabric/modules/project"
- billing_account = "123456-123456-123456"
- name = "project-example"
- parent = "folders/1234567890"
- prefix = "foo"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
services = [
"container.googleapis.com",
"stackdriver.googleapis.com"
@@ -87,12 +88,12 @@ The `group_iam` variable uses group email addresses as keys and is a convenient
```hcl
module "project" {
source = "./fabric/modules/project"
- billing_account = "123456-123456-123456"
- name = "project-example"
- parent = "folders/1234567890"
- prefix = "foo"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
group_iam = {
- "gcp-security-admins@example.com" = [
+ (var.group_email) = [
"roles/cloudasset.owner",
"roles/cloudsupport.techSupportEditor",
"roles/iam.securityReviewer",
@@ -100,7 +101,7 @@ module "project" {
]
}
}
-# tftest modules=1 resources=5 inventory=iam-group.yaml
+# tftest modules=1 resources=5 inventory=iam-group.yaml e2e
```
The `iam_bindings` variable behaves like a more verbose version of `iam`, and allows setting binding-level IAM conditions.
@@ -108,10 +109,10 @@ The `iam_bindings` variable behaves like a more verbose version of `iam`, and al
```hcl
module "project" {
source = "./fabric/modules/project"
- billing_account = "123456-123456-123456"
- name = "project-example"
- parent = "folders/1234567890"
- prefix = "foo"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
services = [
"container.googleapis.com",
"stackdriver.googleapis.com"
@@ -119,7 +120,7 @@ module "project" {
iam_bindings = {
iam_admin_conditional = {
members = [
- "group:test-admins@example.org"
+ "group:${var.group_email}"
]
role = "roles/resourcemanager.projectIamAdmin"
condition = {
@@ -135,7 +136,7 @@ module "project" {
}
}
}
-# tftest modules=1 resources=4 inventory=iam-bindings.yaml
+# tftest modules=1 resources=4 inventory=iam-bindings.yaml e2e
```
### Additive IAM
@@ -146,19 +147,22 @@ The `iam_bindings_additive` variable allows setting individual role/principal bi
```hcl
module "project" {
- source = "./fabric/modules/project"
- name = "project-1"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
services = [
"compute.googleapis.com"
]
iam_bindings_additive = {
group-owner = {
- member = "group:p1-owners@example.org"
+ member = "group:${var.group_email}"
role = "roles/owner"
}
}
}
-# tftest modules=1 resources=3 inventory=iam-bindings-additive.yaml
+# tftest modules=1 resources=3 inventory=iam-bindings-additive.yaml e2e
```
### Service Identities and Authoritative IAM
@@ -167,23 +171,21 @@ As mentioned above, there are cases where authoritative management of specific I
```hcl
module "project" {
- source = "./fabric/modules/project"
- name = "project-example"
- group_iam = {
- "foo@example.com" = [
- "roles/editor"
- ]
- }
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
iam = {
"roles/editor" = [
"serviceAccount:${module.project.service_accounts.cloud_services}"
]
}
}
-# tftest modules=1 resources=2
+# tftest modules=1 resources=2 e2e
```
-### Service Identities Requiring Manual Iam Grants
+### Service Identities Requiring Manual IAM Grants
The module will create service identities at project creation instead of creating of them at the time of first use. This allows granting these service identities roles in other projects, something which is usually necessary in a Shared VPC context.
@@ -191,15 +193,21 @@ You can grant roles to service identities using the following construct:
```hcl
module "project" {
- source = "./fabric/modules/project"
- name = "project-example"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
+ services = [
+ "apigee.googleapis.com",
+ ]
iam = {
"roles/apigee.serviceAgent" = [
"serviceAccount:${module.project.service_accounts.robots.apigee}"
]
}
}
-# tftest modules=1 resources=2
+# tftest modules=1 resources=4 e2e
```
This table lists all affected services and roles that you need to grant to service identities
@@ -225,16 +233,26 @@ You can enable Shared VPC Host at the project level and manage project service a
```hcl
module "host-project" {
- source = "./fabric/modules/project"
- name = "my-host-project"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "host"
+ parent = var.folder_id
+ prefix = var.prefix
shared_vpc_host_config = {
enabled = true
}
}
module "service-project" {
- source = "./fabric/modules/project"
- name = "my-service-project"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "service"
+ parent = var.folder_id
+ prefix = var.prefix
+ services = [
+ "container.googleapis.com",
+ "run.googleapis.com"
+ ]
shared_vpc_service_config = {
host_project = module.host-project.project_id
service_identity_iam = {
@@ -250,23 +268,29 @@ module "service-project" {
}
}
}
-# tftest modules=2 resources=8 inventory=shared-vpc.yaml
+# tftest modules=2 resources=10 inventory=shared-vpc.yaml e2e
```
The module allows also granting necessary permissions in host project to service identities by specifying which services will be used in service project in `grant_iam_for_services`.
```hcl
module "host-project" {
- source = "./fabric/modules/project"
- name = "my-host-project"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "host"
+ parent = var.folder_id
+ prefix = var.prefix
shared_vpc_host_config = {
enabled = true
}
}
module "service-project" {
- source = "./fabric/modules/project"
- name = "my-service-project"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "service"
+ parent = var.folder_id
+ prefix = var.prefix
services = [
"container.googleapis.com",
]
@@ -275,7 +299,7 @@ module "service-project" {
service_iam_grants = module.service-project.services
}
}
-# tftest modules=2 resources=9 inventory=shared-vpc-auto-grants.yaml
+# tftest modules=2 resources=9 inventory=shared-vpc-auto-grants.yaml e2e
```
## Organization Policies
@@ -285,10 +309,10 @@ To manage organization policies, the `orgpolicy.googleapis.com` service should b
```hcl
module "project" {
source = "./fabric/modules/project"
- billing_account = "123456-123456-123456"
- name = "project-example"
- parent = "folders/1234567890"
- prefix = "foo"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
org_policies = {
"compute.disableGuestAttributesAccess" = {
rules = [{ enforce = true }]
@@ -334,7 +358,7 @@ module "project" {
}
}
}
-# tftest modules=1 resources=8 inventory=org-policies.yaml
+# tftest modules=1 resources=8 inventory=org-policies.yaml e2e
```
### Organization Policy Factory
@@ -348,13 +372,13 @@ The example below deploys a few organization policies split between two YAML fil
```hcl
module "project" {
source = "./fabric/modules/project"
- billing_account = "123456-123456-123456"
- name = "project-example"
- parent = "folders/1234567890"
- prefix = "foo"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
org_policies_data_path = "configs/org-policies/"
}
-# tftest modules=1 resources=8 files=boolean,list inventory=org-policies.yaml
+# tftest modules=1 resources=8 files=boolean,list inventory=org-policies.yaml e2e
```
```yaml
@@ -415,6 +439,7 @@ module "gcs" {
source = "./fabric/modules/gcs"
project_id = var.project_id
name = "gcs_sink"
+ prefix = var.prefix
force_destroy = true
}
@@ -422,6 +447,7 @@ module "dataset" {
source = "./fabric/modules/bigquery-dataset"
project_id = var.project_id
id = "bq_sink"
+ options = { delete_contents_on_destroy = true }
}
module "pubsub" {
@@ -433,15 +459,19 @@ module "pubsub" {
module "bucket" {
source = "./fabric/modules/logging-bucket"
parent_type = "project"
- parent = "my-project"
+ parent = var.project_id
id = "bucket"
}
module "project-host" {
source = "./fabric/modules/project"
- name = "my-project"
- billing_account = "123456-123456-123456"
- parent = "folders/1234567890"
+ name = "project"
+ billing_account = var.billing_account_id
+ parent = var.folder_id
+ prefix = var.prefix
+ services = [
+ "logging.googleapis.com"
+ ]
logging_sinks = {
warnings = {
destination = module.gcs.id
@@ -471,7 +501,7 @@ module "project-host" {
no-gce-instances = "resource.type=gce_instance"
}
}
-# tftest modules=5 resources=14 inventory=logging.yaml
+# tftest modules=5 resources=15 inventory=logging.yaml e2e
```
## Data Access Logs
@@ -483,13 +513,14 @@ This example shows how to set a non-authoritative access log configuration:
```hcl
module "project" {
source = "./fabric/modules/project"
- name = "my-project"
- billing_account = "123456-123456-123456"
- parent = "folders/1234567890"
+ name = "project"
+ billing_account = var.billing_account_id
+ parent = var.folder_id
+ prefix = var.prefix
logging_data_access = {
allServices = {
# logs for principals listed here will be excluded
- ADMIN_READ = ["group:organization-admins@example.org"]
+ ADMIN_READ = ["group:${var.group_email}"]
}
"storage.googleapis.com" = {
DATA_READ = []
@@ -497,33 +528,34 @@ module "project" {
}
}
}
-# tftest modules=1 resources=3 inventory=logging-data-access.yaml
+# tftest modules=1 resources=3 inventory=logging-data-access.yaml e2e
```
-## Cloud Kms Encryption Keys
+## Cloud KMS Encryption Keys
The module offers a simple, centralized way to assign `roles/cloudkms.cryptoKeyEncrypterDecrypter` to service identities.
```hcl
module "project" {
- source = "./fabric/modules/project"
- name = "my-project"
- prefix = "foo"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "project"
+ prefix = var.prefix
+ parent = var.folder_id
services = [
"compute.googleapis.com",
"storage.googleapis.com"
]
service_encryption_key_ids = {
compute = [
- "projects/kms-central-prj/locations/europe-west3/keyRings/my-keyring/cryptoKeys/europe3-gce",
- "projects/kms-central-prj/locations/europe-west4/keyRings/my-keyring/cryptoKeys/europe4-gce"
+ var.kms_key.id
]
storage = [
- "projects/kms-central-prj/locations/europe/keyRings/my-keyring/cryptoKeys/europe-gcs"
+ var.kms_key.id
]
}
}
-# tftest modules=1 resources=7
+# tftest modules=1 resources=6 e2e
```
## Tags
@@ -548,7 +580,8 @@ module "org" {
module "project" {
source = "./fabric/modules/project"
- name = "test-project"
+ name = "project"
+ parent = var.folder_id
tag_bindings = {
env-prod = module.org.tag_values["environment/prod"].id
foo = "tagValues/12345678"
@@ -565,8 +598,11 @@ One non-obvious output is `service_accounts`, which offers a simple way to disco
```hcl
module "project" {
- source = "./fabric/modules/project"
- name = "project-example"
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "project"
+ prefix = var.prefix
+ parent = var.folder_id
services = [
"compute.googleapis.com"
]
@@ -575,9 +611,222 @@ module "project" {
output "compute_robot" {
value = module.project.service_accounts.robots.compute
}
-# tftest modules=1 resources=2 inventory:outputs.yaml
+# tftest modules=1 resources=2 inventory:outputs.yaml e2e
```
+### Managing project related configuration without creating it
+
+The module offers managing all related resources without ever touching the project itself by using `project_create = false`
+
+```hcl
+module "create-project" {
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
+}
+
+module "project" {
+ source = "./fabric/modules/project"
+ depends_on = [module.create-project]
+ billing_account = var.billing_account_id
+ name = "project"
+ parent = var.folder_id
+ prefix = var.prefix
+ project_create = false
+
+ group_iam = {
+ (var.group_email) = [
+ "roles/cloudasset.owner",
+ "roles/cloudsupport.techSupportEditor",
+ "roles/iam.securityReviewer",
+ "roles/logging.admin",
+ ]
+ }
+ iam_bindings = {
+ iam_admin_conditional = {
+ members = [
+ "group:${var.group_email}"
+ ]
+ role = "roles/resourcemanager.projectIamAdmin"
+ condition = {
+ title = "delegated_network_user_one"
+ expression = <<-END
+ api.getAttribute(
+ 'iam.googleapis.com/modifiedGrantsByRole', []
+ ).hasOnly([
+ 'roles/compute.networkAdmin'
+ ])
+ END
+ }
+ }
+ }
+ iam_bindings_additive = {
+ group-owner = {
+ member = "group:${var.group_email}"
+ role = "roles/owner"
+ }
+ }
+ iam = {
+ "roles/editor" = [
+ "serviceAccount:${module.project.service_accounts.cloud_services}"
+ ]
+ "roles/apigee.serviceAgent" = [
+ "serviceAccount:${module.project.service_accounts.robots.apigee}"
+ ]
+ }
+ logging_data_access = {
+ allServices = {
+ # logs for principals listed here will be excluded
+ ADMIN_READ = ["group:${var.group_email}"]
+ }
+ "storage.googleapis.com" = {
+ DATA_READ = []
+ DATA_WRITE = []
+ }
+ }
+ logging_sinks = {
+ warnings = {
+ destination = module.gcs.id
+ filter = "severity=WARNING"
+ type = "storage"
+ }
+ info = {
+ destination = module.dataset.id
+ filter = "severity=INFO"
+ type = "bigquery"
+ }
+ notice = {
+ destination = module.pubsub.id
+ filter = "severity=NOTICE"
+ type = "pubsub"
+ }
+ debug = {
+ destination = module.bucket.id
+ filter = "severity=DEBUG"
+ exclusions = {
+ no-compute = "logName:compute"
+ }
+ type = "logging"
+ }
+ }
+ logging_exclusions = {
+ no-gce-instances = "resource.type=gce_instance"
+ }
+ org_policies = {
+ "compute.disableGuestAttributesAccess" = {
+ rules = [{ enforce = true }]
+ }
+ "compute.skipDefaultNetworkCreation" = {
+ rules = [{ enforce = true }]
+ }
+ "iam.disableServiceAccountKeyCreation" = {
+ rules = [{ enforce = true }]
+ }
+ "iam.disableServiceAccountKeyUpload" = {
+ rules = [
+ {
+ condition = {
+ expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')"
+ title = "condition"
+ description = "test condition"
+ location = "somewhere"
+ }
+ enforce = true
+ },
+ {
+ enforce = false
+ }
+ ]
+ }
+ "iam.allowedPolicyMemberDomains" = {
+ rules = [{
+ allow = {
+ values = ["C0xxxxxxx", "C0yyyyyyy"]
+ }
+ }]
+ }
+ "compute.trustedImageProjects" = {
+ rules = [{
+ allow = {
+ values = ["projects/my-project"]
+ }
+ }]
+ }
+ "compute.vmExternalIpAccess" = {
+ rules = [{ deny = { all = true } }]
+ }
+ }
+ shared_vpc_service_config = {
+ host_project = module.host-project.project_id
+ service_iam_grants = module.project.services
+ service_identity_iam = {
+ "roles/cloudasset.owner" = [
+ "cloudservices", "container-engine"
+ ]
+ }
+ }
+ services = [
+ "apigee.googleapis.com",
+ "bigquery.googleapis.com",
+ "container.googleapis.com",
+ "logging.googleapis.com",
+ "run.googleapis.com",
+ "storage.googleapis.com",
+ ]
+ service_encryption_key_ids = {
+ compute = [
+ var.kms_key.id
+ ]
+ storage = [
+ var.kms_key.id
+ ]
+ }
+}
+
+module "host-project" {
+ source = "./fabric/modules/project"
+ billing_account = var.billing_account_id
+ name = "host"
+ parent = var.folder_id
+ prefix = var.prefix
+ shared_vpc_host_config = {
+ enabled = true
+ }
+}
+
+module "gcs" {
+ source = "./fabric/modules/gcs"
+ project_id = var.project_id
+ name = "gcs_sink"
+ prefix = var.prefix
+ force_destroy = true
+}
+
+module "dataset" {
+ source = "./fabric/modules/bigquery-dataset"
+ project_id = var.project_id
+ id = "bq_sink"
+ options = { delete_contents_on_destroy = true }
+}
+
+module "pubsub" {
+ source = "./fabric/modules/pubsub"
+ project_id = var.project_id
+ name = "pubsub_sink"
+}
+
+module "bucket" {
+ source = "./fabric/modules/logging-bucket"
+ parent_type = "project"
+ parent = var.project_id
+ id = "bucket"
+}
+# tftest modules=7 resources=53 inventory=data.yaml e2e
+```
+
+
## Files
diff --git a/modules/project/logging.tf b/modules/project/logging.tf
index 0181f04f56..6694c176a2 100644
--- a/modules/project/logging.tf
+++ b/modules/project/logging.tf
@@ -69,7 +69,8 @@ resource "google_logging_project_sink" "sink" {
depends_on = [
google_project_iam_binding.authoritative,
google_project_iam_binding.bindings,
- google_project_iam_member.bindings
+ google_project_iam_member.bindings,
+ google_project_service.project_services
]
}
diff --git a/modules/project/service-agents.yaml b/modules/project/service-agents.yaml
index c8eff2df97..eb38dc4cc9 100644
--- a/modules/project/service-agents.yaml
+++ b/modules/project/service-agents.yaml
@@ -18,7 +18,7 @@
service_agent: "service-%s@gcp-sa-adsdatahub.iam.gserviceaccount.com"
- name: "aiplatform"
service_agent: "service-%s@gcp-sa-aiplatform.iam.gserviceaccount.com"
- jit: true
+ jit: true # roles/aiplatform.customCodeServiceAgent
- name: "aiplatform-cc"
service_agent: "service-%s@gcp-sa-aiplatform-cc.iam.gserviceaccount.com"
- name: "alloydb"
@@ -37,7 +37,7 @@
service_agent: "service-%s@gcp-sa-apigateway-mgmt.iam.gserviceaccount.com"
- name: "apigee"
service_agent: "service-%s@gcp-sa-apigee.iam.gserviceaccount.com"
- jit: true #roles/apigee.serviceAgent
+ jit: true # roles/apigee.serviceAgent
- name: "apigeeregistry"
service_agent: "service-%s@gcp-sa-apigeeregistry.iam.gserviceaccount.com"
- name: "appdevelopmentexperience"
@@ -221,7 +221,7 @@
service_agent: "service-%s@gcp-sa-healthcare.iam.gserviceaccount.com"
- name: "iap"
service_agent: "service-%s@gcp-sa-iap.iam.gserviceaccount.com"
- jit: true
+ jit: true # none
- name: "identitytoolkit"
service_agent: "service-%s@gcp-sa-identitytoolkit.iam.gserviceaccount.com"
- name: "ids"
@@ -314,7 +314,7 @@
service_agent: "service-%s@gcp-sa-spectrumsas.iam.gserviceaccount.com"
- name: "secretmanager"
service_agent: "service-%s@gcp-sa-secretmanager.iam.gserviceaccount.com"
- jit: true
+ jit: true # none
- name: "securedlandingzone"
service_agent: "service-%s@gcp-sa-slz.iam.gserviceaccount.com"
- name: "securitycenter-notification"
diff --git a/modules/project/versions.tf b/modules/project/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/project/versions.tf
+++ b/modules/project/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/projects-data-source/versions.tf b/modules/projects-data-source/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/projects-data-source/versions.tf
+++ b/modules/projects-data-source/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/pubsub/versions.tf b/modules/pubsub/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/pubsub/versions.tf
+++ b/modules/pubsub/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/secret-manager/README.md b/modules/secret-manager/README.md
index dc0929832f..8d1d8b110b 100644
--- a/modules/secret-manager/README.md
+++ b/modules/secret-manager/README.md
@@ -17,8 +17,10 @@ module "secret-manager" {
source = "./fabric/modules/secret-manager"
project_id = "my-project"
secrets = {
- test-auto = null
- test-manual = ["europe-west1", "europe-west4"]
+ test-auto = {}
+ test-manual = {
+ locations = ["europe-west1", "europe-west4"]
+ }
}
}
# tftest modules=1 resources=2
@@ -33,8 +35,10 @@ module "secret-manager" {
source = "./fabric/modules/secret-manager"
project_id = "my-project"
secrets = {
- test-auto = null
- test-manual = ["europe-west1", "europe-west4"]
+ test-auto = {}
+ test-manual = {
+ locations = ["europe-west1", "europe-west4"]
+ }
}
iam = {
test-auto = {
@@ -57,8 +61,10 @@ module "secret-manager" {
source = "./fabric/modules/secret-manager"
project_id = "my-project"
secrets = {
- test-auto = null
- test-manual = ["europe-west1", "europe-west4"]
+ test-auto = {}
+ test-manual = {
+ locations = ["europe-west1", "europe-west4"]
+ }
}
versions = {
test-auto = {
@@ -75,34 +81,40 @@ module "secret-manager" {
### Secret with customer managed encryption key
-Secrets will be used if an encryption key is set in the `encryption_key` variable for the secret region.
+CMEK will be used if an encryption key is set in the `keys` field of `secrets` object for the secret region. For secrets with auto-replication, a global key must be specified.
```hcl
module "secret-manager" {
source = "./fabric/modules/secret-manager"
project_id = "my-project"
secrets = {
- test-encryption = ["europe-west1", "europe-west4"]
- }
- encryption_key = {
- europe-west1 = "projects/PROJECT_ID/locations/europe-west1/keyRings/KEYRING/cryptoKeys/KEY"
- europe-west4 = "projects/PROJECT_ID/locations/europe-west4/keyRings/KEYRING/cryptoKeys/KEY"
+ test-auto = {
+ keys = {
+ global = "projects/PROJECT_ID/locations/global/keyRings/KEYRING/cryptoKeys/KEY"
+ }
+ }
+ test-auto-nokeys = {}
+ test-manual = {
+ locations = ["europe-west1", "europe-west4"]
+ keys = {
+ europe-west1 = "projects/PROJECT_ID/locations/europe-west1/keyRings/KEYRING/cryptoKeys/KEY"
+ europe-west4 = "projects/PROJECT_ID/locations/europe-west4/keyRings/KEYRING/cryptoKeys/KEY"
+ }
+ }
}
}
-# tftest modules=1 resources=1
+# tftest modules=1 resources=3
```
-
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [project_id](variables.tf#L35) | Project id where the keyring will be created. | string
| ✓ | |
-| [encryption_key](variables.tf#L17) | Self link of the KMS keys in {LOCATION => KEY} format. A key must be provided for all replica locations. | map(string)
| | null
|
-| [iam](variables.tf#L23) | IAM bindings in {SECRET => {ROLE => [MEMBERS]}} format. | map(map(list(string)))
| | {}
|
-| [labels](variables.tf#L29) | Optional labels for each secret. | map(map(string))
| | {}
|
-| [secrets](variables.tf#L40) | Map of secrets to manage and their locations. If locations is null, automatic management will be set. | map(list(string))
| | {}
|
-| [versions](variables.tf#L46) | Optional versions to manage for each secret. Version names are only used internally to track individual versions. | map(map(object({…})))
| | {}
|
+| [project_id](variables.tf#L29) | Project id where the keyring will be created. | string
| ✓ | |
+| [iam](variables.tf#L17) | IAM bindings in {SECRET => {ROLE => [MEMBERS]}} format. | map(map(list(string)))
| | {}
|
+| [labels](variables.tf#L23) | Optional labels for each secret. | map(map(string))
| | {}
|
+| [secrets](variables.tf#L34) | Map of secrets to manage, their locations and KMS keys in {LOCATION => KEY} format. {GLOBAL => KEY} format enables CMEK for automatic managed secrets. If locations is null, automatic management will be set. | map(object({…}))
| | {}
|
+| [versions](variables.tf#L43) | Optional versions to manage for each secret. Version names are only used internally to track individual versions. | map(map(object({…})))
| | {}
|
## Outputs
@@ -112,7 +124,6 @@ module "secret-manager" {
| [secrets](outputs.tf#L24) | Secret resources. | |
| [version_ids](outputs.tf#L29) | Version ids keyed by secret name : version name. | |
| [versions](outputs.tf#L36) | Secret versions. | ✓ |
-
## Requirements
diff --git a/modules/secret-manager/main.tf b/modules/secret-manager/main.tf
index 1a17ac21cf..61f4d5efe2 100644
--- a/modules/secret-manager/main.tf
+++ b/modules/secret-manager/main.tf
@@ -42,27 +42,32 @@ resource "google_secret_manager_secret" "default" {
labels = lookup(var.labels, each.key, null)
dynamic "replication" {
- for_each = each.value == null ? [""] : []
+ for_each = each.value.locations == null ? [""] : []
content {
- # TODO(jccb): support custom keys inside auto
- auto {}
+ auto {
+ dynamic "customer_managed_encryption" {
+ for_each = try(lookup(each.value.keys, "global", null) == null ? [] : [""], [])
+ content {
+ kms_key_name = each.value.keys["global"]
+ }
+ }
+ }
}
}
dynamic "replication" {
- for_each = each.value == null ? [] : [each.value]
- iterator = locations
+ for_each = each.value.locations == null ? [] : [""]
content {
user_managed {
dynamic "replicas" {
- for_each = locations.value
+ for_each = each.value.locations
iterator = location
content {
location = location.value
dynamic "customer_managed_encryption" {
- for_each = try(var.encryption_key[location.value] != null ? [""] : [], [])
+ for_each = try(lookup(each.value.keys, location.value, null) == null ? [] : [""], [])
content {
- kms_key_name = var.encryption_key[location.value]
+ kms_key_name = each.value.keys[location.value]
}
}
}
@@ -88,4 +93,4 @@ resource "google_secret_manager_secret_iam_binding" "default" {
role = each.value.role
secret_id = google_secret_manager_secret.default[each.value.secret].id
members = each.value.members
-}
+}
\ No newline at end of file
diff --git a/modules/secret-manager/variables.tf b/modules/secret-manager/variables.tf
index 7d7b528484..089f2a69b2 100644
--- a/modules/secret-manager/variables.tf
+++ b/modules/secret-manager/variables.tf
@@ -1,5 +1,5 @@
/**
- * Copyright 2022 Google LLC
+ * Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,6 @@
* limitations under the License.
*/
-variable "encryption_key" {
- description = "Self link of the KMS keys in {LOCATION => KEY} format. A key must be provided for all replica locations."
- type = map(string)
- default = null
-}
-
variable "iam" {
description = "IAM bindings in {SECRET => {ROLE => [MEMBERS]}} format."
type = map(map(list(string)))
@@ -38,9 +32,12 @@ variable "project_id" {
}
variable "secrets" {
- description = "Map of secrets to manage and their locations. If locations is null, automatic management will be set."
- type = map(list(string))
- default = {}
+ description = "Map of secrets to manage, their locations and KMS keys in {LOCATION => KEY} format. {GLOBAL => KEY} format enables CMEK for automatic managed secrets. If locations is null, automatic management will be set."
+ type = map(object({
+ locations = optional(list(string), null)
+ keys = optional(map(string), null)
+ }))
+ default = {}
}
variable "versions" {
@@ -50,4 +47,4 @@ variable "versions" {
data = string
})))
default = {}
-}
+}
\ No newline at end of file
diff --git a/modules/secret-manager/versions.tf b/modules/secret-manager/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/secret-manager/versions.tf
+++ b/modules/secret-manager/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/service-directory/versions.tf b/modules/service-directory/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/service-directory/versions.tf
+++ b/modules/service-directory/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/source-repository/versions.tf b/modules/source-repository/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/source-repository/versions.tf
+++ b/modules/source-repository/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/modules/vpc-sc/README.md b/modules/vpc-sc/README.md
index 91d90d466d..ee0d63a30f 100644
--- a/modules/vpc-sc/README.md
+++ b/modules/vpc-sc/README.md
@@ -34,6 +34,8 @@ module "test" {
# tftest modules=1 resources=1 inventory=access-policy.yaml
```
+#### Scoped policy
+
If you need the module to create a scoped policy for you, specify 'scopes' of the policy in the `access_policy_create` variable:
```hcl
@@ -49,6 +51,23 @@ module "test" {
# tftest modules=1 resources=1 inventory=scoped-access-policy.yaml
```
+#### Access policy IAM
+
+The usual IAM interface is also implemented here, and can be used with service accounts or user principals:
+
+```hcl
+module "test" {
+ source = "./fabric/modules/vpc-sc"
+ access_policy = "12345678"
+ iam = {
+ "roles/accesscontextmanager.policyAdmin" = [
+ "user:foo@example.org"
+ ]
+ }
+}
+# tftest modules=1 resources=1
+```
+
### Access levels
As highlighted above, the `access_levels` type replicates the underlying resource structure.
@@ -190,6 +209,7 @@ module "test" {
| name | description | resources |
|---|---|---|
| [access-levels.tf](./access-levels.tf) | Access level resources. | google_access_context_manager_access_level
|
+| [iam.tf](./iam.tf) | IAM bindings | google_access_context_manager_access_policy_iam_binding
· google_access_context_manager_access_policy_iam_member
|
| [main.tf](./main.tf) | Module-level locals and resources. | google_access_context_manager_access_policy
|
| [outputs.tf](./outputs.tf) | Module outputs. | |
| [service-perimeters-bridge.tf](./service-perimeters-bridge.tf) | Bridge service perimeter resources. | google_access_context_manager_service_perimeter
|
@@ -205,9 +225,12 @@ module "test" {
| [access_levels](variables.tf#L17) | Access level definitions. | map(object({…}))
| | {}
|
| [access_policy_create](variables.tf#L61) | Access Policy configuration, fill in to create. Parent is in 'organizations/123456' format, scopes are in 'folders/456789' or 'projects/project_id' format. | object({…})
| | null
|
| [egress_policies](variables.tf#L71) | Egress policy definitions that can be referenced in perimeters. | map(object({…}))
| | {}
|
-| [ingress_policies](variables.tf#L102) | Ingress policy definitions that can be referenced in perimeters. | map(object({…}))
| | {}
|
-| [service_perimeters_bridge](variables.tf#L134) | Bridge service perimeters. | map(object({…}))
| | {}
|
-| [service_perimeters_regular](variables.tf#L144) | Regular service perimeters. | map(object({…}))
| | {}
|
+| [iam](variables.tf#L102) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string))
| | {}
|
+| [iam_bindings](variables.tf#L108) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | map(object({…}))
| | {}
|
+| [iam_bindings_additive](variables.tf#L123) | Individual additive IAM bindings. Keys are arbitrary. | map(object({…}))
| | {}
|
+| [ingress_policies](variables.tf#L138) | Ingress policy definitions that can be referenced in perimeters. | map(object({…}))
| | {}
|
+| [service_perimeters_bridge](variables.tf#L170) | Bridge service perimeters. | map(object({…}))
| | {}
|
+| [service_perimeters_regular](variables.tf#L180) | Regular service perimeters. | map(object({…}))
| | {}
|
## Outputs
diff --git a/modules/vpc-sc/iam.tf b/modules/vpc-sc/iam.tf
new file mode 100644
index 0000000000..9b475b68fd
--- /dev/null
+++ b/modules/vpc-sc/iam.tf
@@ -0,0 +1,54 @@
+/**
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+# tfdoc:file:description IAM bindings
+
+resource "google_access_context_manager_access_policy_iam_binding" "authoritative" {
+ for_each = var.iam
+ name = local.access_policy
+ role = each.key
+ members = each.value
+}
+
+resource "google_access_context_manager_access_policy_iam_binding" "bindings" {
+ for_each = var.iam_bindings
+ name = local.access_policy
+ role = each.value.role
+ members = each.value.members
+ dynamic "condition" {
+ for_each = each.value.condition == null ? [] : [""]
+ content {
+ expression = each.value.condition.expression
+ title = each.value.condition.title
+ description = each.value.condition.description
+ }
+ }
+}
+
+resource "google_access_context_manager_access_policy_iam_member" "bindings" {
+ for_each = var.iam_bindings_additive
+ name = local.access_policy
+ role = each.value.role
+ member = each.value.member
+ dynamic "condition" {
+ for_each = each.value.condition == null ? [] : [""]
+ content {
+ expression = each.value.condition.expression
+ title = each.value.condition.title
+ description = each.value.condition.description
+ }
+ }
+}
diff --git a/modules/vpc-sc/variables.tf b/modules/vpc-sc/variables.tf
index 8ce4b41eb1..008d7ae215 100644
--- a/modules/vpc-sc/variables.tf
+++ b/modules/vpc-sc/variables.tf
@@ -99,6 +99,42 @@ variable "egress_policies" {
}
}
+variable "iam" {
+ description = "IAM bindings in {ROLE => [MEMBERS]} format."
+ type = map(list(string))
+ default = {}
+}
+
+variable "iam_bindings" {
+ description = "Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary."
+ type = map(object({
+ members = list(string)
+ role = string
+ condition = optional(object({
+ expression = string
+ title = string
+ description = optional(string)
+ }))
+ }))
+ nullable = false
+ default = {}
+}
+
+variable "iam_bindings_additive" {
+ description = "Individual additive IAM bindings. Keys are arbitrary."
+ type = map(object({
+ member = string
+ role = string
+ condition = optional(object({
+ expression = string
+ title = string
+ description = optional(string)
+ }))
+ }))
+ nullable = false
+ default = {}
+}
+
variable "ingress_policies" {
description = "Ingress policy definitions that can be referenced in perimeters."
type = map(object({
diff --git a/modules/vpc-sc/versions.tf b/modules/vpc-sc/versions.tf
index af3463955f..3adb51d3bd 100644
--- a/modules/vpc-sc/versions.tf
+++ b/modules/vpc-sc/versions.tf
@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 5.0.0, < 6.0.0" # tftest
+ version = ">= 5.4.0, < 6.0.0" # tftest
}
}
}
diff --git a/tests/blueprints/factories/project_factory/examples/example.yaml b/tests/blueprints/factories/project_factory/examples/example.yaml
index 859ec2ee29..71391a526a 100644
--- a/tests/blueprints/factories/project_factory/examples/example.yaml
+++ b/tests/blueprints/factories/project_factory/examples/example.yaml
@@ -30,6 +30,10 @@ values:
module.project-factory.module.projects["prj-app-1"].google_project.project[0]:
auto_create_network: false
billing_account: 012345-67890A-BCDEF0
+ effective_labels:
+ app: app-1
+ environment: test
+ team: foo
folder_id: '12345678'
labels:
app: app-1
@@ -39,6 +43,16 @@ values:
org_id: null
project_id: test-pf-prj-app-1
skip_delete: false
+ terraform_labels:
+ app: app-1
+ environment: test
+ team: foo
+ timeouts: null
+ module.project-factory.module.projects["prj-app-1"].google_project_service.project_services["container.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-pf-prj-app-1
+ service: container.googleapis.com
timeouts: null
module.project-factory.module.projects["prj-app-1"].google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
@@ -52,6 +66,14 @@ values:
project: test-pf-prj-app-1
service: storage.googleapis.com
timeouts: null
+ module.project-factory.module.projects["prj-app-2"].data.google_storage_project_service_account.gcs_sa[0]:
+ project: test-pf-prj-app-2
+ user_project: null
+ module.project-factory.module.projects["prj-app-2"].google_compute_shared_vpc_service_project.shared_vpc_service[0]:
+ deletion_policy: null
+ host_project: foo-host
+ service_project: test-pf-prj-app-2
+ timeouts: null
module.project-factory.module.projects["prj-app-2"].google_essential_contacts_contact.contact["admin@example.com"]:
email: admin@example.com
language_tag: en
@@ -59,44 +81,38 @@ values:
- ALL
parent: projects/test-pf-prj-app-2
timeouts: null
- ? module.project-factory.module.projects["prj-app-2"].google_org_policy_policy.default["compute.disableGuestAttributesAccess"]
- : name: projects/test-pf-prj-app-2/policies/compute.disableGuestAttributesAccess
- parent: projects/test-pf-prj-app-2
- spec:
- - inherit_from_parent: null
- reset: null
- rules:
- - allow_all: null
- condition: []
- deny_all: null
- enforce: 'FALSE'
- values: []
- timeouts: null
- ? module.project-factory.module.projects["prj-app-2"].google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]
- : name: projects/test-pf-prj-app-2/policies/iam.disableServiceAccountKeyCreation
- parent: projects/test-pf-prj-app-2
- spec:
- - inherit_from_parent: null
- reset: null
- rules:
- - allow_all: null
- condition: []
- deny_all: null
- enforce: 'FALSE'
- values: []
- timeouts: null
module.project-factory.module.projects["prj-app-2"].google_project.project[0]:
auto_create_network: false
billing_account: 012345-67890A-ABCDEF
+ effective_labels:
+ app: app-2
+ environment: test
+ team: foo
folder_id: '12345678'
labels:
- app: app-1
+ app: app-2
environment: test
team: foo
name: test-pf-prj-app-2
org_id: null
project_id: test-pf-prj-app-2
skip_delete: false
+ terraform_labels:
+ app: app-2
+ environment: test
+ team: foo
+ timeouts: null
+ module.project-factory.module.projects["prj-app-2"].google_project_service.project_services["compute.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-pf-prj-app-2
+ service: compute.googleapis.com
+ timeouts: null
+ module.project-factory.module.projects["prj-app-2"].google_project_service.project_services["run.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-pf-prj-app-2
+ service: run.googleapis.com
timeouts: null
module.project-factory.module.projects["prj-app-2"].google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
@@ -104,37 +120,95 @@ values:
project: test-pf-prj-app-2
service: stackdriver.googleapis.com
timeouts: null
+ module.project-factory.module.projects["prj-app-2"].google_project_service.project_services["storage.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-pf-prj-app-2
+ service: storage.googleapis.com
+ timeouts: null
+ module.project-factory.module.projects["prj-app-3"].data.google_storage_project_service_account.gcs_sa[0]:
+ project: test-pf-prj-app-3
+ user_project: null
+ module.project-factory.module.projects["prj-app-3"].google_essential_contacts_contact.contact["admin@example.com"]:
+ email: admin@example.com
+ language_tag: en
+ notification_category_subscriptions:
+ - ALL
+ parent: projects/test-pf-prj-app-3
+ timeouts: null
+ module.project-factory.module.projects["prj-app-3"].google_project.project[0]:
+ auto_create_network: false
+ billing_account: 012345-67890A-ABCDEF
+ effective_labels:
+ environment: test
+ folder_id: '12345678'
+ labels:
+ environment: test
+ name: test-pf-prj-app-3
+ org_id: null
+ project_id: test-pf-prj-app-3
+ skip_delete: false
+ terraform_labels:
+ environment: test
+ timeouts: null
+ module.project-factory.module.projects["prj-app-3"].google_project_service.project_services["run.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-pf-prj-app-3
+ service: run.googleapis.com
+ timeouts: null
+ module.project-factory.module.projects["prj-app-3"].google_project_service.project_services["stackdriver.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-pf-prj-app-3
+ service: stackdriver.googleapis.com
+ timeouts: null
+ module.project-factory.module.projects["prj-app-3"].google_project_service.project_services["storage.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-pf-prj-app-3
+ service: storage.googleapis.com
+ timeouts: null
+ ? module.project-factory.module.service-accounts["prj-app-1-app-1-be"].google_project_iam_member.project-roles["test-pf-prj-app-1-roles/logging.logWriter"]
+ : condition: []
+ project: test-pf-prj-app-1
+ role: roles/logging.logWriter
+ ? module.project-factory.module.service-accounts["prj-app-1-app-1-be"].google_project_iam_member.project-roles["test-pf-prj-app-1-roles/monitoring.metricWriter"]
+ : condition: []
+ project: test-pf-prj-app-1
+ role: roles/monitoring.metricWriter
module.project-factory.module.service-accounts["prj-app-1-app-1-be"].google_service_account.service_account[0]:
account_id: app-1-be
description: null
disabled: false
- display_name: Terraform-managed.
+ display_name: null
project: test-pf-prj-app-1
timeouts: null
module.project-factory.module.service-accounts["prj-app-1-app-1-fe"].google_service_account.service_account[0]:
account_id: app-1-fe
description: null
disabled: false
- display_name: Terraform-managed.
+ display_name: Test app 1 frontend.
project: test-pf-prj-app-1
timeouts: null
module.project-factory.module.service-accounts["prj-app-2-app-2-be"].google_service_account.service_account[0]:
account_id: app-2-be
description: null
disabled: false
- display_name: Terraform-managed.
+ display_name: null
project: test-pf-prj-app-2
timeouts: null
counts:
- google_essential_contacts_contact: 2
+ google_compute_shared_vpc_service_project: 1
+ google_essential_contacts_contact: 3
google_kms_crypto_key_iam_member: 1
- google_org_policy_policy: 2
- google_project: 2
- google_project_service: 3
+ google_project: 3
+ google_project_iam_member: 2
+ google_project_service: 10
google_service_account: 3
- google_storage_project_service_account: 1
- modules: 6
- resources: 14
+ google_storage_project_service_account: 3
+ modules: 7
+ resources: 26
outputs: {}
diff --git a/tests/examples/test_plan.py b/tests/examples/test_plan.py
index 3ff2992ed5..22525698ed 100644
--- a/tests/examples/test_plan.py
+++ b/tests/examples/test_plan.py
@@ -18,9 +18,18 @@
from pathlib import Path
BASE_PATH = Path(__file__).parent
-COUNT_TEST_RE = re.compile(r'# tftest +modules=(\d+) +resources=(\d+)' +
- r'(?: +files=([\w@,_-]+))?' +
- r'(?: +inventory=([\w\-.]+))?')
+COUNT_TEST_RE = re.compile(r'# tftest +modules=(?P\d+) +resources=(?P\d+)' +
+ r'(?: +files=(?P[\w@,_-]+))?' +
+ r'(?: +inventory=(?P[\w\-.]+))?')
+
+
+def prepare_files(example, test_path, line):
+ if line is not None:
+ requested_files = line.split(',')
+ for f in requested_files:
+ destination = test_path / example.files[f].path
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ destination.write_text(example.files[f].content)
def test_example(plan_validator, tmp_path, example):
@@ -33,21 +42,16 @@ def test_example(plan_validator, tmp_path, example):
if assets_path.exists():
(tmp_path / 'assets').symlink_to(assets_path)
- expected_modules = int(match.group(1))
- expected_resources = int(match.group(2))
+ expected_modules = int(match.group("modules"))
+ expected_resources = int(match.group("resources"))
- if match.group(3) is not None:
- requested_files = match.group(3).split(',')
- for f in requested_files:
- destination = tmp_path / example.files[f].path
- destination.parent.mkdir(parents=True, exist_ok=True)
- destination.write_text(example.files[f].content)
+ prepare_files(example, tmp_path, match.group("files"))
inventory = []
- if match.group(4) is not None:
+ if match.group("inventory") is not None:
python_test_path = str(example.module).replace('-', '_')
inventory = BASE_PATH.parent / python_test_path / 'examples'
- inventory = inventory / match.group(4)
+ inventory = inventory / match.group("inventory")
# TODO: force plan_validator to never copy files (we're already
# running from a temp dir)
diff --git a/tests/examples/variables.tf b/tests/examples/variables.tf
index 9a65aa7a52..ebdbb155cb 100644
--- a/tests/examples/variables.tf
+++ b/tests/examples/variables.tf
@@ -22,9 +22,13 @@ variable "billing_account_id" {
default = "123456-123456-123456"
}
+variable "group_email" {
+ default = "organization-admins@example.org"
+}
+
variable "kms_key" {
default = {
- self_link = "kms_key_self_link"
+ id = "kms_key_self_link"
}
}
diff --git a/tests/examples_e2e/README.md b/tests/examples_e2e/README.md
index 027ef21c8a..bab4337288 100644
--- a/tests/examples_e2e/README.md
+++ b/tests/examples_e2e/README.md
@@ -9,7 +9,7 @@ Prepare following information:
* prepare service account that has necessary permissions (able to assign billing account to project, resource creation etc)
# How does it work
-Each test case is provided by additional environment defined in [variables.tf](./variables.tf). This simplifies writing the examples as this follows the same structure as for non-end-to-end tests, and allows multiple, independent and concurrent runs of tests.
+Each test case is provided by additional environment defined in [variables.tf](../examples/variables.tf). This simplifies writing the examples as this follows the same structure as for non-end-to-end tests, and allows multiple, independent and concurrent runs of tests.
The test environment can be provisioned automatically during the test run (which now takes ~2 minutes) and destroyed and the end, when of the tests (Option 1 below), which is targeting automated runs in CI/CD pipeline, or can be provisioned manually to reduce test time, which might be typical use case for tests run locally.
@@ -18,6 +18,7 @@ The test environment can be provisioned automatically during the test run (which
## Create `e2e.tfvars` file
```hcl
billing_account = "123456-123456-123456" # billing account id to associate projects
+group_email = "group@example.org" # existing group within organization
organization_id = "1234567890" # your organization id
parent = "folders/1234567890" # folder under which test resources will be created
prefix = "your-unique-prefix" # unique prefix for projects
@@ -27,15 +28,17 @@ region = "europe-west4" # region to use
```
And set environment variable pointing to the file:
```bash
+export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects, no longer than 7 characters
export TFTEST_E2E_SETUP_TFVARS_PATH=
```
Or set above variables in environment:
```bash
export TF_VAR_billing_account="123456-123456-123456" # billing account id to associate projects
+export TF_VAR_group_email="group@example.org" # existing group within organization
export TF_VAR_organization_id="1234567890" # your organization id
export TF_VAR_parent="folders/1234567890" # folder under which test resources will be created
-export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects
+export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects, no longer than 7 characters
export TF_VAR_region="europe-west4" # region to use
```
@@ -55,6 +58,7 @@ pytest tests/examples_e2e
In `tests/examples_e2e/setup_module` create `terraform.tfvars` with following values:
```hcl
billing_account = "123456-123456-123456" # billing account id to associate projects
+group_email = "group@example.org" # existing group within organization
organization_id = "1234567890" # your organization id
parent = "folders/1234567890" # folder under which test resources will be created
prefix = "your-unique-prefix" # unique prefix for projects
@@ -79,6 +83,7 @@ This will generate also `tests/examples_e2e/setup_module/e2e_tests.tfvars` for y
## Setup your environment
```bash
export TFTEST_E2E_TFVARS_PATH=`pwd`/tests/examples_e2e/setup_module/e2e_tests.tfvars # generated above
+export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects, no longer than 7 characters
```
## Run tests
diff --git a/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl b/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl
index c21d77422a..31a34d3df5 100644
--- a/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl
+++ b/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl
@@ -12,14 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-bucket= "${bucket}"
+bucket = "${bucket}"
billing_account_id = "${billing_account_id}"
-kms_key= {
- self_link = "kms_key_self_link"
+kms_key = {
+ id = "${kms_key_id}"
}
+group_email = "${group_email}"
organization_id = "${organization_id}"
-folder_id = "${folder_id}"
-prefix = "${prefix}"
+folder_id = "folders/${folder_id}"
project_id = "${project_id}"
region = "${region}"
service_account = {
diff --git a/tests/examples_e2e/setup_module/main.tf b/tests/examples_e2e/setup_module/main.tf
index 9bc5a9799c..e781d779bc 100644
--- a/tests/examples_e2e/setup_module/main.tf
+++ b/tests/examples_e2e/setup_module/main.tf
@@ -13,11 +13,14 @@
# limitations under the License.
locals {
- prefix = "${var.prefix}-${var.timestamp}-${var.suffix}"
+ prefix = "${var.prefix}-${var.timestamp}${var.suffix}"
services = [
# trimmed down list of services, to be extended as needed
+ "apigee.googleapis.com",
+ "bigquery.googleapis.com",
"cloudbuild.googleapis.com",
"cloudfunctions.googleapis.com",
+ "cloudkms.googleapis.com",
"cloudresourcemanager.googleapis.com",
"compute.googleapis.com",
"iam.googleapis.com",
@@ -77,14 +80,28 @@ resource "google_service_account" "service_account" {
depends_on = [google_project_service.project_service]
}
+resource "google_kms_key_ring" "keyring" {
+ name = "keyring"
+ project = google_project.project.project_id
+ location = var.region
+ depends_on = [google_project_service.project_service]
+}
+
+resource "google_kms_crypto_key" "key" {
+ name = "crypto-key-example"
+ key_ring = google_kms_key_ring.keyring.id
+ rotation_period = "100000s"
+}
+
resource "local_file" "terraform_tfvars" {
filename = "e2e_tests.tfvars"
content = templatefile("e2e_tests.tfvars.tftpl", {
bucket = google_storage_bucket.bucket.name
billing_account_id = var.billing_account
- organization_id = var.organization_id
folder_id = google_folder.folder.folder_id
- prefix = local.prefix
+ group_email = var.group_email
+ kms_key_id = google_kms_crypto_key.key.id
+ organization_id = var.organization_id
project_id = google_project.project.project_id
region = var.region
service_account = {
diff --git a/tests/examples_e2e/setup_module/variables.tf b/tests/examples_e2e/setup_module/variables.tf
index d936cb2080..16f110df0a 100644
--- a/tests/examples_e2e/setup_module/variables.tf
+++ b/tests/examples_e2e/setup_module/variables.tf
@@ -15,6 +15,9 @@
variable "billing_account" {
type = string
}
+variable "group_email" {
+ type = string
+}
variable "organization_id" {
type = string
}
diff --git a/tests/examples_e2e/test_plan.py b/tests/examples_e2e/test_plan.py
index 84579b6b41..c9936b9bbf 100644
--- a/tests/examples_e2e/test_plan.py
+++ b/tests/examples_e2e/test_plan.py
@@ -14,16 +14,14 @@
import re
from pathlib import Path
+from ..examples.test_plan import COUNT_TEST_RE, prepare_files
BASE_PATH = Path(__file__).parent
-COUNT_TEST_RE = re.compile(r'# tftest +modules=(\d+) +resources=(\d+)' +
- r'(?: +files=([\w@,_-]+))?' +
- r'(?: +inventory=([\w\-.]+))?')
def test_example(e2e_validator, tmp_path, examples_e2e, e2e_tfvars_path):
(tmp_path / 'fabric').symlink_to(BASE_PATH.parents[1])
- (tmp_path / 'variables.tf').symlink_to(BASE_PATH / 'variables.tf')
+ (tmp_path / 'variables.tf').symlink_to(BASE_PATH.parent / 'examples' / 'variables.tf')
(tmp_path / 'main.tf').write_text(examples_e2e.code)
assets_path = BASE_PATH.parent / str(examples_e2e.module).replace(
'-', '_') / 'assets'
@@ -31,5 +29,9 @@ def test_example(e2e_validator, tmp_path, examples_e2e, e2e_tfvars_path):
(tmp_path / 'assets').symlink_to(assets_path)
(tmp_path / 'terraform.tfvars').symlink_to(e2e_tfvars_path)
+ # add files the same way as it is done for examples
+ if match := COUNT_TEST_RE.search(examples_e2e.code):
+ prepare_files(examples_e2e, tmp_path, match.group("files"))
+
e2e_validator(module_path=tmp_path, extra_files=[],
tf_var_files=[(tmp_path / 'terraform.tfvars')])
diff --git a/tests/examples_e2e/variables.tf b/tests/examples_e2e/variables.tf
deleted file mode 100644
index 9a65aa7a52..0000000000
--- a/tests/examples_e2e/variables.tf
+++ /dev/null
@@ -1,92 +0,0 @@
-# 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.
-
-# common variables used for examples
-
-variable "bucket" {
- default = "bucket"
-}
-
-variable "billing_account_id" {
- default = "123456-123456-123456"
-}
-
-variable "kms_key" {
- default = {
- self_link = "kms_key_self_link"
- }
-}
-
-variable "organization_id" {
- default = "organizations/1122334455"
-}
-
-variable "folder_id" {
- default = "folders/1122334455"
-}
-
-variable "prefix" {
- default = "test"
-}
-
-variable "project_id" {
- default = "project-id"
-}
-
-variable "region" {
- default = "region"
-}
-
-variable "service_account" {
- default = {
- id = "service_account_id"
- email = "service_account_email"
- iam_email = "service_account_iam_email"
- }
-}
-
-variable "subnet" {
- default = {
- name = "subnet_name"
- region = "subnet_region"
- cidr = "subnet_cidr"
- self_link = "subnet_self_link"
- }
-}
-
-variable "vpc" {
- default = {
- name = "vpc_name"
- self_link = "projects/xxx/global/networks/aaa"
- id = "projects/xxx/global/networks/aaa"
- }
-}
-
-variable "vpc1" {
- default = {
- name = "vpc_name"
- self_link = "projects/xxx/global/networks/bbb"
- }
-}
-
-variable "vpc2" {
- default = {
- name = "vpc2_name"
- self_link = "projects/xxx/global/networks/ccc"
- }
-}
-
-variable "zone" {
- default = "zone"
-}
diff --git a/tests/fixtures.py b/tests/fixtures.py
index caa9c9456f..01a89f423c 100644
--- a/tests/fixtures.py
+++ b/tests/fixtures.py
@@ -298,9 +298,12 @@ def e2e_validator(module_path, extra_files, tf_var_files, basedir=None):
tf.setup(extra_files=extra_files, upgrade=True)
tf_var_files = [(basedir / x).resolve() for x in tf_var_files or []]
+ # to allow different tests to create projects (or other globally unique resources) with the same name
+ # bump prefix forward on each test execution
+ prefix = f'{os.environ.get("TF_VAR_prefix")}-{int(time.time())}{os.environ.get("PYTEST_XDIST_WORKER", "0")[-2:]}'
try:
- apply = tf.apply(tf_var_file=tf_var_files)
- plan = tf.plan(output=True, tf_var_file=tf_var_files)
+ apply = tf.apply(tf_var_file=tf_var_files, tf_vars={"prefix": prefix})
+ plan = tf.plan(output=True, tf_var_file=tf_var_files, tf_vars={"prefix": prefix})
changes = {}
for resource_name, value in plan.resource_changes.items():
if value.get('change', {}).get('actions') != ['no-op']:
@@ -324,7 +327,7 @@ def e2e_validator(module_path, extra_files, tf_var_files, basedir=None):
# If above did not fail, this should not either, but left as a safety check
assert changes == {}, f'Plan not empty for following resources: {", ".join(changes.keys())}'
finally:
- destroy = tf.destroy(tf_var_file=tf_var_files)
+ destroy = tf.destroy(tf_var_file=tf_var_files, tf_vars={'prefix': prefix})
@pytest.fixture(name='e2e_validator')
@@ -371,7 +374,7 @@ def e2e_tfvars_path():
tf = tftest.TerraformTest(test_path, binary=binary)
tf_vars_file = None
tf_vars = {
- 'suffix': os.environ.get("PYTEST_XDIST_WORKER", "0"),
+ 'suffix': os.environ.get("PYTEST_XDIST_WORKER", "0")[-2:], # take at most 2 last chars for suffix
'timestamp': str(int(time.time()))
}
if 'TFTEST_E2E_SETUP_TFVARS_PATH' in os.environ:
diff --git a/tests/modules/cloudsql_instance/examples/insights.yaml b/tests/modules/cloudsql_instance/examples/insights.yaml
index 1c54188352..84a4245ddf 100644
--- a/tests/modules/cloudsql_instance/examples/insights.yaml
+++ b/tests/modules/cloudsql_instance/examples/insights.yaml
@@ -20,18 +20,10 @@ values:
region: europe-west1
settings:
- activation_policy: ALWAYS
- active_directory_config: []
- advanced_machine_features: []
availability_type: ZONAL
- collation: null
- data_cache_config: []
- database_flags: []
deletion_protection_enabled: true
- deny_maintenance_period: []
disk_autoresize: true
- disk_autoresize_limit: 0
disk_type: PD_SSD
- edition: null
insights_config:
- query_insights_enabled: true
query_plans_per_minute: 5
@@ -41,17 +33,9 @@ values:
ip_configuration:
- allocated_ip_range: null
authorized_networks: []
- enable_private_path_for_google_cloud_services: null
ipv4_enabled: false
private_network: projects/xxx/global/networks/aaa
- psc_config: []
- require_ssl: null
- maintenance_window: []
- password_validation_policy: []
- pricing_plan: PER_USE
- sql_server_audit_config: []
tier: db-g1-small
- time_zone: null
counts:
google_sql_database_instance: 1
diff --git a/tests/modules/cloudsql_instance/examples/public-ip.yaml b/tests/modules/cloudsql_instance/examples/public-ip.yaml
index 9ba4622033..f3ca86d3a5 100644
--- a/tests/modules/cloudsql_instance/examples/public-ip.yaml
+++ b/tests/modules/cloudsql_instance/examples/public-ip.yaml
@@ -18,46 +18,19 @@ values:
name: db
project: project-id
region: europe-west1
- restore_backup_context: []
settings:
- activation_policy: ALWAYS
- active_directory_config: []
- advanced_machine_features: []
availability_type: ZONAL
- backup_configuration:
- - backup_retention_settings:
- - retained_backups: 7
- retention_unit: COUNT
- binary_log_enabled: true
- enabled: true
- location: null
- point_in_time_recovery_enabled: null
- start_time: '23:00'
- transaction_log_retention_days: 7
- collation: null
- data_cache_config: []
- database_flags: []
deletion_protection_enabled: true
- deny_maintenance_period: []
disk_autoresize: true
- disk_autoresize_limit: 0
disk_type: PD_SSD
- edition: null
insights_config: []
ip_configuration:
- allocated_ip_range: null
authorized_networks: []
- enable_private_path_for_google_cloud_services: null
ipv4_enabled: true
private_network: projects/xxx/global/networks/aaa
- psc_config: []
- require_ssl: null
- maintenance_window: []
- password_validation_policy: []
- pricing_plan: PER_USE
- sql_server_audit_config: []
tier: db-g1-small
- time_zone: null
module.db.google_sql_database_instance.replicas["replica1"]:
database_version: MYSQL_8_0
master_instance_name: db
@@ -66,34 +39,17 @@ values:
region: europe-west3
settings:
- activation_policy: ALWAYS
- active_directory_config: []
- advanced_machine_features: []
availability_type: ZONAL
- collation: null
- data_cache_config: []
- database_flags: []
deletion_protection_enabled: true
- deny_maintenance_period: []
disk_autoresize: true
- disk_autoresize_limit: 0
disk_type: PD_SSD
- edition: null
insights_config: []
ip_configuration:
- allocated_ip_range: null
authorized_networks: []
- enable_private_path_for_google_cloud_services: null
ipv4_enabled: true
- psc_config: []
private_network: projects/xxx/global/networks/aaa
- require_ssl: null
- maintenance_window: []
- password_validation_policy: []
- pricing_plan: PER_USE
- sql_server_audit_config: []
tier: db-g1-small
- time_zone: null
- timeouts: null
counts:
google_sql_database_instance: 2
diff --git a/tests/modules/cloudsql_instance/examples/simple.yaml b/tests/modules/cloudsql_instance/examples/simple.yaml
index d4c0558d9c..fdc663e219 100644
--- a/tests/modules/cloudsql_instance/examples/simple.yaml
+++ b/tests/modules/cloudsql_instance/examples/simple.yaml
@@ -14,39 +14,22 @@
values:
module.db.google_sql_database_instance.primary:
- clone: []
database_version: POSTGRES_13
name: db
project: my-db-project
region: europe-west1
settings:
- activation_policy: ALWAYS
- active_directory_config: []
- advanced_machine_features: []
availability_type: ZONAL
- collation: null
- data_cache_config: []
- database_flags: []
deletion_protection_enabled: true
- deny_maintenance_period: []
disk_autoresize: true
- disk_autoresize_limit: 0
disk_type: PD_SSD
- edition: null
insights_config: []
ip_configuration:
- allocated_ip_range: null
authorized_networks: []
- enable_private_path_for_google_cloud_services: null
ipv4_enabled: false
- psc_config: []
- require_ssl: null
- maintenance_window: []
- password_validation_policy: []
- pricing_plan: PER_USE
- sql_server_audit_config: []
tier: db-g1-small
- time_zone: null
counts:
google_sql_database_instance: 1
diff --git a/tests/modules/project/examples/basic.yaml b/tests/modules/project/examples/basic.yaml
index 56e6ecc02f..919a0581ee 100644
--- a/tests/modules/project/examples/basic.yaml
+++ b/tests/modules/project/examples/basic.yaml
@@ -17,21 +17,21 @@ values:
module.project.google_project.project[0]:
auto_create_network: false
billing_account: 123456-123456-123456
- folder_id: '1234567890'
+ folder_id: '1122334455'
labels: null
- name: foo-myproject
+ name: test-project
org_id: null
- project_id: foo-myproject
+ project_id: test-project
skip_delete: false
module.project.google_project_service.project_services["container.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
- project: foo-myproject
+ project: test-project
service: container.googleapis.com
module.project.google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
- project: foo-myproject
+ project: test-project
service: stackdriver.googleapis.com
counts:
diff --git a/tests/modules/project/examples/data.yaml b/tests/modules/project/examples/data.yaml
new file mode 100644
index 0000000000..b7ec3d23aa
--- /dev/null
+++ b/tests/modules/project/examples/data.yaml
@@ -0,0 +1,338 @@
+# 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.
+
+
+values:
+ module.bucket.google_logging_project_bucket_config.bucket[0]:
+ bucket_id: bucket
+ project: project-id
+ module.create-project.google_project.project[0]:
+ billing_account: 123456-123456-123456
+ folder_id: '1122334455'
+ name: test-project
+ project_id: test-project
+ module.dataset.google_bigquery_dataset.default:
+ dataset_id: bq_sink
+ delete_contents_on_destroy: true
+ project: project-id
+ module.gcs.google_storage_bucket.bucket:
+ name: test-gcs_sink
+ project: project-id
+ module.host-project.google_compute_shared_vpc_host_project.shared_vpc_host[0]:
+ project: test-host
+ module.host-project.google_project.project[0]:
+ billing_account: 123456-123456-123456
+ folder_id: '1122334455'
+ name: test-host
+ project_id: test-host
+ module.project.data.google_bigquery_default_service_account.bq_sa[0]:
+ project: test-project
+ module.project.data.google_project.project[0]:
+ project_id: test-project
+ module.project.data.google_storage_project_service_account.gcs_sa[0]:
+ project: test-project
+ module.project.google_bigquery_dataset_iam_member.bq-sinks-binding["info"]:
+ role: roles/bigquery.dataEditor
+ module.project.google_compute_shared_vpc_service_project.shared_vpc_service[0]:
+ host_project: test-host
+ service_project: test-project
+ module.project.google_kms_crypto_key_iam_member.service_identity_cmek["compute.kms_key_self_link"]:
+ crypto_key_id: kms_key_self_link
+ role: roles/cloudkms.cryptoKeyEncrypterDecrypter
+ module.project.google_kms_crypto_key_iam_member.service_identity_cmek["storage.kms_key_self_link"]:
+ crypto_key_id: kms_key_self_link
+ role: roles/cloudkms.cryptoKeyEncrypterDecrypter
+ module.project.google_logging_project_exclusion.logging-exclusion["no-gce-instances"]:
+ filter: resource.type=gce_instance
+ name: no-gce-instances
+ project: test-project
+ module.project.google_logging_project_sink.sink["debug"]:
+ exclusions:
+ - description: null
+ disabled: false
+ filter: logName:compute
+ name: no-compute
+ filter: severity=DEBUG
+ name: debug
+ project: test-project
+ module.project.google_logging_project_sink.sink["info"]:
+ exclusions: []
+ filter: severity=INFO
+ name: info
+ project: test-project
+ module.project.google_logging_project_sink.sink["notice"]:
+ destination: pubsub.googleapis.com/projects/project-id/topics/pubsub_sink
+ disabled: false
+ exclusions: []
+ filter: severity=NOTICE
+ name: notice
+ project: test-project
+ module.project.google_logging_project_sink.sink["warnings"]:
+ destination: storage.googleapis.com/test-gcs_sink
+ disabled: false
+ exclusions: []
+ filter: severity=WARNING
+ name: warnings
+ project: test-project
+ module.project.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]:
+ name: projects/test-project/policies/compute.disableGuestAttributesAccess
+ parent: projects/test-project
+ spec:
+ - inherit_from_parent: null
+ rules:
+ - allow_all: null
+ condition: []
+ deny_all: null
+ enforce: 'TRUE'
+ values: []
+ module.project.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]:
+ name: projects/test-project/policies/compute.skipDefaultNetworkCreation
+ parent: projects/test-project
+ spec:
+ - inherit_from_parent: null
+ rules:
+ - allow_all: null
+ condition: []
+ deny_all: null
+ enforce: 'TRUE'
+ values: []
+ module.project.google_org_policy_policy.default["compute.trustedImageProjects"]:
+ name: projects/test-project/policies/compute.trustedImageProjects
+ parent: projects/test-project
+ spec:
+ - inherit_from_parent: null
+ rules:
+ - allow_all: null
+ condition: []
+ deny_all: null
+ enforce: null
+ values:
+ - allowed_values:
+ - projects/my-project
+ denied_values: null
+ module.project.google_org_policy_policy.default["compute.vmExternalIpAccess"]:
+ name: projects/test-project/policies/compute.vmExternalIpAccess
+ parent: projects/test-project
+ spec:
+ - inherit_from_parent: null
+ rules:
+ - allow_all: null
+ condition: []
+ deny_all: 'TRUE'
+ enforce: null
+ values: []
+ module.project.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]:
+ name: projects/test-project/policies/iam.allowedPolicyMemberDomains
+ parent: projects/test-project
+ spec:
+ - inherit_from_parent: null
+ rules:
+ - allow_all: null
+ condition: []
+ deny_all: null
+ enforce: null
+ values:
+ - allowed_values:
+ - C0xxxxxxx
+ - C0yyyyyyy
+ denied_values: null
+ module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]:
+ name: projects/test-project/policies/iam.disableServiceAccountKeyCreation
+ parent: projects/test-project
+ spec:
+ - inherit_from_parent: null
+ rules:
+ - allow_all: null
+ condition: []
+ deny_all: null
+ enforce: 'TRUE'
+ values: []
+ module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]:
+ name: projects/test-project/policies/iam.disableServiceAccountKeyUpload
+ parent: projects/test-project
+ spec:
+ - inherit_from_parent: null
+ rules:
+ - allow_all: null
+ condition:
+ - description: test condition
+ expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234')
+ location: somewhere
+ title: condition
+ deny_all: null
+ enforce: 'TRUE'
+ values: []
+ - allow_all: null
+ condition: []
+ deny_all: null
+ enforce: 'FALSE'
+ values: []
+ module.project.google_project_iam_audit_config.default["allServices"]:
+ audit_log_config:
+ - exempted_members:
+ - group:organization-admins@example.org
+ log_type: ADMIN_READ
+ project: test-project
+ service: allServices
+ module.project.google_project_iam_audit_config.default["storage.googleapis.com"]:
+ audit_log_config:
+ - exempted_members: []
+ log_type: DATA_READ
+ - exempted_members: []
+ log_type: DATA_WRITE
+ project: test-project
+ service: storage.googleapis.com
+ module.project.google_project_iam_binding.authoritative["roles/apigee.serviceAgent"]:
+ condition: []
+ project: test-project
+ role: roles/apigee.serviceAgent
+ module.project.google_project_iam_binding.authoritative["roles/cloudasset.owner"]:
+ condition: []
+ project: test-project
+ role: roles/cloudasset.owner
+ module.project.google_project_iam_binding.authoritative["roles/cloudsupport.techSupportEditor"]:
+ condition: []
+ project: test-project
+ role: roles/cloudsupport.techSupportEditor
+ module.project.google_project_iam_binding.authoritative["roles/editor"]:
+ condition: []
+ project: test-project
+ role: roles/editor
+ module.project.google_project_iam_binding.authoritative["roles/iam.securityReviewer"]:
+ condition: []
+ project: test-project
+ role: roles/iam.securityReviewer
+ module.project.google_project_iam_binding.authoritative["roles/logging.admin"]:
+ condition: []
+ project: test-project
+ role: roles/logging.admin
+ module.project.google_project_iam_binding.bindings["iam_admin_conditional"]:
+ condition:
+ - description: null
+ expression: "api.getAttribute(\n 'iam.googleapis.com/modifiedGrantsByRole',\
+ \ []\n).hasOnly([\n 'roles/compute.networkAdmin'\n])\n"
+ title: delegated_network_user_one
+ members:
+ - group:organization-admins@example.org
+ project: test-project
+ role: roles/resourcemanager.projectIamAdmin
+ module.project.google_project_iam_member.bindings["group-owner"]:
+ condition: []
+ member: group:organization-admins@example.org
+ project: test-project
+ role: roles/owner
+ module.project.google_project_iam_member.bucket-sinks-binding["debug"]:
+ condition:
+ - title: debug bucket writer
+ role: roles/logging.bucketWriter
+ module.project.google_project_iam_member.shared_vpc_host_robots["roles/cloudasset.owner:cloudservices"]:
+ condition: []
+ project: test-host
+ role: roles/cloudasset.owner
+ module.project.google_project_iam_member.shared_vpc_host_robots["roles/cloudasset.owner:container-engine"]:
+ condition: []
+ project: test-host
+ role: roles/cloudasset.owner
+ module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:cloudservices"]:
+ condition: []
+ project: test-host
+ role: roles/compute.networkUser
+ module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:container"]:
+ condition: []
+ project: test-host
+ role: roles/compute.networkUser
+ module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.securityAdmin:container"]:
+ condition: []
+ project: test-host
+ role: roles/compute.securityAdmin
+ module.project.google_project_iam_member.shared_vpc_host_robots["roles/container.hostServiceAgentUser:container"]:
+ condition: []
+ project: test-host
+ role: roles/container.hostServiceAgentUser
+ module.project.google_project_iam_member.shared_vpc_host_robots["roles/vpcaccess.user:run"]:
+ condition: []
+ project: test-host
+ role: roles/vpcaccess.user
+ module.project.google_project_service.project_services["apigee.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-project
+ service: apigee.googleapis.com
+ module.project.google_project_service.project_services["bigquery.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-project
+ service: bigquery.googleapis.com
+ module.project.google_project_service.project_services["container.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-project
+ service: container.googleapis.com
+ module.project.google_project_service.project_services["logging.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-project
+ service: logging.googleapis.com
+ module.project.google_project_service.project_services["run.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-project
+ service: run.googleapis.com
+ module.project.google_project_service.project_services["storage.googleapis.com"]:
+ disable_dependent_services: false
+ disable_on_destroy: false
+ project: test-project
+ service: storage.googleapis.com
+ module.project.google_project_service_identity.jit_si["apigee.googleapis.com"]:
+ project: test-project
+ service: apigee.googleapis.com
+ module.project.google_pubsub_topic_iam_member.pubsub-sinks-binding["notice"]:
+ condition: []
+ project: project-id
+ role: roles/pubsub.publisher
+ topic: pubsub_sink
+ module.project.google_storage_bucket_iam_member.gcs-sinks-binding["warnings"]:
+ bucket: test-gcs_sink
+ condition: []
+ role: roles/storage.objectCreator
+ module.pubsub.google_pubsub_topic.default:
+ name: pubsub_sink
+ project: project-id
+
+counts:
+ google_bigquery_dataset: 1
+ google_bigquery_dataset_iam_member: 1
+ google_bigquery_default_service_account: 1
+ google_compute_shared_vpc_host_project: 1
+ google_compute_shared_vpc_service_project: 1
+ google_kms_crypto_key_iam_member: 2
+ google_logging_project_bucket_config: 1
+ google_logging_project_exclusion: 1
+ google_logging_project_sink: 4
+ google_org_policy_policy: 7
+ google_project: 3
+ google_project_iam_audit_config: 2
+ google_project_iam_binding: 7
+ google_project_iam_member: 9
+ google_project_service: 6
+ google_project_service_identity: 1
+ google_pubsub_topic: 1
+ google_pubsub_topic_iam_member: 1
+ google_storage_bucket: 1
+ google_storage_bucket_iam_member: 1
+ google_storage_project_service_account: 1
+ modules: 7
+ resources: 53
+
+outputs: {}
diff --git a/tests/modules/project/examples/iam-authoritative.yaml b/tests/modules/project/examples/iam-authoritative.yaml
index eeb77aa6e5..d889a88312 100644
--- a/tests/modules/project/examples/iam-authoritative.yaml
+++ b/tests/modules/project/examples/iam-authoritative.yaml
@@ -16,29 +16,29 @@ values:
module.project.google_project.project[0]:
auto_create_network: false
billing_account: 123456-123456-123456
- folder_id: '1234567890'
+ folder_id: '1122334455'
labels: null
- name: foo-project-example
+ name: test-project
org_id: null
- project_id: foo-project-example
+ project_id: test-project
skip_delete: false
timeouts: null
module.project.google_project_iam_binding.authoritative["roles/container.hostServiceAgentUser"]:
condition: []
members:
- serviceAccount:my_gke_service_account
- project: foo-project-example
+ project: test-project
role: roles/container.hostServiceAgentUser
module.project.google_project_service.project_services["container.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
- project: foo-project-example
+ project: test-project
service: container.googleapis.com
timeouts: null
module.project.google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
- project: foo-project-example
+ project: test-project
service: stackdriver.googleapis.com
timeouts: null
diff --git a/tests/modules/project/examples/iam-bindings-additive.yaml b/tests/modules/project/examples/iam-bindings-additive.yaml
index 390781f97c..2276622bb3 100644
--- a/tests/modules/project/examples/iam-bindings-additive.yaml
+++ b/tests/modules/project/examples/iam-bindings-additive.yaml
@@ -15,23 +15,23 @@
values:
module.project.google_project.project[0]:
auto_create_network: false
- billing_account: null
- folder_id: null
+ billing_account: 123456-123456-123456
+ folder_id: '1122334455'
labels: null
- name: project-1
+ name: test-project
org_id: null
- project_id: project-1
+ project_id: test-project
skip_delete: false
timeouts: null
module.project.google_project_iam_member.bindings["group-owner"]:
condition: []
- member: group:p1-owners@example.org
- project: project-1
+ member: group:organization-admins@example.org
+ project: test-project
role: roles/owner
module.project.google_project_service.project_services["compute.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
- project: project-1
+ project: test-project
service: compute.googleapis.com
timeouts: null
diff --git a/tests/modules/project/examples/iam-bindings.yaml b/tests/modules/project/examples/iam-bindings.yaml
index c9fee92524..eddc582083 100644
--- a/tests/modules/project/examples/iam-bindings.yaml
+++ b/tests/modules/project/examples/iam-bindings.yaml
@@ -16,11 +16,11 @@ values:
module.project.google_project.project[0]:
auto_create_network: false
billing_account: 123456-123456-123456
- folder_id: '1234567890'
+ folder_id: '1122334455'
labels: null
- name: foo-project-example
+ name: test-project
org_id: null
- project_id: foo-project-example
+ project_id: test-project
skip_delete: false
timeouts: null
module.project.google_project_iam_binding.bindings["iam_admin_conditional"]:
@@ -30,19 +30,19 @@ values:
\ []\n).hasOnly([\n 'roles/compute.networkAdmin'\n])\n"
title: delegated_network_user_one
members:
- - group:test-admins@example.org
- project: foo-project-example
+ - group:organization-admins@example.org
+ project: test-project
role: roles/resourcemanager.projectIamAdmin
module.project.google_project_service.project_services["container.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
- project: foo-project-example
+ project: test-project
service: container.googleapis.com
timeouts: null
module.project.google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
- project: foo-project-example
+ project: test-project
service: stackdriver.googleapis.com
timeouts: null
diff --git a/tests/modules/project/examples/iam-group.yaml b/tests/modules/project/examples/iam-group.yaml
index 0ca2ecdba9..73f14b80a6 100644
--- a/tests/modules/project/examples/iam-group.yaml
+++ b/tests/modules/project/examples/iam-group.yaml
@@ -17,26 +17,26 @@ values:
module.project.google_project_iam_binding.authoritative["roles/cloudasset.owner"]:
condition: []
members:
- - group:gcp-security-admins@example.com
- project: foo-project-example
+ - group:organization-admins@example.org
+ project: test-project
role: roles/cloudasset.owner
module.project.google_project_iam_binding.authoritative["roles/cloudsupport.techSupportEditor"]:
condition: []
members:
- - group:gcp-security-admins@example.com
- project: foo-project-example
+ - group:organization-admins@example.org
+ project: test-project
role: roles/cloudsupport.techSupportEditor
module.project.google_project_iam_binding.authoritative["roles/iam.securityReviewer"]:
condition: []
members:
- - group:gcp-security-admins@example.com
- project: foo-project-example
+ - group:organization-admins@example.org
+ project: test-project
role: roles/iam.securityReviewer
module.project.google_project_iam_binding.authoritative["roles/logging.admin"]:
condition: []
members:
- - group:gcp-security-admins@example.com
- project: foo-project-example
+ - group:organization-admins@example.org
+ project: test-project
role: roles/logging.admin
counts:
diff --git a/tests/modules/project/examples/logging-data-access.yaml b/tests/modules/project/examples/logging-data-access.yaml
index 3b35bbdc38..50d3886450 100644
--- a/tests/modules/project/examples/logging-data-access.yaml
+++ b/tests/modules/project/examples/logging-data-access.yaml
@@ -16,11 +16,11 @@ values:
module.project.google_project.project[0]:
auto_create_network: false
billing_account: 123456-123456-123456
- folder_id: '1234567890'
+ folder_id: '1122334455'
labels: null
- name: my-project
+ name: test-project
org_id: null
- project_id: my-project
+ project_id: test-project
skip_delete: false
timeouts: null
module.project.google_project_iam_audit_config.default["allServices"]:
@@ -28,7 +28,7 @@ values:
- exempted_members:
- group:organization-admins@example.org
log_type: ADMIN_READ
- project: my-project
+ project: test-project
service: allServices
module.project.google_project_iam_audit_config.default["storage.googleapis.com"]:
audit_log_config:
@@ -36,7 +36,7 @@ values:
log_type: DATA_READ
- exempted_members: []
log_type: DATA_WRITE
- project: my-project
+ project: test-project
service: storage.googleapis.com
counts:
diff --git a/tests/modules/project/examples/logging.yaml b/tests/modules/project/examples/logging.yaml
index 9634d8d102..7e96968afe 100644
--- a/tests/modules/project/examples/logging.yaml
+++ b/tests/modules/project/examples/logging.yaml
@@ -21,7 +21,7 @@ values:
disabled: null
filter: resource.type=gce_instance
name: no-gce-instances
- project: my-project
+ project: test-project
module.project-host.google_logging_project_sink.sink["debug"]:
description: debug (Terraform-managed).
disabled: false
@@ -32,7 +32,7 @@ values:
name: no-compute
filter: severity=DEBUG
name: debug
- project: my-project
+ project: test-project
unique_writer_identity: true
module.project-host.google_logging_project_sink.sink["info"]:
description: info (Terraform-managed).
@@ -40,7 +40,7 @@ values:
exclusions: []
filter: severity=INFO
name: info
- project: my-project
+ project: test-project
unique_writer_identity: true
module.project-host.google_logging_project_sink.sink["notice"]:
description: notice (Terraform-managed).
@@ -48,25 +48,25 @@ values:
exclusions: []
filter: severity=NOTICE
name: notice
- project: my-project
+ project: test-project
unique_writer_identity: true
module.project-host.google_logging_project_sink.sink["warnings"]:
description: warnings (Terraform-managed).
- destination: storage.googleapis.com/gcs_sink
+ destination: storage.googleapis.com/test-gcs_sink
disabled: false
exclusions: []
filter: severity=WARNING
name: warnings
- project: my-project
+ project: test-project
unique_writer_identity: true
module.project-host.google_project.project[0]:
auto_create_network: false
billing_account: 123456-123456-123456
- folder_id: '1234567890'
+ folder_id: '1122334455'
labels: null
- name: my-project
+ name: test-project
org_id: null
- project_id: my-project
+ project_id: test-project
skip_delete: false
module.project-host.google_project_iam_member.bucket-sinks-binding["debug"]:
condition:
@@ -76,7 +76,7 @@ values:
condition: []
role: roles/pubsub.publisher
module.project-host.google_storage_bucket_iam_member.gcs-sinks-binding["warnings"]:
- bucket: gcs_sink
+ bucket: test-gcs_sink
condition: []
role: roles/storage.objectCreator
diff --git a/tests/modules/project/examples/org-policies.yaml b/tests/modules/project/examples/org-policies.yaml
index d4dddc75bf..6539c32c41 100644
--- a/tests/modules/project/examples/org-policies.yaml
+++ b/tests/modules/project/examples/org-policies.yaml
@@ -14,8 +14,8 @@
values:
module.project.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]:
- name: projects/foo-project-example/policies/compute.disableGuestAttributesAccess
- parent: projects/foo-project-example
+ name: projects/test-project/policies/compute.disableGuestAttributesAccess
+ parent: projects/test-project
spec:
- inherit_from_parent: null
reset: null
@@ -26,8 +26,8 @@ values:
enforce: 'TRUE'
values: []
module.project.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]:
- name: projects/foo-project-example/policies/compute.skipDefaultNetworkCreation
- parent: projects/foo-project-example
+ name: projects/test-project/policies/compute.skipDefaultNetworkCreation
+ parent: projects/test-project
spec:
- inherit_from_parent: null
reset: null
@@ -38,8 +38,8 @@ values:
enforce: 'TRUE'
values: []
module.project.google_org_policy_policy.default["compute.trustedImageProjects"]:
- name: projects/foo-project-example/policies/compute.trustedImageProjects
- parent: projects/foo-project-example
+ name: projects/test-project/policies/compute.trustedImageProjects
+ parent: projects/test-project
spec:
- inherit_from_parent: null
reset: null
@@ -53,8 +53,8 @@ values:
- projects/my-project
denied_values: null
module.project.google_org_policy_policy.default["compute.vmExternalIpAccess"]:
- name: projects/foo-project-example/policies/compute.vmExternalIpAccess
- parent: projects/foo-project-example
+ name: projects/test-project/policies/compute.vmExternalIpAccess
+ parent: projects/test-project
spec:
- inherit_from_parent: null
reset: null
@@ -65,8 +65,8 @@ values:
enforce: null
values: []
module.project.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]:
- name: projects/foo-project-example/policies/iam.allowedPolicyMemberDomains
- parent: projects/foo-project-example
+ name: projects/test-project/policies/iam.allowedPolicyMemberDomains
+ parent: projects/test-project
spec:
- inherit_from_parent: null
reset: null
@@ -81,8 +81,8 @@ values:
- C0yyyyyyy
denied_values: null
module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]:
- name: projects/foo-project-example/policies/iam.disableServiceAccountKeyCreation
- parent: projects/foo-project-example
+ name: projects/test-project/policies/iam.disableServiceAccountKeyCreation
+ parent: projects/test-project
spec:
- inherit_from_parent: null
reset: null
@@ -93,8 +93,8 @@ values:
enforce: 'TRUE'
values: []
module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]:
- name: projects/foo-project-example/policies/iam.disableServiceAccountKeyUpload
- parent: projects/foo-project-example
+ name: projects/test-project/policies/iam.disableServiceAccountKeyUpload
+ parent: projects/test-project
spec:
- inherit_from_parent: null
reset: null
@@ -115,10 +115,10 @@ values:
values: []
module.project.google_project.project[0]:
billing_account: 123456-123456-123456
- folder_id: '1234567890'
- name: foo-project-example
+ folder_id: '1122334455'
+ name: test-project
org_id: null
- project_id: foo-project-example
+ project_id: test-project
counts:
google_org_policy_policy: 7
diff --git a/tests/modules/project/examples/shared-vpc-auto-grants.yaml b/tests/modules/project/examples/shared-vpc-auto-grants.yaml
index 226612394b..4dacb377b9 100644
--- a/tests/modules/project/examples/shared-vpc-auto-grants.yaml
+++ b/tests/modules/project/examples/shared-vpc-auto-grants.yaml
@@ -14,25 +14,25 @@
values:
module.host-project.google_compute_shared_vpc_host_project.shared_vpc_host[0]:
- project: my-host-project
+ project: test-host
module.host-project.google_project.project[0]:
- project_id: my-host-project
+ project_id: test-host
module.service-project.google_compute_shared_vpc_service_project.shared_vpc_service[0]:
- host_project: my-host-project
- service_project: my-service-project
+ host_project: test-host
+ service_project: test-service
module.service-project.google_project.project[0]:
- project_id: my-service-project
+ project_id: test-service
module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:cloudservices"]:
condition: []
- project: my-host-project
+ project: test-host
role: roles/compute.networkUser
module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:container"]:
condition: []
- project: my-host-project
+ project: test-host
role: roles/compute.networkUser
module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/container.hostServiceAgentUser:container"]:
condition: []
- project: my-host-project
+ project: test-host
role: roles/container.hostServiceAgentUser
counts:
diff --git a/tests/modules/project/examples/shared-vpc.yaml b/tests/modules/project/examples/shared-vpc.yaml
index 169c897de2..4277d56b3d 100644
--- a/tests/modules/project/examples/shared-vpc.yaml
+++ b/tests/modules/project/examples/shared-vpc.yaml
@@ -14,29 +14,29 @@
values:
module.host-project.google_compute_shared_vpc_host_project.shared_vpc_host[0]:
- project: my-host-project
+ project: test-host
module.host-project.google_project.project[0]:
- project_id: my-host-project
+ project_id: test-host
module.service-project.google_compute_shared_vpc_service_project.shared_vpc_service[0]:
- host_project: my-host-project
- service_project: my-service-project
+ host_project: test-host
+ service_project: test-service
module.service-project.google_project.project[0]:
- project_id: my-service-project
+ project_id: test-service
module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:cloudservices"]:
condition: []
- project: my-host-project
+ project: test-host
role: roles/compute.networkUser
module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:container-engine"]:
condition: []
- project: my-host-project
+ project: test-host
role: roles/compute.networkUser
module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/container.hostServiceAgentUser:container-engine"]:
condition: []
- project: my-host-project
+ project: test-host
role: roles/container.hostServiceAgentUser
module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/vpcaccess.user:cloudrun"]:
condition: []
- project: my-host-project
+ project: test-host
role: roles/vpcaccess.user
counts: