New `bigquery-dataset` module (#66)

* new bigquery-dataset module

* update README

* update top-level READMEs

* update CHANGELOG
This commit is contained in:
Ludovico Magnocavallo 2020-05-02 17:33:48 +02:00 committed by GitHub
parent a9d6bd1f1c
commit c7bffbbac1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 498 additions and 276 deletions

View File

@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
- **incompatible change** the `bigquery` module has been removed and replaced by the new `bigquery-dataset` module
## [1.4.1] - 2020-05-02
- new `secret-manager` module

View File

@ -35,7 +35,7 @@ Currently available modules:
- **foundational** - [folders](./modules/folders), [log sinks](./modules/logging-sinks), [organization](./modules/organization), [project](./modules/project), [service accounts](./modules/iam-service-accounts)
- **networking** - [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN static](./modules/net-vpn-static), [VPN dynamic](./modules/net-vpn-dynamic), [VPN HA](./modules/net-vpn-ha), [NAT](./modules/net-cloudnat), [address reservation](./modules/net-address), [DNS](./modules/dns), [L4 ILB](./modules/net-ilb)
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [GKE cluster](./modules/gke-cluster), [GKE nodepool](./modules/gke-nodepool), [COS container](./modules/cos-container) (coredns, mysql, onprem, squid)
- **data** - [GCS](./modules/gcs), [BigQuery dataset](./modules/bigquery)
- **data** - [GCS](./modules/gcs), [BigQuery dataset](./modules/bigquery-dataset)
- **security** - [KMS](./modules/kms), [SecretManager](./modules/secret-manager)
For more information and usage examples see each module's README file.

View File

@ -40,7 +40,7 @@ Specific modules also offer support for non-authoritative bindings (e.g. `google
## Data
- [BigQuery dataset](./bigquery)
- [BigQuery dataset](./bigquery-dataset)
- [GCS](./gcs)
## Security

View File

@ -0,0 +1,150 @@
# Google Cloud Bigquery Module
This module allows managing a single BigQuery dataset, including access configuration, tables and views.
## Examples
### Simple dataset with access configuration
Access configuration defaults to using incremental accesses, which add to the default ones set at dataset creation. You can use the `access_authoritative` variable to switch to authoritative mode and have full control over dataset-level access. Be sure to always have at least one `OWNER` access and to avoid duplicating accesses, or `terraform apply` will fail.
```hcl
module "bigquery-dataset" {
source = "./modules/bigquery-dataset"
project_id = "my-project
id = "my-dataset"
access = [
{
role = "OWNER"
identity_type = "group_by_email"
identity = "dataset-owners@example.com"
}
]
}
```
### Dataset options
Dataset options are set via the `options` variable. all options must be specified, but a `null` value can be set to options that need to use defaults.
```hcl
module "bigquery-dataset" {
source = "./modules/bigquery-dataset"
project_id = "my-project
id = "my-dataset"
options = {
default_table_expiration_ms = 3600000
default_partition_expiration_ms = null
delete_contents_on_destroy = false
}
}
```
### Tables and views
Tables are created via the `tables` variable, or the `view` variable for views. Support for external tables will be added in a future release.
```hcl
module "bigquery-dataset" {
source = "./modules/bigquery-dataset"
project_id = "my-project
id = "my-dataset"
tables = {
table_a = {
friendly_name = "Table a"
labels = {}
options = null
partitioning = null
schema = file("table-a.json")
}
}
}
```
If partitioning is needed, populate the `partitioning` variable using either the `time` or `range` attribute.
```hcl
module "bigquery-dataset" {
source = "./modules/bigquery-dataset"
project_id = "my-project
id = "my-dataset"
tables = {
table_a = {
friendly_name = "Table a"
labels = {}
options = null
partitioning = {
field = null
range = null # use start/end/interval for range
time = { type = "DAY", expiration_ms = null }
}
schema = file("table-a.json")
}
}
}
```
To create views use the `view` variable. If you're querying a table created by the same module `terraform apply` will initially fail and eventually succeed once the underlying table has been created. You can probably also use the module's output in the view's query to create a dependency on the table.
```hcl
module "bigquery-dataset" {
source = "./modules/bigquery-dataset"
project_id = "my-project
id = "my-dataset"
tables = {
table_a = {
friendly_name = "Table a"
labels = {}
options = null
partitioning = {
field = null
range = null # use start/end/interval for range
time = { type = "DAY", expiration_ms = null }
}
schema = file("table-a.json")
}
}
views = {
view_a = {
friendly_name = "View a"
labels = {}
query = "SELECT * from `my-project.my-dataset.table_a`"
use_legacy_sql = false
}
}
}
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---: |:---:|:---:|
| id | Dataset id. | <code title="">string</code> | ✓ | |
| project_id | Id of the project where datasets will be created. | <code title="">string</code> | ✓ | |
| *access* | Dataset access rules keyed by role, valid identity types are `domain`, `group_by_email`, `special_group` and `user_by_email`. Mode can be controlled via the `access_authoritative` variable. | <code title="map&#40;list&#40;object&#40;&#123;&#10;identity_type &#61; string&#10;identity &#61; string&#10;&#125;&#41;&#41;&#41;">map(list(object({...})))</code> | | <code title="">{}</code> |
| *access_authoritative* | Use authoritative access instead of additive. | <code title="">bool</code> | | <code title="">false</code> |
| *access_views* | Dataset access rules for views. Mode can be controlled via the `access_authoritative` variable. | <code title="list&#40;object&#40;&#123;&#10;project_id &#61; string&#10;dataset_id &#61; string&#10;table_id &#61; string&#10;&#125;&#41;&#41;">list(object({...}))</code> | | <code title="">[]</code> |
| *encryption_key* | Self link of the KMS key that will be used to protect destination table. | <code title="">string</code> | | <code title="">null</code> |
| *friendly_name* | Dataset friendly name. | <code title="">string</code> | | <code title="">null</code> |
| *labels* | Dataset labels. | <code title="map&#40;string&#41;">map(string)</code> | | <code title="">{}</code> |
| *location* | Dataset location. | <code title="">string</code> | | <code title="">EU</code> |
| *options* | Dataset options. | <code title="object&#40;&#123;&#10;default_table_expiration_ms &#61; number&#10;default_partition_expiration_ms &#61; number&#10;delete_contents_on_destroy &#61; bool&#10;&#125;&#41;">object({...})</code> | | <code title="&#123;&#10;default_table_expiration_ms &#61; null&#10;default_partition_expiration_ms &#61; null&#10;delete_contents_on_destroy &#61; false&#10;&#125;">...</code> |
| *tables* | Table definitions. Options and partitioning default to null. Partitioning can only use `range` or `time`, set the unused one to null. | <code title="map&#40;object&#40;&#123;&#10;friendly_name &#61; string&#10;labels &#61; map&#40;string&#41;&#10;options &#61; object&#40;&#123;&#10;clustering &#61; list&#40;string&#41;&#10;encryption_key &#61; string&#10;expiration_time &#61; number&#10;&#125;&#41;&#10;partitioning &#61; object&#40;&#123;&#10;field &#61; string&#10;range &#61; object&#40;&#123;&#10;end &#61; number&#10;interval &#61; number&#10;start &#61; number&#10;&#125;&#41;&#10;time &#61; object&#40;&#123;&#10;expiration_ms &#61; number&#10;type &#61; string&#10;&#125;&#41;&#10;&#125;&#41;&#10;schema &#61; string&#10;&#125;&#41;&#41;">map(object({...}))</code> | | <code title="">{}</code> |
| *views* | View definitions. | <code title="map&#40;object&#40;&#123;&#10;friendly_name &#61; string&#10;labels &#61; map&#40;string&#41;&#10;query &#61; string&#10;use_legacy_sql &#61; bool&#10;&#125;&#41;&#41;">map(object({...}))</code> | | <code title="">{}</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| dataset | Dataset resource. | |
| dataset_id | Dataset full id. | |
| id | Dataset id. | |
| self_link | Dataset self link. | |
| tables | Table resources. | |
| views | View resources. | |
<!-- END TFDOC -->
## TODO
- [ ] add support for tables

View File

@ -0,0 +1,173 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
access_list = flatten([
for role, accesses in var.access : [
for access in accesses : merge(access, { role = role })
]
])
access_default = {
for access in local.access_list :
"${access.role}-${access.identity_type}-${access.identity}" => access
}
access_views = {
for access in var.access_views :
"${access.project_id}-${access.dataset_id}-${access.table_id}" => access
}
}
resource "google_bigquery_dataset" "default" {
project = var.project_id
dataset_id = var.id
friendly_name = var.friendly_name
description = "Terraform managed."
labels = var.labels
location = var.location
delete_contents_on_destroy = var.options.delete_contents_on_destroy
default_table_expiration_ms = var.options.default_table_expiration_ms
default_partition_expiration_ms = var.options.default_partition_expiration_ms
dynamic access {
for_each = var.access_authoritative ? local.access_default : {}
content {
role = access.value.role
domain = (
access.value.identity_type == "domain" ? access.value.identity : null
)
group_by_email = (
access.value.identity_type == "group_by_email" ? access.value.identity : null
)
special_group = (
access.value.identity_type == "special_group" ? access.value.identity : null
)
user_by_email = (
access.value.identity_type == "user_by_email" ? access.value.identity : null
)
}
}
dynamic access {
for_each = var.access_authoritative ? local.access_views : {}
content {
view {
project_id = access.value.project_id
dataset_id = access.value.dataset_id
table_id = access.value.table_id
}
}
}
dynamic default_encryption_configuration {
for_each = var.encryption_key == null ? [] : [""]
content {
kms_key_name = var.encryption_key
}
}
}
resource "google_bigquery_dataset_access" "default" {
for_each = var.access_authoritative ? {} : local.access_default
project = var.project_id
dataset_id = google_bigquery_dataset.default.dataset_id
role = each.value.role
domain = (
each.value.identity_type == "domain" ? each.value.identity : null
)
group_by_email = (
each.value.identity_type == "group_by_email" ? each.value.identity : null
)
special_group = (
each.value.identity_type == "special_group" ? each.value.identity : null
)
user_by_email = (
each.value.identity_type == "user_by_email" ? each.value.identity : null
)
}
resource "google_bigquery_dataset_access" "views" {
for_each = var.access_authoritative ? {} : local.access_views
project = var.project_id
dataset_id = google_bigquery_dataset.default.dataset_id
view {
project_id = each.value.project
dataset_id = each.value.dataset_id
table_id = each.value.table_id
}
}
resource "google_bigquery_table" "default" {
provider = google-beta
for_each = var.tables
project = var.project_id
dataset_id = google_bigquery_dataset.default.dataset_id
table_id = each.key
friendly_name = each.value.friendly_name
description = "Terraform managed."
clustering = try(each.value.options.clustering, null)
expiration_time = try(each.value.options.expiration_time, null)
labels = each.value.labels
schema = each.value.schema
dynamic encryption_configuration {
for_each = try(each.value.options.encryption_key, null) != null ? [""] : []
content {
kms_key_name = each.value.options.encryption_key
}
}
dynamic range_partitioning {
for_each = try(each.value.partitioning.range, null) != null ? [""] : []
content {
field = each.value.partitioning.field
range {
start = each.value.partitioning.range.start
end = each.value.partitioning.range.end
interval = each.value.partitioning.range.interval
}
}
}
dynamic time_partitioning {
for_each = try(each.value.partitioning.time, null) != null ? [""] : []
content {
expiration_ms = each.value.partitioning.time.expiration_ms
field = each.value.partitioning.field
type = each.value.partitioning.time.type
}
}
}
resource "google_bigquery_table" "views" {
for_each = var.views
project = var.project_id
dataset_id = google_bigquery_dataset.default.dataset_id
table_id = each.key
friendly_name = each.value.friendly_name
description = "Terraform managed."
labels = each.value.labels
view {
query = each.value.query
use_legacy_sql = each.value.use_legacy_sql
}
}

View File

@ -0,0 +1,45 @@
/**
* Copyright 2019 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 "dataset" {
description = "Dataset resource."
value = google_bigquery_dataset.default
}
output "dataset_id" {
description = "Dataset full id."
value = google_bigquery_dataset.default.dataset_id
}
output "id" {
description = "Dataset id."
value = google_bigquery_dataset.default.id
}
output "self_link" {
description = "Dataset self link."
value = google_bigquery_dataset.default.self_link
}
output "tables" {
description = "Table resources."
value = google_bigquery_table.default
}
output "views" {
description = "View resources."
value = google_bigquery_table.views
}

View File

@ -0,0 +1,126 @@
/**
* Copyright 2019 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 "access" {
description = "Dataset access rules keyed by role, valid identity types are `domain`, `group_by_email`, `special_group` and `user_by_email`. Mode can be controlled via the `access_authoritative` variable."
type = map(list(object({
identity_type = string
identity = string
})))
default = {}
}
variable "access_authoritative" {
description = "Use authoritative access instead of additive."
type = bool
default = false
}
variable "access_views" {
description = "Dataset access rules for views. Mode can be controlled via the `access_authoritative` variable."
type = list(object({
project_id = string
dataset_id = string
table_id = string
}))
default = []
}
variable "encryption_key" {
description = "Self link of the KMS key that will be used to protect destination table."
type = string
default = null
}
variable "labels" {
description = "Dataset labels."
type = map(string)
default = {}
}
variable "location" {
description = "Dataset location."
type = string
default = "EU"
}
variable "friendly_name" {
description = "Dataset friendly name."
type = string
default = null
}
variable "id" {
description = "Dataset id."
type = string
}
variable "options" {
description = "Dataset options."
type = object({
default_table_expiration_ms = number
default_partition_expiration_ms = number
delete_contents_on_destroy = bool
})
default = {
default_table_expiration_ms = null
default_partition_expiration_ms = null
delete_contents_on_destroy = false
}
}
variable "project_id" {
description = "Id of the project where datasets will be created."
type = string
}
variable "tables" {
description = "Table definitions. Options and partitioning default to null. Partitioning can only use `range` or `time`, set the unused one to null."
type = map(object({
friendly_name = string
labels = map(string)
options = object({
clustering = list(string)
encryption_key = string
expiration_time = number
})
partitioning = object({
field = string
range = object({
end = number
interval = number
start = number
})
time = object({
expiration_ms = number
type = string
})
})
schema = string
}))
default = {}
}
variable "views" {
description = "View definitions."
type = map(object({
friendly_name = string
labels = map(string)
query = string
use_legacy_sql = bool
}))
default = {}
}

View File

@ -1,75 +0,0 @@
# Google Cloud Bigquery Module
Simple Bigquery module offering support for multiple dataset creation and access configuration.
The module interface is designed to allow setting default values for dataset access configurations and options (eg table or partition expiration), and optionally override them for individual datasets. Common labels applied to all datasets can also be specified with a single variable, and overridden individually.
Access configuration supports specifying different [identity types](https://www.terraform.io/docs/providers/google/r/bigquery_dataset.html#access) via the `identity_type` attribute in access variables. The supported identity types are: `domain`, `group_by_email`, `special_group` (eg `projectOwners`), `user_by_email`.
## TODO
- [ ] add support for `google_bigquery_dataset_access`
- [ ] add support for `google_bigquery_table`
- [ ] change the access interface so it's similar to the IAM interface in other modules
## Example
```hcl
module "bigquery-datasets" {
source = "./modules/bigquery"
project_id = "my-project
datasets = {
dataset_1 = {
name = "Dataset 1."
description = "Terraform managed."
location = "EU"
labels = null
},
dataset_2 = {
name = "Dataset 2."
description = "Terraform managed."
location = "EU"
labels = null
},
}
default_access = [
{
role = "OWNER"
identity_type = "special_group"
identity = "projectOwners"
}
]
default_labels = {
eggs = "spam",
bar = "baz
}
}
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---: |:---:|:---:|
| datasets | Map of datasets to create keyed by id. Labels and options can be null. | <code title="map&#40;object&#40;&#123;&#10;description &#61; string&#10;location &#61; string&#10;name &#61; string&#10;labels &#61; map&#40;string&#41;&#10;&#125;&#41;&#41;">map(object({...}))</code> | ✓ | |
| project_id | Id of the project where datasets will be created. | <code title="">string</code> | ✓ | |
| *dataset_access* | Optional map of dataset access rules by dataset id. | <code title="map&#40;list&#40;object&#40;&#123;&#10;role &#61; string&#10;identity_type &#61; string&#10;identity &#61; any&#10;&#125;&#41;&#41;&#41;">map(list(object({...})))</code> | | <code title="">{}</code> |
| *dataset_options* | Optional map of dataset option by dataset id. | <code title="map&#40;object&#40;&#123;&#10;default_table_expiration_ms &#61; number&#10;default_partition_expiration_ms &#61; number&#10;delete_contents_on_destroy &#61; bool&#10;&#125;&#41;&#41;">map(object({...}))</code> | | <code title="">{}</code> |
| *default_access* | Access rules applied to all dataset if no specific ones are defined. | <code title="list&#40;object&#40;&#123;&#10;role &#61; string&#10;identity_type &#61; string&#10;identity &#61; any&#10;&#125;&#41;&#41;">list(object({...}))</code> | | <code title="">[]</code> |
| *default_labels* | Labels set on all datasets. | <code title="map&#40;string&#41;">map(string)</code> | | <code title="">{}</code> |
| *default_options* | Options used for all dataset if no specific ones are defined. | <code title="object&#40;&#123;&#10;default_table_expiration_ms &#61; number&#10;default_partition_expiration_ms &#61; number&#10;delete_contents_on_destroy &#61; bool&#10;&#125;&#41;">object({...})</code> | | <code title="&#123;&#10;default_table_expiration_ms &#61; null&#10;default_partition_expiration_ms &#61; null&#10;delete_contents_on_destroy &#61; false&#10;&#125;">...</code> |
| *kms_key* | Self link of the KMS key that will be used to protect destination table. | <code title="">string</code> | | <code title="">null</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| datasets | Dataset resources. | |
| ids | Dataset ids. | |
| names | Dataset names. | |
| self_links | Dataset self links. | |
<!-- END TFDOC -->
## TODO
- [ ] add support for tables

View File

@ -1,66 +0,0 @@
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
datasets = {
for id, data in var.datasets :
id => merge(data, {
options = lookup(var.dataset_options, id, var.default_options)
access = lookup(var.dataset_access, id, var.default_access)
labels = data.labels == null ? {} : data.labels
})
}
}
resource "google_bigquery_dataset" "datasets" {
for_each = local.datasets
project = var.project_id
dataset_id = each.key
friendly_name = each.value.name
description = each.value.description
labels = merge(var.default_labels, each.value.labels)
location = each.value.location
delete_contents_on_destroy = each.value.options.delete_contents_on_destroy
default_table_expiration_ms = each.value.options.default_table_expiration_ms
default_partition_expiration_ms = each.value.options.default_partition_expiration_ms
dynamic access {
for_each = each.value.access
content {
role = access.value.role
domain = access.value.identity_type == "domain" ? access.value.identity : null
group_by_email = access.value.identity_type == "group_by_email" ? access.value.identity : null
special_group = access.value.identity_type == "special_group" ? access.value.identity : null
user_by_email = access.value.identity_type == "user_by_email" ? access.value.identity : null
dynamic view {
for_each = access.value.identity_type == "view" ? [""] : []
content {
project_id = view.value.project_id
dataset_id = view.value.dataset_id
table_id = view.value.table_id
}
}
}
}
dynamic default_encryption_configuration {
for_each = var.kms_key == null ? [] : [""]
content {
kms_key_name = var.kms_key
}
}
}

View File

@ -1,47 +0,0 @@
/**
* Copyright 2019 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 "datasets" {
description = "Dataset resources."
value = [
for _, resource in google_bigquery_dataset.datasets :
resource
]
}
output "ids" {
description = "Dataset ids."
value = [
for _, resource in google_bigquery_dataset.datasets :
resource.id
]
}
output "names" {
description = "Dataset names."
value = [
for _, resource in google_bigquery_dataset.datasets :
resource.friendly_name
]
}
output "self_links" {
description = "Dataset self links."
value = [
for _, resource in google_bigquery_dataset.datasets :
resource.self_link
]
}

View File

@ -1,86 +0,0 @@
/**
* Copyright 2019 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 "datasets" {
description = "Map of datasets to create keyed by id. Labels and options can be null."
type = map(object({
description = string
location = string
name = string
labels = map(string)
}))
}
variable "dataset_access" {
description = "Optional map of dataset access rules by dataset id."
type = map(list(object({
role = string
identity_type = string
identity = any
})))
default = {}
}
variable "dataset_options" {
description = "Optional map of dataset option by dataset id."
type = map(object({
default_table_expiration_ms = number
default_partition_expiration_ms = number
delete_contents_on_destroy = bool
}))
default = {}
}
variable "default_access" {
description = "Access rules applied to all dataset if no specific ones are defined."
type = list(object({
role = string
identity_type = string
identity = any
}))
default = []
}
variable "default_labels" {
description = "Labels set on all datasets."
type = map(string)
default = {}
}
variable "default_options" {
description = "Options used for all dataset if no specific ones are defined."
type = object({
default_table_expiration_ms = number
default_partition_expiration_ms = number
delete_contents_on_destroy = bool
})
default = {
default_table_expiration_ms = null
default_partition_expiration_ms = null
delete_contents_on_destroy = false
}
}
variable "kms_key" {
description = "Self link of the KMS key that will be used to protect destination table."
type = string
default = null
}
variable "project_id" {
description = "Id of the project where datasets will be created."
type = string
}