Remove as_logging_destination
This commit is contained in:
parent
b37ef3a90a
commit
c83a7de076
|
@ -193,8 +193,9 @@ module "organization" {
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
for name, attrs in var.log_sinks : name => {
|
for name, attrs in var.log_sinks : name => {
|
||||||
bq_partitioned_table = attrs.type == "bigquery"
|
bq_partitioned_table = attrs.type == "bigquery"
|
||||||
destination = local.log_sink_destinations[name].as_logging_destination
|
destination = local.log_sink_destinations[name].id
|
||||||
filter = attrs.filter
|
filter = attrs.filter
|
||||||
|
type = attrs.type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,21 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
output "as_logging_destination" {
|
|
||||||
description = "Parameters to use this dataset as a log sink destination."
|
|
||||||
value = {
|
|
||||||
type = "bigquery"
|
|
||||||
target = google_bigquery_dataset.default.id
|
|
||||||
}
|
|
||||||
depends_on = [
|
|
||||||
google_bigquery_dataset_access.domain,
|
|
||||||
google_bigquery_dataset_access.group_by_email,
|
|
||||||
google_bigquery_dataset_access.special_group,
|
|
||||||
google_bigquery_dataset_access.user_by_email,
|
|
||||||
google_bigquery_dataset_access.views
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
output "dataset" {
|
output "dataset" {
|
||||||
description = "Dataset resource."
|
description = "Dataset resource."
|
||||||
value = google_bigquery_dataset.default
|
value = google_bigquery_dataset.default
|
||||||
|
|
|
@ -173,23 +173,27 @@ module "folder-sink" {
|
||||||
name = "my-folder"
|
name = "my-folder"
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
warnings = {
|
warnings = {
|
||||||
destination = module.gcs.as_logging_destination
|
destination = module.gcs.id
|
||||||
filter = "severity=WARNING"
|
filter = "severity=WARNING"
|
||||||
|
type = "storage"
|
||||||
}
|
}
|
||||||
info = {
|
info = {
|
||||||
destination = module.dataset.as_logging_destination
|
destination = module.dataset.id
|
||||||
filter = "severity=INFO"
|
filter = "severity=INFO"
|
||||||
|
type = "bigquery"
|
||||||
}
|
}
|
||||||
notice = {
|
notice = {
|
||||||
destination = module.pubsub.as_logging_destination
|
destination = module.pubsub.id
|
||||||
filter = "severity=NOTICE"
|
filter = "severity=NOTICE"
|
||||||
|
type = "pubsub"
|
||||||
}
|
}
|
||||||
debug = {
|
debug = {
|
||||||
destination = module.bucket.as_logging_destination
|
destination = module.bucket.id
|
||||||
filter = "severity=DEBUG"
|
filter = "severity=DEBUG"
|
||||||
exclusions = {
|
exclusions = {
|
||||||
no-compute = "logName:compute"
|
no-compute = "logName:compute"
|
||||||
}
|
}
|
||||||
|
type = "logging"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logging_exclusions = {
|
logging_exclusions = {
|
||||||
|
@ -302,12 +306,12 @@ module "folder" {
|
||||||
| [iam_additive_members](variables.tf#L85) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | <code>map(list(string))</code> | | <code>{}</code> |
|
| [iam_additive_members](variables.tf#L85) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||||
| [id](variables.tf#L92) | Folder ID in case you use folder_create=false. | <code>string</code> | | <code>null</code> |
|
| [id](variables.tf#L92) | Folder ID in case you use folder_create=false. | <code>string</code> | | <code>null</code> |
|
||||||
| [logging_exclusions](variables.tf#L98) | Logging exclusions for this folder in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
| [logging_exclusions](variables.tf#L98) | Logging exclusions for this folder in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
||||||
| [logging_sinks](variables.tf#L105) | Logging sinks to create for this folder. | <code title="map(object({ bq_partitioned_table = optional(bool) description = optional(string) destination = object({ type = string target = string }) disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = string include_children = optional(bool, true) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [logging_sinks](variables.tf#L105) | Logging sinks to create for the organization. | <code title="map(object({ bq_partitioned_table = optional(bool) description = optional(string) destination = string disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = string include_children = optional(bool, true) type = string }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [name](variables.tf#L137) | Folder name. | <code>string</code> | | <code>null</code> |
|
| [name](variables.tf#L135) | Folder name. | <code>string</code> | | <code>null</code> |
|
||||||
| [org_policies](variables.tf#L143) | Organization policies applied to this folder keyed by policy name. | <code title="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. condition = object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [org_policies](variables.tf#L141) | Organization policies applied to this folder keyed by policy name. | <code title="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. condition = object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [org_policies_data_path](variables.tf#L183) | Path containing org policies in YAML format. | <code>string</code> | | <code>null</code> |
|
| [org_policies_data_path](variables.tf#L181) | Path containing org policies in YAML format. | <code>string</code> | | <code>null</code> |
|
||||||
| [parent](variables.tf#L189) | Parent in folders/folder_id or organizations/org_id format. | <code>string</code> | | <code>null</code> |
|
| [parent](variables.tf#L187) | Parent in folders/folder_id or organizations/org_id format. | <code>string</code> | | <code>null</code> |
|
||||||
| [tag_bindings](variables.tf#L199) | Tag bindings for this folder, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
| [tag_bindings](variables.tf#L197) | Tag bindings for this folder, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ locals {
|
||||||
type => {
|
type => {
|
||||||
for name, sink in var.logging_sinks :
|
for name, sink in var.logging_sinks :
|
||||||
name => sink
|
name => sink
|
||||||
if sink.destination.type == type
|
if sink.type == type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ resource "google_logging_folder_sink" "sink" {
|
||||||
name = each.key
|
name = each.key
|
||||||
description = coalesce(each.value.description, "${each.key} (Terraform-managed).")
|
description = coalesce(each.value.description, "${each.key} (Terraform-managed).")
|
||||||
folder = local.folder.name
|
folder = local.folder.name
|
||||||
destination = "${each.value.destination.type}.googleapis.com/${each.value.destination.target}"
|
destination = "${each.value.type}.googleapis.com/${each.value.destination}"
|
||||||
filter = each.value.filter
|
filter = each.value.filter
|
||||||
include_children = each.value.include_children
|
include_children = each.value.include_children
|
||||||
disabled = each.value.disabled
|
disabled = each.value.disabled
|
||||||
|
@ -60,37 +60,37 @@ resource "google_logging_folder_sink" "sink" {
|
||||||
|
|
||||||
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
|
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
|
||||||
for_each = local.sink_bindings["storage"]
|
for_each = local.sink_bindings["storage"]
|
||||||
bucket = each.value.destination.target
|
bucket = each.value.destination
|
||||||
role = "roles/storage.objectCreator"
|
role = "roles/storage.objectCreator"
|
||||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
||||||
for_each = local.sink_bindings["bigquery"]
|
for_each = local.sink_bindings["bigquery"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
dataset_id = split("/", each.value.destination.target)[3]
|
dataset_id = split("/", each.value.destination)[3]
|
||||||
role = "roles/bigquery.dataEditor"
|
role = "roles/bigquery.dataEditor"
|
||||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
||||||
for_each = local.sink_bindings["pubsub"]
|
for_each = local.sink_bindings["pubsub"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
topic = split("/", each.value.destination.target)[3]
|
topic = split("/", each.value.destination)[3]
|
||||||
role = "roles/pubsub.publisher"
|
role = "roles/pubsub.publisher"
|
||||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_project_iam_member" "bucket-sinks-binding" {
|
resource "google_project_iam_member" "bucket-sinks-binding" {
|
||||||
for_each = local.sink_bindings["logging"]
|
for_each = local.sink_bindings["logging"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
role = "roles/logging.bucketWriter"
|
role = "roles/logging.bucketWriter"
|
||||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||||
|
|
||||||
condition {
|
condition {
|
||||||
title = "${each.key} bucket writer"
|
title = "${each.key} bucket writer"
|
||||||
description = "Grants bucketWriter to ${google_logging_folder_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${local.folder.id}"
|
description = "Grants bucketWriter to ${google_logging_folder_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${local.folder.id}"
|
||||||
expression = "resource.name.endsWith('${each.value.destination.target}')"
|
expression = "resource.name.endsWith('${each.value.destination}')"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,34 +103,32 @@ variable "logging_exclusions" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "logging_sinks" {
|
variable "logging_sinks" {
|
||||||
description = "Logging sinks to create for this folder."
|
description = "Logging sinks to create for the organization."
|
||||||
type = map(object({
|
type = map(object({
|
||||||
bq_partitioned_table = optional(bool)
|
bq_partitioned_table = optional(bool)
|
||||||
description = optional(string)
|
description = optional(string)
|
||||||
destination = object({
|
destination = string
|
||||||
type = string
|
|
||||||
target = string
|
|
||||||
})
|
|
||||||
disabled = optional(bool, false)
|
disabled = optional(bool, false)
|
||||||
exclusions = optional(map(string), {})
|
exclusions = optional(map(string), {})
|
||||||
filter = string
|
filter = string
|
||||||
include_children = optional(bool, true)
|
include_children = optional(bool, true)
|
||||||
|
type = string
|
||||||
}))
|
}))
|
||||||
default = {}
|
default = {}
|
||||||
nullable = false
|
nullable = false
|
||||||
validation {
|
validation {
|
||||||
condition = alltrue([
|
condition = alltrue([
|
||||||
for k, v in var.logging_sinks :
|
for k, v in var.logging_sinks :
|
||||||
contains(["bigquery", "logging", "pubsub", "storage"], v.destination.type)
|
contains(["bigquery", "logging", "pubsub", "storage"], v.type)
|
||||||
])
|
])
|
||||||
error_message = "Destination type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
||||||
}
|
}
|
||||||
validation {
|
validation {
|
||||||
condition = alltrue([
|
condition = alltrue([
|
||||||
for k, v in var.logging_sinks :
|
for k, v in var.logging_sinks :
|
||||||
v.bq_partitioned_table != true || v.destination.type == "bigquery"
|
v.bq_partitioned_table != true || v.type == "bigquery"
|
||||||
])
|
])
|
||||||
error_message = "Can only set when destination type is `bigquery`."
|
error_message = "Can only set bq_partitioned_table when type is `bigquery`."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,23 +14,26 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
output "as_logging_destination" {
|
output "bucket" {
|
||||||
description = "Parameters to use this bucket as a log sink destination."
|
description = "Bucket resource."
|
||||||
value = {
|
value = google_storage_bucket.bucket
|
||||||
type = "storage"
|
}
|
||||||
target = "${local.prefix}${lower(var.name)}"
|
|
||||||
}
|
# We add `id` as an alias to `name` to simplify log sink handling.
|
||||||
|
# Since all other log destinations (pubsub, logging-bucket, bigquery)
|
||||||
|
# have an id output, it is convenient to have in this module too to
|
||||||
|
# handle all log destination as homogeneous objects (i.e. you can
|
||||||
|
# assume any valid log destination has an `id` output).
|
||||||
|
|
||||||
|
output "id" {
|
||||||
|
description = "Bucket ID (same as name)."
|
||||||
|
value = "${local.prefix}${lower(var.name)}"
|
||||||
depends_on = [
|
depends_on = [
|
||||||
google_storage_bucket.bucket,
|
google_storage_bucket.bucket,
|
||||||
google_storage_bucket_iam_binding.bindings
|
google_storage_bucket_iam_binding.bindings
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
output "bucket" {
|
|
||||||
description = "Bucket resource."
|
|
||||||
value = google_storage_bucket.bucket
|
|
||||||
}
|
|
||||||
|
|
||||||
output "name" {
|
output "name" {
|
||||||
description = "Bucket name."
|
description = "Bucket name."
|
||||||
value = "${local.prefix}${lower(var.name)}"
|
value = "${local.prefix}${lower(var.name)}"
|
||||||
|
|
|
@ -14,19 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
output "as_logging_destination" {
|
|
||||||
description = "Parameters to use this bucket as a log sink destination."
|
|
||||||
value = {
|
|
||||||
type = "logging"
|
|
||||||
target = try(
|
|
||||||
google_logging_project_bucket_config.bucket.0.id,
|
|
||||||
google_logging_folder_bucket_config.bucket.0.id,
|
|
||||||
google_logging_organization_bucket_config.bucket.0.id,
|
|
||||||
google_logging_billing_account_bucket_config.bucket.0.id,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output "id" {
|
output "id" {
|
||||||
description = "ID of the created bucket."
|
description = "ID of the created bucket."
|
||||||
value = try(
|
value = try(
|
||||||
|
|
|
@ -311,24 +311,28 @@ module "org" {
|
||||||
|
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
warnings = {
|
warnings = {
|
||||||
destination = module.gcs.as_logging_destination
|
destination = module.gcs.id
|
||||||
filter = "severity=WARNING"
|
filter = "severity=WARNING"
|
||||||
|
type = "storage"
|
||||||
}
|
}
|
||||||
info = {
|
info = {
|
||||||
destination = module.dataset.as_logging_destination
|
|
||||||
filter = "severity=INFO"
|
|
||||||
bq_partitioned_table = true
|
bq_partitioned_table = true
|
||||||
|
destination = module.dataset.id
|
||||||
|
filter = "severity=INFO"
|
||||||
|
type = "bigquery"
|
||||||
}
|
}
|
||||||
notice = {
|
notice = {
|
||||||
destination = module.pubsub.as_logging_destination
|
destination = module.pubsub.id
|
||||||
filter = "severity=NOTICE"
|
filter = "severity=NOTICE"
|
||||||
|
type = "pubsub"
|
||||||
}
|
}
|
||||||
debug = {
|
debug = {
|
||||||
destination = module.bucket.as_logging_destination
|
destination = module.bucket.id
|
||||||
filter = "severity=DEBUG"
|
filter = "severity=DEBUG"
|
||||||
exclusions = {
|
exclusions = {
|
||||||
no-compute = "logName:compute"
|
no-compute = "logName:compute"
|
||||||
}
|
}
|
||||||
|
type = "logging"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logging_exclusions = {
|
logging_exclusions = {
|
||||||
|
@ -411,7 +415,7 @@ module "org" {
|
||||||
|
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [organization_id](variables.tf#L227) | Organization id in organizations/nnnnnn format. | <code>string</code> | ✓ | |
|
| [organization_id](variables.tf#L225) | Organization id in organizations/nnnnnn format. | <code>string</code> | ✓ | |
|
||||||
| [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. | <code>map(list(string))</code> | | <code>{}</code> |
|
| [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. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||||
| [custom_roles](variables.tf#L24) | Map of role name => list of permissions to create in this project. | <code>map(list(string))</code> | | <code>{}</code> |
|
| [custom_roles](variables.tf#L24) | Map of role name => list of permissions to create in this project. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||||
| [firewall_policies](variables.tf#L31) | Hierarchical firewall policy rules created in the organization. | <code title="map(map(object({ action = string description = string direction = string logging = bool ports = map(list(string)) priority = number ranges = list(string) target_resources = list(string) target_service_accounts = list(string) })))">map(map(object({…})))</code> | | <code>{}</code> |
|
| [firewall_policies](variables.tf#L31) | Hierarchical firewall policy rules created in the organization. | <code title="map(map(object({ action = string description = string direction = string logging = bool ports = map(list(string)) priority = number ranges = list(string) target_resources = list(string) target_service_accounts = list(string) })))">map(map(object({…})))</code> | | <code>{}</code> |
|
||||||
|
@ -425,13 +429,13 @@ module "org" {
|
||||||
| [iam_audit_config_authoritative](variables.tf#L105) | IAM Authoritative service audit logging configuration. Service as key, map of log permission (eg DATA_READ) and excluded members as value for each service. Audit config should also be authoritative when using authoritative bindings. Use with caution. | <code>map(map(list(string)))</code> | | <code>null</code> |
|
| [iam_audit_config_authoritative](variables.tf#L105) | IAM Authoritative service audit logging configuration. Service as key, map of log permission (eg DATA_READ) and excluded members as value for each service. Audit config should also be authoritative when using authoritative bindings. Use with caution. | <code>map(map(list(string)))</code> | | <code>null</code> |
|
||||||
| [iam_bindings_authoritative](variables.tf#L116) | IAM authoritative bindings, in {ROLE => [MEMBERS]} format. Roles and members not explicitly listed will be cleared. Bindings should also be authoritative when using authoritative audit config. Use with caution. | <code>map(list(string))</code> | | <code>null</code> |
|
| [iam_bindings_authoritative](variables.tf#L116) | IAM authoritative bindings, in {ROLE => [MEMBERS]} format. Roles and members not explicitly listed will be cleared. Bindings should also be authoritative when using authoritative audit config. Use with caution. | <code>map(list(string))</code> | | <code>null</code> |
|
||||||
| [logging_exclusions](variables.tf#L122) | Logging exclusions for this organization in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
| [logging_exclusions](variables.tf#L122) | Logging exclusions for this organization in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
||||||
| [logging_sinks](variables.tf#L129) | Logging sinks to create for the organization. | <code title="map(object({ bq_partitioned_table = optional(bool) description = optional(string) destination = object({ type = string target = string }) disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = string include_children = optional(bool, true) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [logging_sinks](variables.tf#L129) | Logging sinks to create for the organization. | <code title="map(object({ bq_partitioned_table = optional(bool) description = optional(string) destination = string disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = string include_children = optional(bool, true) type = string }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [org_policies](variables.tf#L161) | Organization policies applied to this organization keyed by policy name. | <code title="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. condition = object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [org_policies](variables.tf#L159) | Organization policies applied to this organization keyed by policy name. | <code title="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. condition = object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [org_policies_data_path](variables.tf#L201) | Path containing org policies in YAML format. | <code>string</code> | | <code>null</code> |
|
| [org_policies_data_path](variables.tf#L199) | Path containing org policies in YAML format. | <code>string</code> | | <code>null</code> |
|
||||||
| [org_policy_custom_constraints](variables.tf#L207) | Organization policiy custom constraints keyed by constraint name. | <code title="map(object({ display_name = optional(string) description = optional(string) action_type = string condition = string method_types = list(string) resource_types = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [org_policy_custom_constraints](variables.tf#L205) | Organization policiy custom constraints keyed by constraint name. | <code title="map(object({ display_name = optional(string) description = optional(string) action_type = string condition = string method_types = list(string) resource_types = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [org_policy_custom_constraints_data_path](variables.tf#L221) | Path containing org policy custom constraints in YAML format. | <code>string</code> | | <code>null</code> |
|
| [org_policy_custom_constraints_data_path](variables.tf#L219) | Path containing org policy custom constraints in YAML format. | <code>string</code> | | <code>null</code> |
|
||||||
| [tag_bindings](variables.tf#L237) | Tag bindings for this organization, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
| [tag_bindings](variables.tf#L235) | Tag bindings for this organization, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
||||||
| [tags](variables.tf#L243) | Tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map(object({ description = string iam = map(list(string)) values = map(object({ description = string iam = map(list(string)) })) }))">map(object({…}))</code> | | <code>null</code> |
|
| [tags](variables.tf#L241) | Tags by key name. The `iam` attribute behaves like the similarly named one at module level. | <code title="map(object({ description = string iam = map(list(string)) values = map(object({ description = string iam = map(list(string)) })) }))">map(object({…}))</code> | | <code>null</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ locals {
|
||||||
for type in ["bigquery", "logging", "pubsub", "storage"] :
|
for type in ["bigquery", "logging", "pubsub", "storage"] :
|
||||||
type => {
|
type => {
|
||||||
for name, sink in var.logging_sinks :
|
for name, sink in var.logging_sinks :
|
||||||
name => sink if sink.destination.type == type
|
name => sink if sink.type == type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ resource "google_logging_organization_sink" "sink" {
|
||||||
name = each.key
|
name = each.key
|
||||||
description = coalesce(each.value.description, "${each.key} (Terraform-managed).")
|
description = coalesce(each.value.description, "${each.key} (Terraform-managed).")
|
||||||
org_id = local.organization_id_numeric
|
org_id = local.organization_id_numeric
|
||||||
destination = "${each.value.destination.type}.googleapis.com/${each.value.destination.target}"
|
destination = "${each.value.type}.googleapis.com/${each.value.destination}"
|
||||||
filter = each.value.filter
|
filter = each.value.filter
|
||||||
include_children = each.value.include_children
|
include_children = each.value.include_children
|
||||||
disabled = each.value.disabled
|
disabled = each.value.disabled
|
||||||
|
@ -61,37 +61,37 @@ resource "google_logging_organization_sink" "sink" {
|
||||||
|
|
||||||
resource "google_storage_bucket_iam_member" "storage-sinks-binding" {
|
resource "google_storage_bucket_iam_member" "storage-sinks-binding" {
|
||||||
for_each = local.sink_bindings["storage"]
|
for_each = local.sink_bindings["storage"]
|
||||||
bucket = each.value.destination.target
|
bucket = each.value.destination
|
||||||
role = "roles/storage.objectCreator"
|
role = "roles/storage.objectCreator"
|
||||||
member = google_logging_organization_sink.sink[each.key].writer_identity
|
member = google_logging_organization_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
||||||
for_each = local.sink_bindings["bigquery"]
|
for_each = local.sink_bindings["bigquery"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
dataset_id = split("/", each.value.destination.target)[3]
|
dataset_id = split("/", each.value.destination)[3]
|
||||||
role = "roles/bigquery.dataEditor"
|
role = "roles/bigquery.dataEditor"
|
||||||
member = google_logging_organization_sink.sink[each.key].writer_identity
|
member = google_logging_organization_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
||||||
for_each = local.sink_bindings["pubsub"]
|
for_each = local.sink_bindings["pubsub"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
topic = split("/", each.value.destination.target)[3]
|
topic = split("/", each.value.destination)[3]
|
||||||
role = "roles/pubsub.publisher"
|
role = "roles/pubsub.publisher"
|
||||||
member = google_logging_organization_sink.sink[each.key].writer_identity
|
member = google_logging_organization_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_project_iam_member" "bucket-sinks-binding" {
|
resource "google_project_iam_member" "bucket-sinks-binding" {
|
||||||
for_each = local.sink_bindings["logging"]
|
for_each = local.sink_bindings["logging"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
role = "roles/logging.bucketWriter"
|
role = "roles/logging.bucketWriter"
|
||||||
member = google_logging_organization_sink.sink[each.key].writer_identity
|
member = google_logging_organization_sink.sink[each.key].writer_identity
|
||||||
|
|
||||||
condition {
|
condition {
|
||||||
title = "${each.key} bucket writer"
|
title = "${each.key} bucket writer"
|
||||||
description = "Grants bucketWriter to ${google_logging_organization_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${var.organization_id}"
|
description = "Grants bucketWriter to ${google_logging_organization_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${var.organization_id}"
|
||||||
expression = "resource.name.endsWith('${each.value.destination.target}')"
|
expression = "resource.name.endsWith('${each.value.destination}')"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,30 +131,28 @@ variable "logging_sinks" {
|
||||||
type = map(object({
|
type = map(object({
|
||||||
bq_partitioned_table = optional(bool)
|
bq_partitioned_table = optional(bool)
|
||||||
description = optional(string)
|
description = optional(string)
|
||||||
destination = object({
|
destination = string
|
||||||
type = string
|
|
||||||
target = string
|
|
||||||
})
|
|
||||||
disabled = optional(bool, false)
|
disabled = optional(bool, false)
|
||||||
exclusions = optional(map(string), {})
|
exclusions = optional(map(string), {})
|
||||||
filter = string
|
filter = string
|
||||||
include_children = optional(bool, true)
|
include_children = optional(bool, true)
|
||||||
|
type = string
|
||||||
}))
|
}))
|
||||||
default = {}
|
default = {}
|
||||||
nullable = false
|
nullable = false
|
||||||
validation {
|
validation {
|
||||||
condition = alltrue([
|
condition = alltrue([
|
||||||
for k, v in var.logging_sinks :
|
for k, v in var.logging_sinks :
|
||||||
contains(["bigquery", "logging", "pubsub", "storage"], v.destination.type)
|
contains(["bigquery", "logging", "pubsub", "storage"], v.type)
|
||||||
])
|
])
|
||||||
error_message = "Destination type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
||||||
}
|
}
|
||||||
validation {
|
validation {
|
||||||
condition = alltrue([
|
condition = alltrue([
|
||||||
for k, v in var.logging_sinks :
|
for k, v in var.logging_sinks :
|
||||||
v.bq_partitioned_table != true || v.destination.type == "bigquery"
|
v.bq_partitioned_table != true || v.type == "bigquery"
|
||||||
])
|
])
|
||||||
error_message = "Can only set bq_partitioned_table when destination type is `bigquery`."
|
error_message = "Can only set bq_partitioned_table when type is `bigquery`."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,23 +312,27 @@ module "project-host" {
|
||||||
parent = "folders/1234567890"
|
parent = "folders/1234567890"
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
warnings = {
|
warnings = {
|
||||||
destination = module.gcs.as_logging_destination
|
destination = module.gcs.id
|
||||||
filter = "severity=WARNING"
|
filter = "severity=WARNING"
|
||||||
|
type = "storage"
|
||||||
}
|
}
|
||||||
info = {
|
info = {
|
||||||
destination = module.dataset.as_logging_destination
|
destination = module.dataset.id
|
||||||
filter = "severity=INFO"
|
filter = "severity=INFO"
|
||||||
|
type = "bigquery"
|
||||||
}
|
}
|
||||||
notice = {
|
notice = {
|
||||||
destination = module.pubsub.as_logging_destination
|
destination = module.pubsub.id
|
||||||
filter = "severity=NOTICE"
|
filter = "severity=NOTICE"
|
||||||
|
type = "pubsub"
|
||||||
}
|
}
|
||||||
debug = {
|
debug = {
|
||||||
destination = module.bucket.as_logging_destination
|
destination = module.bucket.id
|
||||||
filter = "severity=DEBUG"
|
filter = "severity=DEBUG"
|
||||||
exclusions = {
|
exclusions = {
|
||||||
no-compute = "logName:compute"
|
no-compute = "logName:compute"
|
||||||
}
|
}
|
||||||
|
type = "logging"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logging_exclusions = {
|
logging_exclusions = {
|
||||||
|
@ -357,9 +361,10 @@ module "project-host" {
|
||||||
parent = "folders/1234567890"
|
parent = "folders/1234567890"
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
warnings = {
|
warnings = {
|
||||||
destination = module.gcs.as_logging_destination
|
destination = module.gcs.id
|
||||||
filter = "severity=WARNING"
|
filter = "severity=WARNING"
|
||||||
unique_writer = true
|
unique_writer = true
|
||||||
|
type = "storage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -469,7 +474,7 @@ output "compute_robot" {
|
||||||
|
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [name](variables.tf#L142) | Project name and id suffix. | <code>string</code> | ✓ | |
|
| [name](variables.tf#L140) | Project name and id suffix. | <code>string</code> | ✓ | |
|
||||||
| [auto_create_network](variables.tf#L17) | Whether to create the default network for the project. | <code>bool</code> | | <code>false</code> |
|
| [auto_create_network](variables.tf#L17) | Whether to create the default network for the project. | <code>bool</code> | | <code>false</code> |
|
||||||
| [billing_account](variables.tf#L23) | Billing account id. | <code>string</code> | | <code>null</code> |
|
| [billing_account](variables.tf#L23) | Billing account id. | <code>string</code> | | <code>null</code> |
|
||||||
| [contacts](variables.tf#L29) | 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. | <code>map(list(string))</code> | | <code>{}</code> |
|
| [contacts](variables.tf#L29) | 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. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||||
|
@ -483,25 +488,25 @@ output "compute_robot" {
|
||||||
| [labels](variables.tf#L82) | Resource labels. | <code>map(string)</code> | | <code>{}</code> |
|
| [labels](variables.tf#L82) | Resource labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||||
| [lien_reason](variables.tf#L89) | If non-empty, creates a project lien with this description. | <code>string</code> | | <code>""</code> |
|
| [lien_reason](variables.tf#L89) | If non-empty, creates a project lien with this description. | <code>string</code> | | <code>""</code> |
|
||||||
| [logging_exclusions](variables.tf#L95) | Logging exclusions for this project in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
| [logging_exclusions](variables.tf#L95) | Logging exclusions for this project in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
||||||
| [logging_sinks](variables.tf#L102) | Logging sinks to create for this project. | <code title="map(object({ bq_partitioned_table = optional(bool) description = optional(string) destination = object({ type = string target = string }) disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = string iam = optional(bool, true) unique_writer = optional(bool) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [logging_sinks](variables.tf#L102) | Logging sinks to create for this project. | <code title="map(object({ bq_partitioned_table = optional(bool) description = optional(string) destination = string disabled = optional(bool, false) exclusions = optional(map(string), {}) filter = string iam = optional(bool, true) type = string unique_writer = optional(bool) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [metric_scopes](variables.tf#L135) | List of projects that will act as metric scopes for this project. | <code>list(string)</code> | | <code>[]</code> |
|
| [metric_scopes](variables.tf#L133) | List of projects that will act as metric scopes for this project. | <code>list(string)</code> | | <code>[]</code> |
|
||||||
| [org_policies](variables.tf#L147) | Organization policies applied to this project keyed by policy name. | <code title="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. condition = object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [org_policies](variables.tf#L145) | Organization policies applied to this project keyed by policy name. | <code title="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. condition = object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [org_policies_data_path](variables.tf#L187) | Path containing org policies in YAML format. | <code>string</code> | | <code>null</code> |
|
| [org_policies_data_path](variables.tf#L185) | Path containing org policies in YAML format. | <code>string</code> | | <code>null</code> |
|
||||||
| [oslogin](variables.tf#L193) | Enable OS Login. | <code>bool</code> | | <code>false</code> |
|
| [oslogin](variables.tf#L191) | Enable OS Login. | <code>bool</code> | | <code>false</code> |
|
||||||
| [oslogin_admins](variables.tf#L199) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | <code>list(string)</code> | | <code>[]</code> |
|
| [oslogin_admins](variables.tf#L197) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | <code>list(string)</code> | | <code>[]</code> |
|
||||||
| [oslogin_users](variables.tf#L207) | List of IAM-style identities that will be granted roles necessary for OS Login users. | <code>list(string)</code> | | <code>[]</code> |
|
| [oslogin_users](variables.tf#L205) | List of IAM-style identities that will be granted roles necessary for OS Login users. | <code>list(string)</code> | | <code>[]</code> |
|
||||||
| [parent](variables.tf#L214) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | <code>string</code> | | <code>null</code> |
|
| [parent](variables.tf#L212) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | <code>string</code> | | <code>null</code> |
|
||||||
| [prefix](variables.tf#L224) | Optional prefix used to generate project id and name. | <code>string</code> | | <code>null</code> |
|
| [prefix](variables.tf#L222) | Optional prefix used to generate project id and name. | <code>string</code> | | <code>null</code> |
|
||||||
| [project_create](variables.tf#L234) | Create project. When set to false, uses a data source to reference existing project. | <code>bool</code> | | <code>true</code> |
|
| [project_create](variables.tf#L232) | Create project. When set to false, uses a data source to reference existing project. | <code>bool</code> | | <code>true</code> |
|
||||||
| [service_config](variables.tf#L240) | Configure service API activation. | <code title="object({ disable_on_destroy = bool disable_dependent_services = bool })">object({…})</code> | | <code title="{ disable_on_destroy = false disable_dependent_services = false }">{…}</code> |
|
| [service_config](variables.tf#L238) | Configure service API activation. | <code title="object({ disable_on_destroy = bool disable_dependent_services = bool })">object({…})</code> | | <code title="{ disable_on_destroy = false disable_dependent_services = false }">{…}</code> |
|
||||||
| [service_encryption_key_ids](variables.tf#L252) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
| [service_encryption_key_ids](variables.tf#L250) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||||
| [service_perimeter_bridges](variables.tf#L259) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | <code>list(string)</code> | | <code>null</code> |
|
| [service_perimeter_bridges](variables.tf#L257) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | <code>list(string)</code> | | <code>null</code> |
|
||||||
| [service_perimeter_standard](variables.tf#L266) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | <code>string</code> | | <code>null</code> |
|
| [service_perimeter_standard](variables.tf#L264) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | <code>string</code> | | <code>null</code> |
|
||||||
| [services](variables.tf#L272) | Service APIs to enable. | <code>list(string)</code> | | <code>[]</code> |
|
| [services](variables.tf#L270) | Service APIs to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||||
| [shared_vpc_host_config](variables.tf#L278) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | <code title="object({ enabled = bool service_projects = optional(list(string), []) })">object({…})</code> | | <code>null</code> |
|
| [shared_vpc_host_config](variables.tf#L276) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | <code title="object({ enabled = bool service_projects = optional(list(string), []) })">object({…})</code> | | <code>null</code> |
|
||||||
| [shared_vpc_service_config](variables.tf#L287) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | <code title="object({ host_project = string service_identity_iam = optional(map(list(string))) })">object({…})</code> | | <code>null</code> |
|
| [shared_vpc_service_config](variables.tf#L285) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | <code title="object({ host_project = string service_identity_iam = optional(map(list(string))) })">object({…})</code> | | <code>null</code> |
|
||||||
| [skip_delete](variables.tf#L297) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
|
| [skip_delete](variables.tf#L295) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
|
||||||
| [tag_bindings](variables.tf#L303) | Tag bindings for this project, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
| [tag_bindings](variables.tf#L301) | Tag bindings for this project, in key => tag value id format. | <code>map(string)</code> | | <code>null</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ locals {
|
||||||
for type in ["bigquery", "pubsub", "logging", "storage"] :
|
for type in ["bigquery", "pubsub", "logging", "storage"] :
|
||||||
type => {
|
type => {
|
||||||
for name, sink in var.logging_sinks :
|
for name, sink in var.logging_sinks :
|
||||||
name => sink if sink.iam && sink.destination.type == type
|
name => sink if sink.iam && sink.type == type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ resource "google_logging_project_sink" "sink" {
|
||||||
name = each.key
|
name = each.key
|
||||||
description = coalesce(each.value.description, "${each.key} (Terraform-managed).")
|
description = coalesce(each.value.description, "${each.key} (Terraform-managed).")
|
||||||
project = local.project.project_id
|
project = local.project.project_id
|
||||||
destination = "${each.value.destination.type}.googleapis.com/${each.value.destination.target}"
|
destination = "${each.value.type}.googleapis.com/${each.value.destination}"
|
||||||
filter = each.value.filter
|
filter = each.value.filter
|
||||||
unique_writer_identity = each.value.unique_writer
|
unique_writer_identity = each.value.unique_writer
|
||||||
disabled = each.value.disabled
|
disabled = each.value.disabled
|
||||||
|
@ -60,37 +60,37 @@ resource "google_logging_project_sink" "sink" {
|
||||||
|
|
||||||
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
|
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
|
||||||
for_each = local.sink_bindings["storage"]
|
for_each = local.sink_bindings["storage"]
|
||||||
bucket = each.value.destination.target
|
bucket = each.value.destination
|
||||||
role = "roles/storage.objectCreator"
|
role = "roles/storage.objectCreator"
|
||||||
member = google_logging_project_sink.sink[each.key].writer_identity
|
member = google_logging_project_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
||||||
for_each = local.sink_bindings["bigquery"]
|
for_each = local.sink_bindings["bigquery"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
dataset_id = split("/", each.value.destination.target)[3]
|
dataset_id = split("/", each.value.destination)[3]
|
||||||
role = "roles/bigquery.dataEditor"
|
role = "roles/bigquery.dataEditor"
|
||||||
member = google_logging_project_sink.sink[each.key].writer_identity
|
member = google_logging_project_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
||||||
for_each = local.sink_bindings["pubsub"]
|
for_each = local.sink_bindings["pubsub"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
topic = split("/", each.value.destination.target)[3]
|
topic = split("/", each.value.destination)[3]
|
||||||
role = "roles/pubsub.publisher"
|
role = "roles/pubsub.publisher"
|
||||||
member = google_logging_project_sink.sink[each.key].writer_identity
|
member = google_logging_project_sink.sink[each.key].writer_identity
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "google_project_iam_member" "bucket-sinks-binding" {
|
resource "google_project_iam_member" "bucket-sinks-binding" {
|
||||||
for_each = local.sink_bindings["logging"]
|
for_each = local.sink_bindings["logging"]
|
||||||
project = split("/", each.value.destination.target)[1]
|
project = split("/", each.value.destination)[1]
|
||||||
role = "roles/logging.bucketWriter"
|
role = "roles/logging.bucketWriter"
|
||||||
member = google_logging_project_sink.sink[each.key].writer_identity
|
member = google_logging_project_sink.sink[each.key].writer_identity
|
||||||
|
|
||||||
condition {
|
condition {
|
||||||
title = "${each.key} bucket writer"
|
title = "${each.key} bucket writer"
|
||||||
description = "Grants bucketWriter to ${google_logging_project_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${local.project.project_id}"
|
description = "Grants bucketWriter to ${google_logging_project_sink.sink[each.key].writer_identity} used by log sink ${each.key} on ${local.project.project_id}"
|
||||||
expression = "resource.name.endsWith('${each.value.destination.target}')"
|
expression = "resource.name.endsWith('${each.value.destination}')"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,14 +104,12 @@ variable "logging_sinks" {
|
||||||
type = map(object({
|
type = map(object({
|
||||||
bq_partitioned_table = optional(bool)
|
bq_partitioned_table = optional(bool)
|
||||||
description = optional(string)
|
description = optional(string)
|
||||||
destination = object({
|
destination = string
|
||||||
type = string
|
|
||||||
target = string
|
|
||||||
})
|
|
||||||
disabled = optional(bool, false)
|
disabled = optional(bool, false)
|
||||||
exclusions = optional(map(string), {})
|
exclusions = optional(map(string), {})
|
||||||
filter = string
|
filter = string
|
||||||
iam = optional(bool, true)
|
iam = optional(bool, true)
|
||||||
|
type = string
|
||||||
unique_writer = optional(bool)
|
unique_writer = optional(bool)
|
||||||
}))
|
}))
|
||||||
default = {}
|
default = {}
|
||||||
|
@ -119,16 +117,16 @@ variable "logging_sinks" {
|
||||||
validation {
|
validation {
|
||||||
condition = alltrue([
|
condition = alltrue([
|
||||||
for k, v in var.logging_sinks :
|
for k, v in var.logging_sinks :
|
||||||
contains(["bigquery", "logging", "pubsub", "storage"], v.destination.type)
|
contains(["bigquery", "logging", "pubsub", "storage"], v.type)
|
||||||
])
|
])
|
||||||
error_message = "Destination type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
||||||
}
|
}
|
||||||
validation {
|
validation {
|
||||||
condition = alltrue([
|
condition = alltrue([
|
||||||
for k, v in var.logging_sinks :
|
for k, v in var.logging_sinks :
|
||||||
v.bq_partitioned_table != true || v.destination.type == "bigquery"
|
v.bq_partitioned_table != true || v.type == "bigquery"
|
||||||
])
|
])
|
||||||
error_message = "Can only set bq_partitioned_table when destination type is `bigquery`."
|
error_message = "Can only set bq_partitioned_table when type is `bigquery`."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,6 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
output "as_logging_destination" {
|
|
||||||
description = "Parameters to use this topic as a log sink destination."
|
|
||||||
value = {
|
|
||||||
type = "pubsub"
|
|
||||||
target = google_pubsub_topic.default.id
|
|
||||||
}
|
|
||||||
depends_on = [
|
|
||||||
google_pubsub_topic_iam_binding.default
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
output "id" {
|
output "id" {
|
||||||
description = "Topic id."
|
description = "Topic id."
|
||||||
value = google_pubsub_topic.default.id
|
value = google_pubsub_topic.default.id
|
||||||
|
|
|
@ -1,32 +1,24 @@
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
warning = {
|
warning = {
|
||||||
destination = {
|
destination = "mybucket"
|
||||||
type = "storage"
|
type = "storage"
|
||||||
target = "mybucket"
|
|
||||||
}
|
|
||||||
filter = "severity=WARNING"
|
filter = "severity=WARNING"
|
||||||
}
|
}
|
||||||
info = {
|
info = {
|
||||||
destination = {
|
destination = "projects/myproject/datasets/mydataset"
|
||||||
type = "bigquery"
|
type = "bigquery"
|
||||||
target = "projects/myproject/datasets/mydataset"
|
|
||||||
}
|
|
||||||
filter = "severity=INFO"
|
filter = "severity=INFO"
|
||||||
disabled = true
|
disabled = true
|
||||||
}
|
}
|
||||||
notice = {
|
notice = {
|
||||||
destination = {
|
destination = "projects/myproject/topics/mytopic"
|
||||||
type = "pubsub"
|
type = "pubsub"
|
||||||
target = "projects/myproject/topics/mytopic"
|
|
||||||
}
|
|
||||||
filter = "severity=NOTICE"
|
filter = "severity=NOTICE"
|
||||||
include_children = false
|
include_children = false
|
||||||
}
|
}
|
||||||
debug = {
|
debug = {
|
||||||
destination = {
|
destination = "projects/myproject/locations/global/buckets/mybucket"
|
||||||
type = "logging"
|
type = "logging"
|
||||||
target = "projects/myproject/locations/global/buckets/mybucket"
|
|
||||||
}
|
|
||||||
filter = "severity=DEBUG"
|
filter = "severity=DEBUG"
|
||||||
include_children = false
|
include_children = false
|
||||||
exclusions = {
|
exclusions = {
|
||||||
|
|
|
@ -1,32 +1,24 @@
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
warning = {
|
warning = {
|
||||||
destination = {
|
destination = "mybucket"
|
||||||
type = "storage"
|
type = "storage"
|
||||||
target = "mybucket"
|
|
||||||
}
|
|
||||||
filter = "severity=WARNING"
|
filter = "severity=WARNING"
|
||||||
}
|
}
|
||||||
info = {
|
info = {
|
||||||
destination = {
|
destination = "projects/myproject/datasets/mydataset"
|
||||||
type = "bigquery"
|
type = "bigquery"
|
||||||
target = "projects/myproject/datasets/mydataset"
|
|
||||||
}
|
|
||||||
filter = "severity=INFO"
|
filter = "severity=INFO"
|
||||||
disabled = true
|
disabled = true
|
||||||
}
|
}
|
||||||
notice = {
|
notice = {
|
||||||
destination = {
|
destination = "projects/myproject/topics/mytopic"
|
||||||
type = "pubsub"
|
type = "pubsub"
|
||||||
target = "projects/myproject/topics/mytopic"
|
|
||||||
}
|
|
||||||
filter = "severity=NOTICE"
|
filter = "severity=NOTICE"
|
||||||
include_children = false
|
include_children = false
|
||||||
}
|
}
|
||||||
debug = {
|
debug = {
|
||||||
destination = {
|
destination = "projects/myproject/locations/global/buckets/mybucket"
|
||||||
type = "logging"
|
type = "logging"
|
||||||
target = "projects/myproject/locations/global/buckets/mybucket"
|
|
||||||
}
|
|
||||||
filter = "severity=DEBUG"
|
filter = "severity=DEBUG"
|
||||||
include_children = false
|
include_children = false
|
||||||
exclusions = {
|
exclusions = {
|
||||||
|
|
|
@ -1,32 +1,24 @@
|
||||||
logging_sinks = {
|
logging_sinks = {
|
||||||
warning = {
|
warning = {
|
||||||
destination = {
|
destination = "mybucket"
|
||||||
type = "storage"
|
type = "storage"
|
||||||
target = "mybucket"
|
|
||||||
}
|
|
||||||
filter = "severity=WARNING"
|
filter = "severity=WARNING"
|
||||||
}
|
}
|
||||||
info = {
|
info = {
|
||||||
destination = {
|
destination = "projects/myproject/datasets/mydataset"
|
||||||
type = "bigquery"
|
type = "bigquery"
|
||||||
target = "projects/myproject/datasets/mydataset"
|
|
||||||
}
|
|
||||||
filter = "severity=INFO"
|
filter = "severity=INFO"
|
||||||
disabled = true
|
disabled = true
|
||||||
}
|
}
|
||||||
notice = {
|
notice = {
|
||||||
destination = {
|
destination = "projects/myproject/topics/mytopic"
|
||||||
type = "pubsub"
|
type = "pubsub"
|
||||||
target = "projects/myproject/topics/mytopic"
|
|
||||||
}
|
|
||||||
filter = "severity=NOTICE"
|
filter = "severity=NOTICE"
|
||||||
unique_writer = true
|
unique_writer = true
|
||||||
}
|
}
|
||||||
debug = {
|
debug = {
|
||||||
destination = {
|
destination = "projects/myproject/locations/global/buckets/mybucket"
|
||||||
type = "logging"
|
type = "logging"
|
||||||
target = "projects/myproject/locations/global/buckets/mybucket"
|
|
||||||
}
|
|
||||||
filter = "severity=DEBUG"
|
filter = "severity=DEBUG"
|
||||||
exclusions = {
|
exclusions = {
|
||||||
no-compute = "logName:compute"
|
no-compute = "logName:compute"
|
||||||
|
|
Loading…
Reference in New Issue