Skip to content

Commit da48684

Browse files
authored
Implement Organizational CloudLogs module (#7)
* First implementation draft * Enable AuditLogs for org case, refactor * Create organizational template file and refactor * Remove unnecessary output declaration * Update documentation for the organizational case * Remove unused google_project declaration * Update README files * Use organization domain instead of organization id as module input
1 parent d4b087d commit da48684

File tree

6 files changed

+105
-47
lines changed

6 files changed

+105
-47
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Provides unified threat-detection, compliance, forensics and analysis through th
88

99
* **[CIEM](https://docs.sysdig.com/en/docs/sysdig-secure/posture/identity-and-access/)**: Permissions and Entitlements management. Managed through `service-principal` module. <br/>
1010

11-
* **CDR (Cloud Detection and Response)**: It send periodically the Audit Logs collected from a GCP project to Sysdig's systems, this by collecting them in a PubSub topic through a Sink and then sending them through a `PUSH` integration. Managed through `webhook-datasource` module. <br/>
11+
* **CDR (Cloud Detection and Response)**: It sends periodically the Audit Logs collected from a GCP project/organization to Sysdig's systems, this by collecting them in a PubSub topic through a Sink and then sending them through a `PUSH` integration. Managed through `webhook-datasource` module. <br/>
1212

1313
For other Cloud providers check: [AWS](https://github.com/draios/terraform-aws-secure-for-cloud)
1414

modules/services/webhook-datasource/README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# GCP Webhook Datasource Module
22

3-
This Module creates the resources required to send Project-specific AuditLogs to Sysdig by creating a dedicated Push Subscription tied to a ingestion PubSub topic.
3+
This Module creates the resources required to send Project or Organization-specific AuditLogs to Sysdig by creating a dedicated Push Subscription tied to a ingestion PubSub topic.
44

55

66
The following resources will be created in each instrumented account:
7-
- A Sink to direct the AuditLogs towards a dedicated PubSub topic
8-
- A PubSub ingestion topic that will hold all the AuditLogs coming from the specified project
9-
- A Push Subscription that will POST the AuditLogs collected from the project towards Sysdig's backend
10-
- All the necessary Service Accounts and Policies to enable the AuditLogs publishing operation
7+
- A Project/Organization `Sink` to direct the AuditLogs towards a dedicated PubSub topic
8+
- A `PubSub` ingestion topic that will hold all the AuditLogs coming from the specified project
9+
- A `Push` Subscription that will POST the AuditLogs collected from the project towards Sysdig's backend
10+
- All the necessary `Service Accounts` and `Policies` to enable the `AuditLogs` publishing operation
1111

1212
## Requirements
1313

@@ -20,7 +20,7 @@ The following resources will be created in each instrumented account:
2020

2121
| Name | Version |
2222
|------|---------|
23-
| <a name="provider_google"></a> [google](#provider\_google) | >= 4.21.0 |
23+
| <a name="provider_google"></a> [google](#provider\_google) | 5.0.0 |
2424

2525
## Modules
2626

@@ -30,32 +30,35 @@ No modules.
3030

3131
| Name | Type |
3232
|------|------|
33+
| [google_logging_organization_sink.ingestion_sink](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/logging_organization_sink) | resource |
3334
| [google_logging_project_sink.ingestion_sink](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/logging_project_sink) | resource |
35+
| [google_organization_iam_audit_config.audit_config](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/organization_iam_audit_config) | resource |
3436
| [google_project_iam_audit_config.audit_config](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_audit_config) | resource |
3537
| [google_pubsub_subscription.ingestion_topic_push_subscription](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_subscription) | resource |
3638
| [google_pubsub_topic.deadletter_topic](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic) | resource |
3739
| [google_pubsub_topic.ingestion_topic](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic) | resource |
3840
| [google_pubsub_topic_iam_member.publisher_iam_member](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/pubsub_topic_iam_member) | resource |
3941
| [google_service_account.push_auth](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource |
4042
| [google_service_account_iam_binding.push_auth_binding](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_binding) | resource |
43+
| [google_organization.org](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/organization) | data source |
4144

4245
## Inputs
4346

4447
| Name | Description | Type | Default | Required |
4548
|------|-------------|------|---------|:--------:|
4649
| <a name="input_ack_deadline_seconds"></a> [ack\_deadline\_seconds](#input\_ack\_deadline\_seconds) | (Optional) Maximum time in seconds after Sysdig's subscriber receives a message before the subscriber should acknowledge the message | `number` | `60` | no |
47-
| <a name="input_labels"></a> [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` | <pre>{<br> "originator": "Sysdig"<br>}</pre> | no |
50+
| <a name="input_is_organizational"></a> [is\_organizational](#input\_is\_organizational) | (Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization. | `bool` | `false` | no |
51+
| <a name="input_labels"></a> [labels](#input\_labels) | (Optional) Labels to be associated with Sysdig-originated resources | `map(string)` | <pre>{<br> "originator": "sysdig"<br>}</pre> | no |
4852
| <a name="input_max_delivery_attempts"></a> [max\_delivery\_attempts](#input\_max\_delivery\_attempts) | (Optional) Number of attempts redelivering missed messages from the deadletter topic to the main one | `number` | `5` | no |
4953
| <a name="input_maximum_backoff"></a> [maximum\_backoff](#input\_maximum\_backoff) | (Optional) Maximum backoff time for exponential backoff of the push subscription retry policy | `string` | `"600s"` | no |
5054
| <a name="input_message_retention_duration"></a> [message\_retention\_duration](#input\_message\_retention\_duration) | (Optional) How long unacknowledged messages are retained in Sysdig's subscription backlog, from the moment a message is published | `string` | `"604800s"` | no |
5155
| <a name="input_minimum_backoff"></a> [minimum\_backoff](#input\_minimum\_backoff) | (Optional) Minimum backoff time for exponential backoff of the push subscription retry policy | `string` | `"10s"` | no |
56+
| <a name="input_organization_domain"></a> [organization\_domain](#input\_organization\_domain) | Organization domain. e.g. sysdig.com | `string` | `""` | no |
5257
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | (Required) Target Project identifier provided by the customer | `string` | n/a | yes |
5358
| <a name="input_push_endpoint"></a> [push\_endpoint](#input\_push\_endpoint) | (Required) Final endpoint towards which audit logs POST calls will be directed | `string` | n/a | yes |
5459

5560
## Outputs
5661

5762
| Name | Description |
5863
|------|-------------|
59-
| <a name="output_project_id"></a> [project\_id](#output\_project\_id) | GCP Project Identifier |
6064
| <a name="output_push_endpoint"></a> [push\_endpoint](#output\_push\_endpoint) | Push endpoint towards which the POST request will be directed |
61-
| <a name="output_push_subscription_service_account"></a> [push\_subscription\_service\_account](#output\_push\_subscription\_service\_account) | Service Account used to send POST messages, a KMS key needs to be manually added in order to properly authenticate the requests at Sysdig's side |

modules/services/webhook-datasource/main.tf

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,20 @@
1616
# Subscription that will send the data to Sysdig's backend. This module takes also care
1717
# of creating the necessary service accounts along with the necessary policies to enable
1818
# pushing logs to Sysdig's system.
19+
#
20+
# Note: The alternative definitions for the organizational variant of this module are contained
21+
# in organizational.tf. The only differences w.r.t. the standalone template is in using an
22+
# organizational sink instead of a project-specific one, as well as enabling AuditLogs for
23+
# all the projects that fall within the organization.
1924
########################################################################################
2025

21-
#-------------#
22-
# GCP Project #
23-
#-------------#
24-
25-
data "google_project" "target_project" {
26-
project_id = var.project_id
27-
}
28-
2926
#------------#
3027
# Audit Logs #
3128
#------------#
3229

3330
resource "google_project_iam_audit_config" "audit_config" {
31+
count = var.is_organizational ? 0 : 1
32+
3433
project = var.project_id
3534
service = "allServices"
3635

@@ -47,11 +46,31 @@ resource "google_project_iam_audit_config" "audit_config" {
4746
}
4847
}
4948

49+
#-----------------#
50+
# Ingestion topic #
51+
#-----------------#
52+
53+
resource "google_pubsub_topic" "ingestion_topic" {
54+
name = "ingestion_topic"
55+
labels = var.labels
56+
project = var.project_id
57+
message_retention_duration = var.message_retention_duration
58+
}
59+
60+
resource "google_pubsub_topic" "deadletter_topic" {
61+
name = "dl-${google_pubsub_topic.ingestion_topic.name}"
62+
63+
project = var.project_id
64+
message_retention_duration = var.message_retention_duration
65+
}
66+
5067
#------#
5168
# Sink #
5269
#------#
5370

5471
resource "google_logging_project_sink" "ingestion_sink" {
72+
count = var.is_organizational ? 0 : 1
73+
5574
name = "${google_pubsub_topic.ingestion_topic.name}_sink"
5675
description = "Sysdig sink to direct the AuditLogs to the PubSub topic used for data gathering"
5776

@@ -68,25 +87,7 @@ resource "google_pubsub_topic_iam_member" "publisher_iam_member" {
6887
project = google_pubsub_topic.ingestion_topic.project
6988
topic = google_pubsub_topic.ingestion_topic.name
7089
role = "roles/pubsub.publisher"
71-
member = google_logging_project_sink.ingestion_sink.writer_identity
72-
}
73-
74-
#-----------------#
75-
# Ingestion topic #
76-
#-----------------#
77-
78-
resource "google_pubsub_topic" "ingestion_topic" {
79-
name = "ingestion_topic"
80-
labels = var.labels
81-
project = var.project_id
82-
message_retention_duration = var.message_retention_duration
83-
}
84-
85-
resource "google_pubsub_topic" "deadletter_topic" {
86-
name = "dl-${google_pubsub_topic.ingestion_topic.name}"
87-
88-
project = var.project_id
89-
message_retention_duration = var.message_retention_duration
90+
member = var.is_organizational ? google_logging_organization_sink.ingestion_sink[0].writer_identity : google_logging_project_sink.ingestion_sink[0].writer_identity
9091
}
9192

9293
#-------------------#
@@ -96,6 +97,7 @@ resource "google_pubsub_topic" "deadletter_topic" {
9697
resource "google_service_account" "push_auth" {
9798
account_id = "ingestion-topic-push-auth"
9899
display_name = "Push Auth Service Account"
100+
project = var.project_id
99101
}
100102

101103
resource "google_service_account_iam_binding" "push_auth_binding" {
@@ -113,6 +115,7 @@ resource "google_pubsub_subscription" "ingestion_topic_push_subscription" {
113115
labels = var.labels
114116
ack_deadline_seconds = var.ack_deadline_seconds
115117
message_retention_duration = var.message_retention_duration
118+
project = var.project_id
116119

117120
push_config {
118121
push_endpoint = var.push_endpoint
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#--------------#
2+
# Organization #
3+
#--------------#
4+
5+
data "google_organization" "org" {
6+
count = var.is_organizational ? 1 : 0
7+
domain = var.organization_domain
8+
}
9+
10+
#------------#
11+
# Audit Logs #
12+
#------------#
13+
resource "google_organization_iam_audit_config" "audit_config" {
14+
count = var.is_organizational ? 1 : 0
15+
16+
org_id = data.google_organization.org[0].org_id
17+
service = "allServices"
18+
19+
audit_log_config {
20+
log_type = "ADMIN_READ"
21+
}
22+
23+
audit_log_config {
24+
log_type = "DATA_READ"
25+
}
26+
27+
audit_log_config {
28+
log_type = "DATA_WRITE"
29+
}
30+
}
31+
32+
#------#
33+
# Sink #
34+
#------#
35+
36+
resource "google_logging_organization_sink" "ingestion_sink" {
37+
count = var.is_organizational ? 1 : 0
38+
39+
name = "${google_pubsub_topic.ingestion_topic.name}_sink"
40+
description = "Sysdig sink to direct the AuditLogs to the PubSub topic used for data gathering"
41+
org_id = data.google_organization.org[0].org_id
42+
43+
# NOTE: The target destination is a PubSub topic
44+
destination = "pubsub.googleapis.com/projects/${var.project_id}/topics/${google_pubsub_topic.ingestion_topic.name}"
45+
filter = "protoPayload.@type = \"type.googleapis.com/google.cloud.audit.AuditLog\""
46+
47+
# NOTE: The include_children attribute is set to true in order to ingest data
48+
# even from potential sub-organizations
49+
include_children = true
50+
}

modules/services/webhook-datasource/outputs.tf

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
1-
output "project_id" {
2-
value = data.google_project.target_project.id
3-
description = "GCP Project Identifier"
4-
}
5-
6-
output "push_subscription_service_account" {
7-
value = google_service_account.push_auth.name
8-
description = "Service Account used to send POST messages, a KMS key needs to be manually added in order to properly authenticate the requests at Sysdig's side"
9-
}
10-
111
output "push_endpoint" {
122
value = google_pubsub_subscription.ingestion_topic_push_subscription.push_config[0].push_endpoint
133
description = "Push endpoint towards which the POST request will be directed"

modules/services/webhook-datasource/variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,15 @@ variable "maximum_backoff" {
4545
description = "(Optional) Maximum backoff time for exponential backoff of the push subscription retry policy"
4646
default = "600s"
4747
}
48+
49+
variable "is_organizational" {
50+
description = "(Optional) Set this field to 'true' to deploy secure-for-cloud to a GCP Organization."
51+
type = bool
52+
default = false
53+
}
54+
55+
variable "organization_domain" {
56+
type = string
57+
description = "(Optional) Organization domain. e.g. sysdig.com"
58+
default = ""
59+
}

0 commit comments

Comments
 (0)