Support additional attributes for buckets/datasets in project factory module (#3755)
* extend attributes for project factory secondary resources * remove extra files * complete * tf fmt * tfdoc * schemas * fix tests * tfdoc
This commit is contained in:
committed by
GitHub
parent
db8eecc999
commit
67b1543e90
10
.agents/rules/dev-workflow.md
Normal file
10
.agents/rules/dev-workflow.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
# Always make sure edited code passes linting checks
|
||||
|
||||
- run `tools/tfdoc.py` if variable or output definitions changed
|
||||
- run `terraform fmt` on any edited Terraform file, and hcl examples in README files
|
||||
- a schema change should be reflected in all the other places that use the same schema, those are documented in `tools/duplicate-diff.py`
|
||||
- always make sure both example and module (or stage) level tests run for all the modules/stages where code was edited
|
||||
18
.agents/rules/fast-factory-driven.md
Normal file
18
.agents/rules/fast-factory-driven.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
# Use factory datasets for resource configuration
|
||||
|
||||
**FAST stages should generally not implement factories, but leverage those defined in modules and their associated schemas.**
|
||||
|
||||
Stages in the FAST folder are split between Terraform code and datasets.
|
||||
|
||||
Code is used to implement and wire together "factories" that implement resource management, while the actual description of resources and their relationships is implemented via YAML configurations read by those factories.
|
||||
|
||||
- YAML configurations are grouped in "datasets" which implement a complete design for the stage
|
||||
- each factory has a reference JSON schema used to describe and validate the YAML data
|
||||
- factories are generally implemented in the underlying modules, not in FAST stages
|
||||
- modules deal with one specific resource set (eg an instance and its disks, a project and its org policies, IAM, etc.) and generally implement a single factory
|
||||
- the project and VPC factory modules are the exception, as they are designed as "macro modules" to support interrelated creation of resources pertaining to a larger scope
|
||||
- modules that do not manage "sets" of resources (e.g. one project, one folder, one dataset, etc.) typically do not have an associated factory, or only do for sub-resources (e.g. rules in a single policy), those factories are either implemented in the "macro modules" or directly in FAST
|
||||
9
.agents/rules/modules-as-resource-managers.md
Normal file
9
.agents/rules/modules-as-resource-managers.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
Modules are designed to be containers for all aspects related to uage of a resource type. The pattern is a module is focused on a specific resource (e.g. folder, project, vpc, etc.) and implements all the functionality needed to create/manage that resources so that it is ready for user consumption. This includes: IAM, sub resources (eg subnets and routes for a network), org policies where applicable, etc.
|
||||
|
||||
Unrelated resources like a dataset for a project should never be part of the same module, except in the two "aggregation modules" (project and vpc factory) where that makes sense to allow consumers to create baseline infrastructure ready to receive application-level resources.
|
||||
|
||||
Never, ever break this boundary as a first approach, and always, always check in with the user if this looks like the only plan of action, as the criteria and constraints that led to the plan might need to be revised instead.
|
||||
@@ -244,6 +244,39 @@
|
||||
},
|
||||
"encryption_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"iam": {
|
||||
"$ref": "#/$defs/iam"
|
||||
},
|
||||
"iam_bindings": {
|
||||
"$ref": "#/$defs/iam_bindings"
|
||||
},
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"iam_by_principals": {
|
||||
"$ref": "#/$defs/iam_by_principals"
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"default_table_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"default_partition_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"delete_contents_on_destroy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_time_travel_hours": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,6 +381,9 @@
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
},
|
||||
"keys": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -651,6 +687,9 @@
|
||||
},
|
||||
"iam_sa_roles": {
|
||||
"$ref": "#/$defs/iam_sa_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,15 +795,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
@@ -813,6 +843,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"universe": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -1192,6 +1231,9 @@
|
||||
},
|
||||
"enable_object_retention": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1804,6 +1846,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,6 +244,39 @@
|
||||
},
|
||||
"encryption_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"iam": {
|
||||
"$ref": "#/$defs/iam"
|
||||
},
|
||||
"iam_bindings": {
|
||||
"$ref": "#/$defs/iam_bindings"
|
||||
},
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"iam_by_principals": {
|
||||
"$ref": "#/$defs/iam_by_principals"
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"default_table_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"default_partition_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"delete_contents_on_destroy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_time_travel_hours": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,6 +381,9 @@
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
},
|
||||
"keys": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -651,6 +687,9 @@
|
||||
},
|
||||
"iam_sa_roles": {
|
||||
"$ref": "#/$defs/iam_sa_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,15 +795,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
@@ -813,6 +843,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"universe": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -1192,6 +1231,9 @@
|
||||
},
|
||||
"enable_object_retention": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1804,6 +1846,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,6 +244,39 @@
|
||||
},
|
||||
"encryption_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"iam": {
|
||||
"$ref": "#/$defs/iam"
|
||||
},
|
||||
"iam_bindings": {
|
||||
"$ref": "#/$defs/iam_bindings"
|
||||
},
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"iam_by_principals": {
|
||||
"$ref": "#/$defs/iam_by_principals"
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"default_table_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"default_partition_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"delete_contents_on_destroy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_time_travel_hours": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,6 +381,9 @@
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
},
|
||||
"keys": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -651,6 +687,9 @@
|
||||
},
|
||||
"iam_sa_roles": {
|
||||
"$ref": "#/$defs/iam_sa_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,15 +795,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
@@ -813,6 +843,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"universe": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -1192,6 +1231,9 @@
|
||||
},
|
||||
"enable_object_retention": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1804,6 +1846,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,6 +244,39 @@
|
||||
},
|
||||
"encryption_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"iam": {
|
||||
"$ref": "#/$defs/iam"
|
||||
},
|
||||
"iam_bindings": {
|
||||
"$ref": "#/$defs/iam_bindings"
|
||||
},
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"iam_by_principals": {
|
||||
"$ref": "#/$defs/iam_by_principals"
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"default_table_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"default_partition_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"delete_contents_on_destroy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_time_travel_hours": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,6 +381,9 @@
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
},
|
||||
"keys": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -651,6 +687,9 @@
|
||||
},
|
||||
"iam_sa_roles": {
|
||||
"$ref": "#/$defs/iam_sa_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,15 +795,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
@@ -813,6 +843,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"universe": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -1192,6 +1231,9 @@
|
||||
},
|
||||
"enable_object_retention": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1804,6 +1846,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,8 +55,14 @@ module "bigquery-dataset" {
|
||||
iam = {
|
||||
"roles/bigquery.dataOwner" = ["user:user1@example.org"]
|
||||
}
|
||||
iam_bindings = {
|
||||
reader_user = {
|
||||
role = "roles/bigquery.dataViewer"
|
||||
members = ["user:user2@example.org"]
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=2 inventory=iam.yaml
|
||||
# tftest modules=1 resources=3 inventory=iam.yaml
|
||||
```
|
||||
|
||||
## Authorized Views, Datasets, and Routines
|
||||
@@ -353,27 +359,30 @@ module "bigquery-dataset" {
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [id](variables.tf#L112) | Dataset id. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L176) | Id of the project where datasets will be created. | <code>string</code> | ✓ | |
|
||||
| [id](variables.tf#L111) | Dataset id. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L175) | Id of the project where datasets will be created. | <code>string</code> | ✓ | |
|
||||
| [access](variables.tf#L17) | Map of access rules with role and identity type. Keys are arbitrary and must match those in the `access_identities` variable, types are `domain`, `group`, `special_group`, `user`, `view`. | <code title="map(object({ role = string type = string }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [access_identities](variables.tf#L33) | Map of access identities used for basic access roles. View identities have the format 'project_id\|dataset_id\|table_id'. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [authorized_datasets](variables.tf#L39) | An array of datasets to be authorized on the dataset. | <code title="list(object({ dataset_id = string, project_id = string, }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [authorized_routines](variables.tf#L48) | An array of routines to be authorized on the dataset. | <code title="list(object({ project_id = string, dataset_id = string, routine_id = string }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [authorized_views](variables.tf#L58) | An array of views to be authorized on the dataset. | <code title="list(object({ dataset_id = string, project_id = string, table_id = string # this is the view id, but we keep table_id to stay consistent as the resource }))">list(object({…}))</code> | | <code>[]</code> |
|
||||
| [context](variables.tf#L68) | Context-specific interpolations. | <code title="object({ custom_roles = optional(map(string), {}) kms_keys = optional(map(string), {}) iam_principals = optional(map(string), {}) locations = optional(map(string), {}) project_ids = optional(map(string), {}) tag_values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [dataset_access](variables.tf#L82) | Set access in the dataset resource instead of using separate resources. | <code>bool</code> | | <code>false</code> |
|
||||
| [description](variables.tf#L88) | Optional description. | <code>string</code> | | <code>"Terraform managed."</code> |
|
||||
| [encryption_key](variables.tf#L94) | Self link of the KMS key that will be used to protect destination table. | <code>string</code> | | <code>null</code> |
|
||||
| [friendly_name](variables.tf#L100) | Dataset friendly name. | <code>string</code> | | <code>null</code> |
|
||||
| [iam](variables.tf#L106) | IAM bindings in {ROLE => [MEMBERS]} format. Mutually exclusive with the access_* variables used for basic roles. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L117) | Dataset labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [location](variables.tf#L123) | Dataset location. | <code>string</code> | | <code>"EU"</code> |
|
||||
| [materialized_views](variables.tf#L129) | Materialized views definitions. | <code title="map(object({ query = string allow_non_incremental_definition = optional(bool) deletion_protection = optional(bool) description = optional(string, "Terraform managed.") enable_refresh = optional(bool) friendly_name = optional(string) labels = optional(map(string), {}) refresh_interval_ms = optional(bool) require_partition_filter = optional(bool) options = optional(object({ clustering = optional(list(string)) expiration_time = optional(number) }), {}) partitioning = optional(object({ field = optional(string) range = optional(object({ end = number interval = number start = number })) time = optional(object({ type = string expiration_ms = optional(number) field = optional(string) })) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [options](variables.tf#L162) | Dataset options. | <code title="object({ default_collation = optional(string) default_table_expiration_ms = optional(number) default_partition_expiration_ms = optional(number) delete_contents_on_destroy = optional(bool, false) is_case_insensitive = optional(bool) max_time_travel_hours = optional(number, 168) storage_billing_model = optional(string) })">object({…})</code> | | <code>{}</code> |
|
||||
| [routines](variables.tf#L181) | Routine definitions. | <code title="map(object({ description = optional(string) routine_type = string language = optional(string) definition_body = string imported_libraries = optional(list(string)) determinism_level = optional(string) data_governance_type = optional(string) return_type = optional(string) return_table_type = optional(string) arguments = optional(map(object({ argument_kind = optional(string) mode = optional(string) data_type = optional(string) })), {}) spark_options = optional(object({ archive_uris = optional(list(string), []) connection = string container_image = optional(string) file_uris = optional(list(string), []) jar_uris = optional(list(string), []) main_file_uri = optional(string) main_class = optional(string) properties = optional(map(string), {}) py_file_uris = optional(list(string), []) runtime_version = optional(string) })) remote_function_options = optional(object({ connection = string endpoint = optional(string) max_batching_rows = optional(string) user_defined_context = optional(map(string), {}) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tables](variables.tf#L220) | Table definitions. Options and partitioning default to null. Partitioning can only use `range` or `time`, set the unused one to null. | <code title="map(object({ deletion_protection = optional(bool) description = optional(string, "Terraform managed.") friendly_name = optional(string) labels = optional(map(string), {}) require_partition_filter = optional(bool) schema = optional(string) external_data_configuration = optional(object({ autodetect = bool source_uris = list(string) avro_logical_types = optional(bool) compression = optional(string) connection_id = optional(string) file_set_spec_type = optional(string) ignore_unknown_values = optional(bool) metadata_cache_mode = optional(string) object_metadata = optional(string) json_options_encoding = optional(string) reference_file_schema_uri = optional(string) schema = optional(string) source_format = optional(string) max_bad_records = optional(number) csv_options = optional(object({ quote = string allow_jagged_rows = optional(bool) allow_quoted_newlines = optional(bool) encoding = optional(string) field_delimiter = optional(string) skip_leading_rows = optional(number) })) google_sheets_options = optional(object({ range = optional(string) skip_leading_rows = optional(number) })) hive_partitioning_options = optional(object({ mode = optional(string) require_partition_filter = optional(bool) source_uri_prefix = optional(string) })) parquet_options = optional(object({ enum_as_string = optional(bool) enable_list_inference = optional(bool) })) })) options = optional(object({ clustering = optional(list(string)) encryption_key = optional(string) expiration_time = optional(number) max_staleness = optional(string) }), {}) partitioning = optional(object({ field = optional(string) range = optional(object({ end = number interval = number start = number })) time = optional(object({ type = string expiration_ms = optional(number) field = optional(string) })) })) table_constraints = optional(object({ primary_key_columns = optional(list(string)) foreign_keys = optional(object({ referenced_table = object({ project_id = string dataset_id = string table_id = string }) column_references = object({ referencing_column = string referenced_column = string }) name = optional(string) })) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L305) | Tag bindings for this dataset, in key => tag value id format. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [views](variables.tf#L312) | View definitions. | <code title="map(object({ query = string deletion_protection = optional(bool) description = optional(string, "Terraform managed.") friendly_name = optional(string) labels = optional(map(string), {}) use_legacy_sql = optional(bool) schema = optional(list(object({ name = string type = string description = string mode = optional(string) }))) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [context](variables.tf#L68) | Context-specific interpolations. | <code title="object({ condition_vars = optional(map(map(string)), {}) custom_roles = optional(map(string), {}) kms_keys = optional(map(string), {}) iam_principals = optional(map(string), {}) locations = optional(map(string), {}) project_ids = optional(map(string), {}) tag_values = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [dataset_access](variables.tf#L83) | Set access in the dataset resource instead of using separate resources. | <code>bool</code> | | <code>false</code> |
|
||||
| [description](variables.tf#L89) | Optional description. | <code>string</code> | | <code>"Terraform managed."</code> |
|
||||
| [encryption_key](variables.tf#L95) | Self link of the KMS key that will be used to protect destination table. | <code>string</code> | | <code>null</code> |
|
||||
| [friendly_name](variables.tf#L101) | Dataset friendly name. | <code>string</code> | | <code>null</code> |
|
||||
| [iam](variables-iam.tf#L17) | IAM bindings in {ROLE => [MEMBERS]} format. Mutually exclusive with the access_* variables used for basic roles. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam_bindings](variables-iam.tf#L23) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | <code title="map(object({ members = list(string) role = string condition = optional(object({ expression = string title = string description = optional(string) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [iam_bindings_additive](variables-iam.tf#L38) | Individual additive IAM bindings. Keys are arbitrary. | <code title="map(object({ member = string role = string condition = optional(object({ expression = string title = string description = optional(string) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [iam_by_principals](variables-iam.tf#L53) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid errors. Merged internally with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L116) | Dataset labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [location](variables.tf#L122) | Dataset location. | <code>string</code> | | <code>"EU"</code> |
|
||||
| [materialized_views](variables.tf#L128) | Materialized views definitions. | <code title="map(object({ query = string allow_non_incremental_definition = optional(bool) deletion_protection = optional(bool) description = optional(string, "Terraform managed.") enable_refresh = optional(bool) friendly_name = optional(string) labels = optional(map(string), {}) refresh_interval_ms = optional(bool) require_partition_filter = optional(bool) options = optional(object({ clustering = optional(list(string)) expiration_time = optional(number) }), {}) partitioning = optional(object({ field = optional(string) range = optional(object({ end = number interval = number start = number })) time = optional(object({ type = string expiration_ms = optional(number) field = optional(string) })) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [options](variables.tf#L161) | Dataset options. | <code title="object({ default_collation = optional(string) default_table_expiration_ms = optional(number) default_partition_expiration_ms = optional(number) delete_contents_on_destroy = optional(bool, false) is_case_insensitive = optional(bool) max_time_travel_hours = optional(number, 168) storage_billing_model = optional(string) })">object({…})</code> | | <code>{}</code> |
|
||||
| [routines](variables.tf#L180) | Routine definitions. | <code title="map(object({ description = optional(string) routine_type = string language = optional(string) definition_body = string imported_libraries = optional(list(string)) determinism_level = optional(string) data_governance_type = optional(string) return_type = optional(string) return_table_type = optional(string) arguments = optional(map(object({ argument_kind = optional(string) mode = optional(string) data_type = optional(string) })), {}) spark_options = optional(object({ archive_uris = optional(list(string), []) connection = string container_image = optional(string) file_uris = optional(list(string), []) jar_uris = optional(list(string), []) main_file_uri = optional(string) main_class = optional(string) properties = optional(map(string), {}) py_file_uris = optional(list(string), []) runtime_version = optional(string) })) remote_function_options = optional(object({ connection = string endpoint = optional(string) max_batching_rows = optional(string) user_defined_context = optional(map(string), {}) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tables](variables.tf#L219) | Table definitions. Options and partitioning default to null. Partitioning can only use `range` or `time`, set the unused one to null. | <code title="map(object({ deletion_protection = optional(bool) description = optional(string, "Terraform managed.") friendly_name = optional(string) labels = optional(map(string), {}) require_partition_filter = optional(bool) schema = optional(string) external_data_configuration = optional(object({ autodetect = bool source_uris = list(string) avro_logical_types = optional(bool) compression = optional(string) connection_id = optional(string) file_set_spec_type = optional(string) ignore_unknown_values = optional(bool) metadata_cache_mode = optional(string) object_metadata = optional(string) json_options_encoding = optional(string) reference_file_schema_uri = optional(string) schema = optional(string) source_format = optional(string) max_bad_records = optional(number) csv_options = optional(object({ quote = string allow_jagged_rows = optional(bool) allow_quoted_newlines = optional(bool) encoding = optional(string) field_delimiter = optional(string) skip_leading_rows = optional(number) })) google_sheets_options = optional(object({ range = optional(string) skip_leading_rows = optional(number) })) hive_partitioning_options = optional(object({ mode = optional(string) require_partition_filter = optional(bool) source_uri_prefix = optional(string) })) parquet_options = optional(object({ enum_as_string = optional(bool) enable_list_inference = optional(bool) })) })) options = optional(object({ clustering = optional(list(string)) encryption_key = optional(string) expiration_time = optional(number) max_staleness = optional(string) }), {}) partitioning = optional(object({ field = optional(string) range = optional(object({ end = number interval = number start = number })) time = optional(object({ type = string expiration_ms = optional(number) field = optional(string) })) })) table_constraints = optional(object({ primary_key_columns = optional(list(string)) foreign_keys = optional(object({ referenced_table = object({ project_id = string dataset_id = string table_id = string }) column_references = object({ referencing_column = string referenced_column = string }) name = optional(string) })) })) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [tag_bindings](variables.tf#L304) | Tag bindings for this dataset, in key => tag value id format. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [views](variables.tf#L311) | View definitions. | <code title="map(object({ query = string deletion_protection = optional(bool) description = optional(string, "Terraform managed.") friendly_name = optional(string) labels = optional(map(string), {}) use_legacy_sql = optional(bool) schema = optional(list(object({ name = string type = string description = string mode = optional(string) }))) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
||||
82
modules/bigquery-dataset/iam.tf
Normal file
82
modules/bigquery-dataset/iam.tf
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
# tfdoc:file:description IAM bindings.
|
||||
|
||||
locals {
|
||||
_iam_principal_roles = distinct(flatten(values(var.iam_by_principals)))
|
||||
_iam_principals = {
|
||||
for r in local._iam_principal_roles : r => [
|
||||
for k, v in var.iam_by_principals :
|
||||
k if try(index(v, r), null) != null
|
||||
]
|
||||
}
|
||||
iam = {
|
||||
for role in distinct(concat(keys(var.iam), keys(local._iam_principals))) :
|
||||
role => concat(
|
||||
try(var.iam[role], []),
|
||||
try(local._iam_principals[role], [])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_bigquery_dataset_iam_binding" "authoritative" {
|
||||
for_each = local.iam
|
||||
project = local.project_id
|
||||
dataset_id = google_bigquery_dataset.default.dataset_id
|
||||
role = lookup(local.ctx.custom_roles, each.key, each.key)
|
||||
members = [
|
||||
for v in each.value : lookup(local.ctx.iam_principals, v, v)
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_bigquery_dataset_iam_binding" "bindings" {
|
||||
for_each = var.iam_bindings
|
||||
project = local.project_id
|
||||
dataset_id = google_bigquery_dataset.default.dataset_id
|
||||
role = lookup(local.ctx.custom_roles, each.value.role, each.value.role)
|
||||
members = [
|
||||
for v in each.value.members : lookup(local.ctx.iam_principals, v, v)
|
||||
]
|
||||
dynamic "condition" {
|
||||
for_each = each.value.condition == null ? [] : [""]
|
||||
content {
|
||||
expression = templatestring(
|
||||
each.value.condition.expression, var.context.condition_vars
|
||||
)
|
||||
title = each.value.condition.title
|
||||
description = each.value.condition.description
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_bigquery_dataset_iam_member" "bindings" {
|
||||
for_each = var.iam_bindings_additive
|
||||
project = local.project_id
|
||||
dataset_id = google_bigquery_dataset.default.dataset_id
|
||||
role = lookup(local.ctx.custom_roles, each.value.role, each.value.role)
|
||||
member = lookup(local.ctx.iam_principals, each.value.member, each.value.member)
|
||||
dynamic "condition" {
|
||||
for_each = each.value.condition == null ? [] : [""]
|
||||
content {
|
||||
expression = templatestring(
|
||||
each.value.condition.expression, var.context.condition_vars
|
||||
)
|
||||
title = each.value.condition.title
|
||||
description = each.value.condition.description
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,15 +231,6 @@ resource "google_bigquery_dataset_access" "authorized_routines" {
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_bigquery_dataset_iam_binding" "bindings" {
|
||||
for_each = var.iam
|
||||
project = local.project_id
|
||||
dataset_id = google_bigquery_dataset.default.dataset_id
|
||||
role = lookup(local.ctx.custom_roles, each.key, each.key)
|
||||
members = [
|
||||
for v in each.value : lookup(local.ctx.iam_principals, v, v)
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_bigquery_table" "default" {
|
||||
provider = google-beta
|
||||
|
||||
58
modules/bigquery-dataset/variables-iam.tf
Normal file
58
modules/bigquery-dataset/variables-iam.tf
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "iam" {
|
||||
description = "IAM bindings in {ROLE => [MEMBERS]} format. Mutually exclusive with the access_* variables used for basic roles."
|
||||
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 "iam_by_principals" {
|
||||
description = "Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid errors. Merged internally with the `iam` variable."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
@@ -68,6 +68,7 @@ variable "authorized_views" {
|
||||
variable "context" {
|
||||
description = "Context-specific interpolations."
|
||||
type = object({
|
||||
condition_vars = optional(map(map(string)), {})
|
||||
custom_roles = optional(map(string), {})
|
||||
kms_keys = optional(map(string), {})
|
||||
iam_principals = optional(map(string), {})
|
||||
@@ -103,11 +104,9 @@ variable "friendly_name" {
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "iam" {
|
||||
description = "IAM bindings in {ROLE => [MEMBERS]} format. Mutually exclusive with the access_* variables used for basic roles."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
variable "id" {
|
||||
description = "Dataset id."
|
||||
|
||||
@@ -442,7 +442,8 @@ module "project-factory" {
|
||||
data_defaults = {
|
||||
billing_account = var.billing_account_id
|
||||
locations = {
|
||||
storage = "EU"
|
||||
bigquery = "EU"
|
||||
storage = "EU"
|
||||
}
|
||||
}
|
||||
# make sure the environment label and stackdriver service are always added
|
||||
@@ -557,7 +558,6 @@ asset_feeds:
|
||||
name: App 0
|
||||
factories_config:
|
||||
org_policies: data/factories/org-policies
|
||||
|
||||
pam_entitlements:
|
||||
app-0-admins:
|
||||
max_request_duration: 3600s
|
||||
@@ -639,6 +639,8 @@ service_accounts:
|
||||
iam_self_roles:
|
||||
- roles/logging.logWriter
|
||||
- roles/monitoring.metricWriter
|
||||
tag_bindings:
|
||||
context: $tag_values:context/project-factory
|
||||
# this is just for illustrative/test purposes
|
||||
iam:
|
||||
roles/iam.serviceAccountUser:
|
||||
@@ -672,6 +674,8 @@ billing_budgets:
|
||||
buckets:
|
||||
app-0-bucket-a:
|
||||
location: europe-west8
|
||||
tag_bindings:
|
||||
context: $tag_values:context/gke
|
||||
app-0-bucket-b:
|
||||
location: europe-west8
|
||||
logging_config:
|
||||
@@ -695,6 +699,12 @@ services:
|
||||
- container.googleapis.com
|
||||
- pubsub.googleapis.com
|
||||
- storage.googleapis.com
|
||||
datasets:
|
||||
test_0:
|
||||
friendly_name: Test Dataset
|
||||
iam:
|
||||
roles/bigquery.dataViewer:
|
||||
- $iam_principals:gcp-devops
|
||||
pubsub_topics:
|
||||
app-0-topic-a:
|
||||
iam:
|
||||
@@ -703,6 +713,14 @@ pubsub_topics:
|
||||
app-0-topic-b:
|
||||
subscriptions:
|
||||
app-0-topic-b-sub: {}
|
||||
kms:
|
||||
keyrings:
|
||||
my-keyring:
|
||||
location: europe-west1
|
||||
keys:
|
||||
my-key: {}
|
||||
tag_bindings:
|
||||
context: $tag_values:context/project-factory
|
||||
tags:
|
||||
my-tag-key-1:
|
||||
values:
|
||||
|
||||
@@ -18,12 +18,26 @@ locals {
|
||||
projects_bigquery_datasets = flatten([
|
||||
for k, v in local.projects_input : [
|
||||
for name, opts in lookup(v, "datasets", {}) : {
|
||||
project_key = k
|
||||
project_name = v.name
|
||||
id = name
|
||||
encryption_key = lookup(opts, "encryption_key", null)
|
||||
friendly_name = lookup(opts, "friendly_name", null)
|
||||
location = lookup(opts, "location", null)
|
||||
project_key = k
|
||||
project_name = v.name
|
||||
id = name
|
||||
encryption_key = lookup(opts, "encryption_key", null)
|
||||
friendly_name = lookup(opts, "friendly_name", null)
|
||||
location = lookup(opts, "location", null)
|
||||
iam = lookup(opts, "iam", {})
|
||||
iam_bindings = lookup(opts, "iam_bindings", {})
|
||||
iam_bindings_additive = lookup(opts, "iam_bindings_additive", {})
|
||||
iam_by_principals = lookup(opts, "iam_by_principals", {})
|
||||
tag_bindings = lookup(opts, "tag_bindings", {})
|
||||
options = {
|
||||
default_collation = try(opts.options.default_collation, null)
|
||||
default_table_expiration_ms = try(opts.options.default_table_expiration_ms, null)
|
||||
default_partition_expiration_ms = try(opts.options.default_partition_expiration_ms, null)
|
||||
delete_contents_on_destroy = try(opts.options.delete_contents_on_destroy, null)
|
||||
is_case_insensitive = try(opts.options.is_case_insensitive, null)
|
||||
max_time_travel_hours = try(opts.options.max_time_travel_hours, null)
|
||||
storage_billing_model = try(opts.options.storage_billing_model, null)
|
||||
}
|
||||
}
|
||||
]
|
||||
])
|
||||
@@ -46,6 +60,8 @@ module "bigquery-datasets" {
|
||||
kms_keys = merge(local.ctx.kms_keys, local.kms_keys, local.kms_autokeys)
|
||||
locations = local.ctx.locations
|
||||
project_ids = local.ctx_project_ids
|
||||
tag_keys = local.ctx_tag_keys
|
||||
tag_values = local.ctx_tag_values
|
||||
})
|
||||
encryption_key = each.value.encryption_key
|
||||
friendly_name = each.value.friendly_name
|
||||
@@ -54,4 +70,10 @@ module "bigquery-datasets" {
|
||||
lookup(each.value, "location", null),
|
||||
local.data_defaults.defaults.locations.bigquery
|
||||
)
|
||||
iam = each.value.iam
|
||||
iam_bindings = each.value.iam_bindings
|
||||
iam_bindings_additive = each.value.iam_bindings_additive
|
||||
iam_by_principals = each.value.iam_by_principals
|
||||
tag_bindings = each.value.tag_bindings
|
||||
options = each.value.options
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ locals {
|
||||
lifecycle_rules = lookup(opts, "lifecycle_rules", {})
|
||||
logging_config = lookup(opts, "logging_config", null)
|
||||
enable_object_retention = lookup(opts, "enable_object_retention", null)
|
||||
tag_bindings = lookup(opts, "tag_bindings", {})
|
||||
}
|
||||
]
|
||||
])
|
||||
@@ -81,6 +82,8 @@ module "buckets" {
|
||||
locations = local.ctx.locations
|
||||
project_ids = local.ctx_project_ids
|
||||
storage_buckets = local.ctx.storage_buckets
|
||||
tag_keys = local.ctx_tag_keys
|
||||
tag_values = local.ctx_tag_values
|
||||
})
|
||||
iam = each.value.iam
|
||||
iam_bindings = each.value.iam_bindings
|
||||
@@ -101,4 +104,5 @@ module "buckets" {
|
||||
soft_delete_retention = each.value.soft_delete_retention
|
||||
logging_config = each.value.logging_config
|
||||
enable_object_retention = each.value.enable_object_retention
|
||||
tag_bindings = each.value.tag_bindings
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ locals {
|
||||
iam = lookup(opts, "iam", {})
|
||||
iam_bindings = lookup(opts, "iam_bindings", {})
|
||||
iam_bindings_additive = lookup(opts, "iam_bindings_additive", {})
|
||||
tag_bindings = lookup(opts, "tag_bindings", {})
|
||||
keys = lookup(opts, "keys", {})
|
||||
} if try(opts.location, null) != null
|
||||
]
|
||||
@@ -64,6 +65,7 @@ module "kms" {
|
||||
iam = each.value.iam
|
||||
iam_bindings = each.value.iam_bindings
|
||||
iam_bindings_additive = each.value.iam_bindings_additive
|
||||
tag_bindings = each.value.tag_bindings
|
||||
keys = each.value.keys
|
||||
context = merge(local.ctx, {
|
||||
iam_principals = merge(
|
||||
@@ -75,5 +77,7 @@ module "kms" {
|
||||
)
|
||||
locations = local.ctx.locations
|
||||
project_ids = local.ctx_project_ids
|
||||
tag_keys = local.ctx_tag_keys
|
||||
tag_values = local.ctx_tag_values
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ locals {
|
||||
try(local.data_defaults.defaults.service_accounts.iam_self_roles, []),
|
||||
))
|
||||
iam_storage_roles = try(opts.iam_storage_roles, {})
|
||||
tag_bindings = try(opts.tag_bindings, {})
|
||||
opts = opts
|
||||
}
|
||||
]
|
||||
@@ -85,6 +86,7 @@ module "service-accounts" {
|
||||
display_name = each.value.display_name
|
||||
context = merge(local.ctx, {
|
||||
project_ids = local.ctx_project_ids
|
||||
tag_values = local.ctx_tag_values
|
||||
})
|
||||
iam_project_roles = merge(
|
||||
each.value.iam_project_roles,
|
||||
@@ -92,6 +94,7 @@ module "service-accounts" {
|
||||
"$project_ids:${each.value.project_key}" = each.value.iam_self_roles
|
||||
}
|
||||
)
|
||||
tag_bindings = each.value.tag_bindings
|
||||
}
|
||||
|
||||
module "service_accounts-iam" {
|
||||
|
||||
@@ -244,6 +244,39 @@
|
||||
},
|
||||
"encryption_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"iam": {
|
||||
"$ref": "#/$defs/iam"
|
||||
},
|
||||
"iam_bindings": {
|
||||
"$ref": "#/$defs/iam_bindings"
|
||||
},
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"iam_by_principals": {
|
||||
"$ref": "#/$defs/iam_by_principals"
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"default_table_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"default_partition_expiration_ms": {
|
||||
"type": "number"
|
||||
},
|
||||
"delete_contents_on_destroy": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"max_time_travel_hours": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,6 +381,9 @@
|
||||
"iam_bindings_additive": {
|
||||
"$ref": "#/$defs/iam_bindings_additive"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
},
|
||||
"keys": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -651,6 +687,9 @@
|
||||
},
|
||||
"iam_sa_roles": {
|
||||
"$ref": "#/$defs/iam_sa_roles"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,15 +795,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
@@ -813,6 +843,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"universe": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -1192,6 +1231,9 @@
|
||||
},
|
||||
"enable_object_retention": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tag_bindings": {
|
||||
"$ref": "#/$defs/tag_bindings"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1804,6 +1846,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tag_bindings": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-z0-9_-]+$": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,14 +34,14 @@ values:
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
google_bigquery_dataset_iam_binding.bindings["$custom_roles:myrole_one"]:
|
||||
google_bigquery_dataset_iam_binding.authoritative["$custom_roles:myrole_one"]:
|
||||
condition: []
|
||||
dataset_id: dataset_0
|
||||
members:
|
||||
- user:test-user@example.com
|
||||
project: foo-test-0
|
||||
role: organizations/366118655033/roles/myRoleOne
|
||||
google_bigquery_dataset_iam_binding.bindings["roles/viewer"]:
|
||||
google_bigquery_dataset_iam_binding.authoritative["roles/viewer"]:
|
||||
condition: []
|
||||
dataset_id: dataset_0
|
||||
members:
|
||||
|
||||
@@ -15,15 +15,39 @@
|
||||
values:
|
||||
module.bigquery-dataset.google_bigquery_dataset.default:
|
||||
dataset_id: my_dataset
|
||||
default_encryption_configuration: []
|
||||
default_partition_expiration_ms: null
|
||||
default_table_expiration_ms: null
|
||||
delete_contents_on_destroy: false
|
||||
description: Terraform managed.
|
||||
effective_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
external_catalog_dataset_options: []
|
||||
external_dataset_reference: []
|
||||
friendly_name: null
|
||||
labels: null
|
||||
location: EU
|
||||
max_time_travel_hours: '168'
|
||||
project: my-project
|
||||
module.bigquery-dataset.google_bigquery_dataset_iam_binding.bindings["roles/bigquery.dataOwner"]:
|
||||
resource_tags: null
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
module.bigquery-dataset.google_bigquery_dataset_iam_binding.authoritative["roles/bigquery.dataOwner"]:
|
||||
condition: []
|
||||
dataset_id: my_dataset
|
||||
members:
|
||||
- user:user1@example.org
|
||||
project: my-project
|
||||
role: roles/bigquery.dataOwner
|
||||
module.bigquery-dataset.google_bigquery_dataset_iam_binding.bindings["reader_user"]:
|
||||
condition: []
|
||||
dataset_id: my_dataset
|
||||
members:
|
||||
- user:user2@example.org
|
||||
project: my-project
|
||||
role: roles/bigquery.dataViewer
|
||||
|
||||
counts:
|
||||
google_bigquery_dataset: 1
|
||||
google_bigquery_dataset_iam_binding: 1
|
||||
google_bigquery_dataset_iam_binding: 2
|
||||
|
||||
@@ -81,6 +81,33 @@ values:
|
||||
member: serviceAccount:dev-tb-app0-0-rw@test-pf-teams-iac-0.iam.gserviceaccount.com
|
||||
project: test-pf-teams-iac-0
|
||||
timeouts: null
|
||||
module.project-factory.module.bigquery-datasets["dev-ta-app0-be/test_0"].google_bigquery_dataset.default:
|
||||
dataset_id: test_0
|
||||
default_encryption_configuration: []
|
||||
default_partition_expiration_ms: null
|
||||
default_table_expiration_ms: null
|
||||
delete_contents_on_destroy: false
|
||||
description: Terraform managed.
|
||||
effective_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
external_catalog_dataset_options: []
|
||||
external_dataset_reference: []
|
||||
friendly_name: Test Dataset
|
||||
labels: null
|
||||
location: EU
|
||||
max_time_travel_hours: '168'
|
||||
project: test-pf-dev-ta-app0-be
|
||||
resource_tags: null
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
? module.project-factory.module.bigquery-datasets["dev-ta-app0-be/test_0"].google_bigquery_dataset_iam_binding.authoritative["roles/bigquery.dataViewer"]
|
||||
: condition: []
|
||||
dataset_id: test_0
|
||||
members:
|
||||
- group:gcp-devops@example.org
|
||||
project: test-pf-dev-ta-app0-be
|
||||
role: roles/bigquery.dataViewer
|
||||
module.project-factory.module.billing-budgets[0].google_billing_budget.default["test-100"]:
|
||||
all_updates_rule:
|
||||
- disable_default_iam_recipients: true
|
||||
@@ -148,6 +175,11 @@ values:
|
||||
uniform_bucket_level_access: true
|
||||
versioning:
|
||||
- enabled: false
|
||||
module.project-factory.module.buckets["dev-ta-app0-be/app-0-bucket-a"].google_tags_location_tag_binding.binding["context"]:
|
||||
location: europe-west8
|
||||
parent: //storage.googleapis.com/projects/_/buckets/test-pf-dev-ta-app0-be-app-0-bucket-a
|
||||
tag_value: tagValues/654321
|
||||
timeouts: null
|
||||
module.project-factory.module.buckets["dev-ta-app0-be/app-0-bucket-b"].google_storage_bucket.bucket[0]:
|
||||
autoclass: []
|
||||
cors: []
|
||||
@@ -288,6 +320,26 @@ values:
|
||||
display_name: App X
|
||||
tags: null
|
||||
timeouts: null
|
||||
module.project-factory.module.kms["dev-ta-app0-be/my-keyring"].google_kms_crypto_key.default["my-key"]:
|
||||
effective_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
labels: null
|
||||
name: my-key
|
||||
purpose: ENCRYPT_DECRYPT
|
||||
rotation_period: null
|
||||
skip_initial_version_creation: false
|
||||
terraform_labels:
|
||||
goog-terraform-provisioned: 'true'
|
||||
timeouts: null
|
||||
module.project-factory.module.kms["dev-ta-app0-be/my-keyring"].google_kms_key_ring.default[0]:
|
||||
location: europe-west1
|
||||
name: my-keyring
|
||||
project: test-pf-dev-ta-app0-be
|
||||
timeouts: null
|
||||
module.project-factory.module.kms["dev-ta-app0-be/my-keyring"].google_tags_location_tag_binding.binding["context"]:
|
||||
location: europe-west1
|
||||
tag_value: $tag_values:context/project-factory
|
||||
timeouts: null
|
||||
? module.project-factory.module.projects-iam["dev-ta-app0-be"].google_compute_shared_vpc_service_project.shared_vpc_service[0]
|
||||
: deletion_policy: null
|
||||
host_project: $project_ids:dev-spoke-0
|
||||
@@ -819,6 +871,9 @@ values:
|
||||
member: serviceAccount:app-0-be@test-pf-dev-ta-app0-be.iam.gserviceaccount.com
|
||||
project: test-pf-dev-ta-app0-be
|
||||
timeouts: null
|
||||
module.project-factory.module.service-accounts["dev-ta-app0-be/app-0-be"].google_tags_tag_binding.binding["context"]:
|
||||
tag_value: $tag_values:context/project-factory
|
||||
timeouts: null
|
||||
? module.project-factory.module.service-accounts["dev-ta-app0-be/app-0-fe"].google_project_iam_member.project-roles["$project_ids:dev-spoke-0-roles/compute.networkUser"]
|
||||
: condition: []
|
||||
project: $project_ids:dev-spoke-0
|
||||
@@ -905,6 +960,8 @@ values:
|
||||
triggers_replace: null
|
||||
|
||||
counts:
|
||||
google_bigquery_dataset: 1
|
||||
google_bigquery_dataset_iam_binding: 1
|
||||
google_billing_budget: 1
|
||||
google_cloud_asset_folder_feed: 1
|
||||
google_compute_shared_vpc_host_project: 1
|
||||
@@ -915,7 +972,9 @@ counts:
|
||||
google_folder_iam_binding: 1
|
||||
google_iam_workload_identity_pool: 1
|
||||
google_iam_workload_identity_pool_provider: 1
|
||||
google_kms_crypto_key: 1
|
||||
google_kms_crypto_key_iam_member: 2
|
||||
google_kms_key_ring: 1
|
||||
google_monitoring_notification_channel: 1
|
||||
google_org_policy_policy: 3
|
||||
google_privileged_access_manager_entitlement: 2
|
||||
@@ -934,10 +993,11 @@ counts:
|
||||
google_storage_bucket: 3
|
||||
google_storage_bucket_iam_binding: 2
|
||||
google_storage_project_service_account: 4
|
||||
google_tags_tag_binding: 2
|
||||
google_tags_location_tag_binding: 2
|
||||
google_tags_tag_binding: 3
|
||||
google_tags_tag_key: 1
|
||||
google_tags_tag_value: 2
|
||||
google_tags_tag_value_iam_binding: 1
|
||||
modules: 32
|
||||
resources: 111
|
||||
modules: 34
|
||||
resources: 118
|
||||
terraform_data: 2
|
||||
|
||||
Reference in New Issue
Block a user