Fix IAM bindings for logging sinks

- Move to non-authoritative bindings to allow multiple sinks to write to
  the same destination
- Allow automatically adding logging bucket IAM bindings
This commit is contained in:
Julio Castillo 2021-03-31 09:57:23 +02:00
parent 37935cee3a
commit 94b1a439ee
10 changed files with 54 additions and 26 deletions

1
.gitignore vendored
View File

@ -15,3 +15,4 @@ credentials.json
key.json
terraform-ls.tf
bundle.zip
.DS_Store

View File

@ -186,5 +186,5 @@ module "folder2" {
| folder | Folder resource. | |
| id | Folder id. | |
| name | Folder name. | |
| sink_writer_identities | None | |
| sink_writer_identities | Writer identities created for each sink | |
<!-- END TFDOC -->

View File

@ -202,27 +202,36 @@ resource "google_logging_folder_sink" "sink" {
}
}
resource "google_storage_bucket_iam_binding" "gcs-sinks-binding" {
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
for_each = local.sink_bindings["gcs"]
bucket = each.value.destination
role = "roles/storage.objectCreator"
members = [google_logging_folder_sink.sink[each.key].writer_identity]
member = google_logging_folder_sink.sink[each.key].writer_identity
}
resource "google_bigquery_dataset_iam_binding" "bq-sinks-binding" {
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
for_each = local.sink_bindings["bigquery"]
project = split("/", each.value.destination)[1]
dataset_id = split("/", each.value.destination)[3]
role = "roles/bigquery.dataEditor"
members = [google_logging_folder_sink.sink[each.key].writer_identity]
member = google_logging_folder_sink.sink[each.key].writer_identity
}
resource "google_pubsub_topic_iam_binding" "pubsub-sinks-binding" {
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
for_each = local.sink_bindings["pubsub"]
project = split("/", each.value.destination)[1]
topic = split("/", each.value.destination)[3]
role = "roles/pubsub.publisher"
members = [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" {
for_each = local.sink_bindings["logging"]
project = split("/", each.value.destination)[1]
role = "roles/logging.bucketWriter"
member = google_logging_folder_sink.sink[each.key].writer_identity
# TODO(jccb): use a condition to limit writer-identity only to this
# bucket
}
resource "google_logging_folder_exclusion" "logging-exclusion" {

View File

@ -51,7 +51,7 @@ output "firewall_policy_id" {
}
output "sink_writer_identities" {
description = ""
description = "Writer identities created for each sink."
value = {
for name, sink in google_logging_folder_sink.sink : name => sink.writer_identity
}

View File

@ -163,5 +163,5 @@ module "org" {
| firewall_policies | Map of firewall policy resources created in the organization. | |
| firewall_policy_id | Map of firewall policy ids created in the organization. | |
| organization_id | Organization id dependent on module resources. | |
| sink_writer_identities | None | |
| sink_writer_identities | Writer identities created for each sink | |
<!-- END TFDOC -->

View File

@ -286,27 +286,36 @@ resource "google_logging_organization_sink" "sink" {
}
}
resource "google_storage_bucket_iam_binding" "gcs-sinks-binding" {
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
for_each = local.sink_bindings["gcs"]
bucket = each.value.destination
role = "roles/storage.objectCreator"
members = [google_logging_organization_sink.sink[each.key].writer_identity]
member = google_logging_organization_sink.sink[each.key].writer_identity
}
resource "google_bigquery_dataset_iam_binding" "bq-sinks-binding" {
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
for_each = local.sink_bindings["bigquery"]
project = split("/", each.value.destination)[1]
dataset_id = split("/", each.value.destination)[3]
role = "roles/bigquery.dataEditor"
members = [google_logging_organization_sink.sink[each.key].writer_identity]
member = google_logging_organization_sink.sink[each.key].writer_identity
}
resource "google_pubsub_topic_iam_binding" "pubsub-sinks-binding" {
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
for_each = local.sink_bindings["pubsub"]
project = split("/", each.value.destination)[1]
topic = split("/", each.value.destination)[3]
role = "roles/pubsub.publisher"
members = [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" {
for_each = local.sink_bindings["logging"]
project = split("/", each.value.destination)[1]
role = "roles/logging.bucketWriter"
member = google_logging_organization_sink.sink[each.key].writer_identity
# TODO(jccb): use a condition to limit writer-identity only to this
# bucket
}
resource "google_logging_organization_exclusion" "logging-exclusion" {

View File

@ -45,7 +45,7 @@ output "firewall_policy_id" {
}
output "sink_writer_identities" {
description = ""
description = "Writer identities created for each sink."
value = {
for name, sink in google_logging_organization_sink.sink : name => sink.writer_identity
}

View File

@ -191,6 +191,6 @@ module "project-host" {
| number | Project number. | |
| project_id | Project id. | |
| service_accounts | Product robot service accounts in project. | |
| sink_writer_identities | None | |
| sink_writer_identities | Writer identities created for each sink | |
<!-- END TFDOC -->

View File

@ -277,27 +277,36 @@ resource "google_logging_project_sink" "sink" {
}
}
resource "google_storage_bucket_iam_binding" "gcs-sinks-binding" {
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
for_each = local.sink_bindings["gcs"]
bucket = each.value.destination
role = "roles/storage.objectCreator"
members = [google_logging_project_sink.sink[each.key].writer_identity]
member = google_logging_project_sink.sink[each.key].writer_identity
}
resource "google_bigquery_dataset_iam_binding" "bq-sinks-binding" {
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
for_each = local.sink_bindings["bigquery"]
project = split("/", each.value.destination)[1]
dataset_id = split("/", each.value.destination)[3]
role = "roles/bigquery.dataEditor"
members = [google_logging_project_sink.sink[each.key].writer_identity]
member = google_logging_project_sink.sink[each.key].writer_identity
}
resource "google_pubsub_topic_iam_binding" "pubsub-sinks-binding" {
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
for_each = local.sink_bindings["pubsub"]
project = split("/", each.value.destination)[1]
topic = split("/", each.value.destination)[3]
role = "roles/pubsub.publisher"
members = [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" {
for_each = local.sink_bindings["logging"]
project = split("/", each.value.destination)[1]
role = "roles/logging.bucketWriter"
member = google_logging_project_sink.sink[each.key].writer_identity
# TODO(jccb): use a condition to limit writer-identity only to this
# bucket
}
resource "google_logging_project_exclusion" "logging-exclusion" {
@ -318,7 +327,7 @@ resource "google_essential_contacts_contact" "contact" {
}
resource "google_access_context_manager_service_perimeter_resource" "service-perimeter-resource-standard" {
count = var.service_perimeter_standard != null ? 1 : 0
count = var.service_perimeter_standard != null ? 1 : 0
# If used, remember to uncomment 'lifecycle' block in the
# modules/vpc-sc/google_access_context_manager_service_perimeter resource.
@ -327,7 +336,7 @@ resource "google_access_context_manager_service_perimeter_resource" "service-per
}
resource "google_access_context_manager_service_perimeter_resource" "service-perimeter-resource-bridges" {
for_each = toset(var.service_perimeter_bridges != null ? var.service_perimeter_bridges : [])
for_each = toset(var.service_perimeter_bridges != null ? var.service_perimeter_bridges : [])
# If used, remember to uncomment 'lifecycle' block in the
# modules/vpc-sc/google_access_context_manager_service_perimeter resource.

View File

@ -68,7 +68,7 @@ output "custom_roles" {
}
output "sink_writer_identities" {
description = ""
description = "Writer identities created for each sink."
value = {
for name, sink in google_logging_project_sink.sink : name => sink.writer_identity
}