main.tf (225 lines of code) (raw):
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
tables = { for table in var.tables : table["table_id"] => table }
views = { for view in var.views : view["view_id"] => view }
materialized_views = { for mat_view in var.materialized_views : mat_view["view_id"] => mat_view }
external_tables = { for external_table in var.external_tables : external_table["table_id"] => external_table }
routines = { for routine in var.routines : routine["routine_id"] => routine }
iam_to_primitive = {
"roles/bigquery.dataOwner" : "OWNER"
"roles/bigquery.dataEditor" : "WRITER"
"roles/bigquery.dataViewer" : "READER"
}
}
resource "google_bigquery_dataset" "main" {
dataset_id = var.dataset_id
friendly_name = var.dataset_name
description = var.description
location = var.location
delete_contents_on_destroy = var.delete_contents_on_destroy
default_table_expiration_ms = var.default_table_expiration_ms
max_time_travel_hours = var.max_time_travel_hours
project = var.project_id
labels = var.dataset_labels
dynamic "default_encryption_configuration" {
for_each = var.encryption_key == null ? [] : [var.encryption_key]
content {
kms_key_name = var.encryption_key
}
}
dynamic "access" {
for_each = var.access
content {
# BigQuery API converts IAM to primitive roles in its backend.
# This causes Terraform to show a diff on every plan that uses IAM equivalent roles.
# Thus, do the conversion between IAM to primitive role here to prevent the diff.
role = lookup(local.iam_to_primitive, access.value.role, access.value.role)
# Additionally, using null as a default value would lead to a permanant diff
# See https://github.com/hashicorp/terraform-provider-google/issues/4085#issuecomment-516923872
domain = lookup(access.value, "domain", "")
group_by_email = lookup(access.value, "group_by_email", "")
user_by_email = lookup(access.value, "user_by_email", "")
special_group = lookup(access.value, "special_group", "")
}
}
}
resource "google_bigquery_table" "main" {
for_each = local.tables
dataset_id = google_bigquery_dataset.main.dataset_id
friendly_name = each.value["table_name"] != null ? each.value["table_name"] : each.key
table_id = each.key
description = each.value["description"]
labels = each.value["labels"]
schema = each.value["schema"]
clustering = each.value["clustering"]
expiration_time = each.value["expiration_time"] != null ? each.value["expiration_time"] : 0
project = var.project_id
deletion_protection = var.deletion_protection
dynamic "time_partitioning" {
for_each = each.value["time_partitioning"] != null ? [each.value["time_partitioning"]] : []
content {
type = time_partitioning.value["type"]
expiration_ms = time_partitioning.value["expiration_ms"] != null ? time_partitioning.value["expiration_ms"] : 0
field = time_partitioning.value["field"]
require_partition_filter = time_partitioning.value["require_partition_filter"]
}
}
dynamic "range_partitioning" {
for_each = each.value["range_partitioning"] != null ? [each.value["range_partitioning"]] : []
content {
field = range_partitioning.value["field"]
range {
start = range_partitioning.value["range"].start
end = range_partitioning.value["range"].end
interval = range_partitioning.value["range"].interval
}
}
}
lifecycle {
ignore_changes = [
encryption_configuration # managed by google_bigquery_dataset.main.default_encryption_configuration
]
}
}
resource "google_bigquery_table" "view" {
for_each = local.views
dataset_id = google_bigquery_dataset.main.dataset_id
friendly_name = each.key
table_id = each.key
description = each.value["description"]
labels = each.value["labels"]
project = var.project_id
deletion_protection = false
view {
query = each.value["query"]
use_legacy_sql = each.value["use_legacy_sql"]
}
lifecycle {
ignore_changes = [
encryption_configuration # managed by google_bigquery_dataset.main.default_encryption_configuration
]
}
}
resource "google_bigquery_table" "materialized_view" {
for_each = local.materialized_views
dataset_id = google_bigquery_dataset.main.dataset_id
friendly_name = each.key
table_id = each.key
description = each.value["description"]
labels = each.value["labels"]
clustering = each.value["clustering"]
expiration_time = each.value["expiration_time"] != null ? each.value["expiration_time"] : 0
max_staleness = each.value["max_staleness"]
project = var.project_id
deletion_protection = false
dynamic "time_partitioning" {
for_each = each.value["time_partitioning"] != null ? [each.value["time_partitioning"]] : []
content {
type = time_partitioning.value["type"]
expiration_ms = time_partitioning.value["expiration_ms"] != null ? time_partitioning.value["expiration_ms"] : 0
field = time_partitioning.value["field"]
require_partition_filter = time_partitioning.value["require_partition_filter"]
}
}
dynamic "range_partitioning" {
for_each = each.value["range_partitioning"] != null ? [each.value["range_partitioning"]] : []
content {
field = range_partitioning.value["field"]
range {
start = range_partitioning.value["range"].start
end = range_partitioning.value["range"].end
interval = range_partitioning.value["range"].interval
}
}
}
materialized_view {
query = each.value["query"]
enable_refresh = each.value["enable_refresh"]
refresh_interval_ms = each.value["refresh_interval_ms"]
}
lifecycle {
ignore_changes = [
encryption_configuration # managed by google_bigquery_dataset.main.default_encryption_configuration
]
}
}
resource "google_bigquery_table" "external_table" {
for_each = local.external_tables
dataset_id = google_bigquery_dataset.main.dataset_id
friendly_name = each.key
table_id = each.key
description = each.value["description"]
labels = each.value["labels"]
expiration_time = each.value["expiration_time"] != null ? each.value["expiration_time"] : 0
max_staleness = each.value["max_staleness"]
project = var.project_id
deletion_protection = var.deletion_protection
external_data_configuration {
autodetect = each.value["autodetect"]
compression = each.value["compression"]
ignore_unknown_values = each.value["ignore_unknown_values"]
max_bad_records = each.value["max_bad_records"]
schema = each.value["schema"]
source_format = each.value["source_format"]
source_uris = each.value["source_uris"]
dynamic "csv_options" {
for_each = each.value["csv_options"] != null ? [each.value["csv_options"]] : []
content {
quote = csv_options.value["quote"]
allow_jagged_rows = csv_options.value["allow_jagged_rows"]
allow_quoted_newlines = csv_options.value["allow_quoted_newlines"]
encoding = csv_options.value["encoding"]
field_delimiter = csv_options.value["field_delimiter"]
skip_leading_rows = csv_options.value["skip_leading_rows"]
}
}
dynamic "google_sheets_options" {
for_each = each.value["google_sheets_options"] != null ? [each.value["google_sheets_options"]] : []
content {
range = google_sheets_options.value["range"]
skip_leading_rows = google_sheets_options.value["skip_leading_rows"]
}
}
dynamic "hive_partitioning_options" {
for_each = each.value["hive_partitioning_options"] != null ? [each.value["hive_partitioning_options"]] : []
content {
mode = hive_partitioning_options.value["mode"]
source_uri_prefix = hive_partitioning_options.value["source_uri_prefix"]
}
}
}
lifecycle {
ignore_changes = [
encryption_configuration # managed by google_bigquery_dataset.main.default_encryption_configuration
]
}
}
resource "google_bigquery_routine" "routine" {
for_each = local.routines
dataset_id = google_bigquery_dataset.main.dataset_id
routine_id = each.key
description = each.value["description"]
routine_type = each.value["routine_type"]
language = each.value["language"]
definition_body = each.value["definition_body"]
project = var.project_id
dynamic "arguments" {
for_each = each.value["arguments"] != null ? each.value["arguments"] : []
content {
name = arguments.value["name"]
data_type = arguments.value["data_type"]
mode = arguments.value["mode"]
argument_kind = arguments.value["argument_kind"]
}
}
return_type = each.value["return_type"]
}