diff --git a/main.tf b/main.tf index 69880f3..cb06d19 100644 --- a/main.tf +++ b/main.tf @@ -4,11 +4,22 @@ locals { sink_name = length(var.existing_sink_name) > 0 ? var.existing_sink_name : ( local.org_integration ? "${var.prefix}-${var.organization_id}-lacework-sink-${random_id.uniq.hex}" : "${var.prefix}-lacework-sink-${random_id.uniq.hex}" ) + + exclude_folders = length(var.folders_to_exclude) != 0 + explicit_folders = length(var.folders_to_include) != 0 + logging_sink_writer_identity = length(var.existing_sink_name) > 0 ? ["serviceAccount:${local.service_account_json_key.client_email}"] : ( - (local.org_integration) ? ( + (local.org_integration && !(local.exclude_folders || local.explicit_folders)) ? ( [google_logging_organization_sink.lacework_organization_sink[0].writer_identity] ) : ( - [google_logging_project_sink.lacework_project_sink[0].writer_identity] + (local.org_integration && (local.exclude_folders || local.explicit_folders)) ? ( + concat( + [for v in google_logging_folder_sink.lacework_folder_sink : v.writer_identity], + [for v in google_logging_project_sink.lacework_root_project_sink : v.writer_identity] + ) + ) : ( + [google_logging_project_sink.lacework_project_sink[0].writer_identity] + ) ) ) @@ -42,6 +53,25 @@ locals { ) ) + folders = [ + (local.org_integration && local.exclude_folders) ? ( + setsubtract(data.google_folders.my-org-folders[0].folders[*].name, var.folders_to_exclude) + ) : ( + local.org_integration && local.explicit_folders) ? ( + var.folders_to_include + ) : ( + toset([]) + ) + ] + + root_projects = [ + (local.org_integration && local.exclude_folders && var.include_root_projects) ? ( + toset(data.google_projects.my-org-projects[0].projects[*].project_id) + ) : ( + toset([]) + ) + ] + version_file = "${abspath(path.module)}/VERSION" module_name = "terraform-gcp-pub-sub-audit-log" module_version = fileexists(local.version_file) ? file(local.version_file) : "" @@ -55,6 +85,11 @@ data "google_project" "selected" { count = length(var.project_id) > 0 ? 0 : 1 } +data "google_folders" "my-org-folders" { + count = (local.org_integration && local.exclude_folders) ? 1 : 0 + parent_id = "organizations/${var.organization_id}" +} + resource "google_project_service" "required_apis" { for_each = var.required_apis project = local.project_id @@ -108,8 +143,29 @@ resource "google_logging_project_sink" "lacework_project_sink" { depends_on = [google_pubsub_topic.lacework_topic] } +resource "google_logging_project_sink" "lacework_root_project_sink" { + for_each = local.root_projects[0] + project = each.value + name = local.sink_name + destination = "pubsub.googleapis.com/${google_pubsub_topic.lacework_topic.id}" + unique_writer_identity = true + + filter = local.log_filter + depends_on = [google_pubsub_topic.lacework_topic] +} + +resource "google_logging_folder_sink" "lacework_folder_sink" { + for_each = local.folders[0] + name = local.sink_name + folder = each.value + destination = "pubsub.googleapis.com/${google_pubsub_topic.lacework_topic.id}" + include_children = true + + filter = local.log_filter +} + resource "google_logging_organization_sink" "lacework_organization_sink" { - count = length(var.existing_sink_name) > 0 ? 0 : ((local.org_integration) ? 1 : 0) + count = length(var.existing_sink_name) > 0 ? 0 : ((local.org_integration && !(local.exclude_folders || local.explicit_folders) ? 1 : 0)) name = local.sink_name org_id = var.organization_id destination = "pubsub.googleapis.com/${google_pubsub_topic.lacework_topic.id}" diff --git a/variables.tf b/variables.tf index a5d4568..766d983 100644 --- a/variables.tf +++ b/variables.tf @@ -13,7 +13,7 @@ variable "integration_type" { default = "PROJECT" description = "Specify the integration type. Can only be PROJECT or ORGANIZATION. Defaults to PROJECT" validation { - condition = contains(["PROJECT", "ORGANIZATION"], var.integration_type) + condition = contains(["PROJECT", "ORGANIZATION"], var.integration_type) error_message = "The integration_type must be either PROJECT or ORGANIZATION." } } @@ -114,5 +114,23 @@ variable "google_workspace_filter" { variable "custom_filter" { type = string default = "" - description = "Customer defined Audit Log filter which will supersede all other filter options when defined" + description = "Customer defined Audit Log filter which will supersede all other filter options when defined" +} + +variable "folders_to_include" { + type = set(string) + default = [] + description = "List of root folders to include in an organization-level integration. Format is 'folders/1234567890'" +} + +variable "folders_to_exclude" { + type = list(string) + default = [] + description = "List of root folders to exclude in an organization-level integration. Format is 'folders/1234567890'" +} + +variable "include_root_projects" { + type = bool + default = true + description = "Enables logic to include root-level projects if excluding folders. Default is true" }