Skip to content

Commit ebb3d61

Browse files
feat(cloud_logs): add SNS support (#32)
1 parent ed0c917 commit ebb3d61

File tree

3 files changed

+102
-36
lines changed

3 files changed

+102
-36
lines changed

modules/integrations/cloud-logs/main.tf

+80-35
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
#-----------------------------------------------------------------------------------------------------------------------
2-
# The only resource needed to make Sysdig's backend start to fetch data from the CloudTrail associated s3 bucket is a
3-
# properly set AWS IAM Role. Sysdig's trusted identity act as the Principal in the assume role Policy, namely the role
4-
# that the backend will use to assume the Client's role. At that point, given the permission set granted to the newly
5-
# created Role in the Client's account, Sysdig's backend will be able to perform all the required actions in order to
6-
# retrieve the log files that are automatically published in the target s3 bucket.
2+
# This Terraform module creates the necessary resources to enable Sysdig's backend to fetch data from the
3+
# CloudTrail-associated S3 bucket in the customer's AWS account. The setup includes:
74
#
8-
# Note: this setup assumes that the Customer has already properly set up an AWS CloudTrail Trail and the associated bucket.
9-
# Sysdig's Secure UI provides the necessary information to make the Customer perform the
10-
# required setup operations before applying the Terraform module.
5+
# 1. An AWS IAM Role with the appropriate permissions to allow Sysdig's backend to access the S3 bucket where
6+
# CloudTrail logs are stored. Sysdig's trusted identity is specified as the Principal in the assume role policy,
7+
# enabling the backend to assume the role in the customer account and perform required actions.
8+
#
9+
# 2. An AWS SNS Topic and Subscription for CloudTrail notifications, ensuring Sysdig's backend is notified whenever
10+
# new logs are published to the S3 bucket. The SNS Topic allows CloudTrail to publish notifications, while the
11+
# subscription forwards these notifications to Sysdig's ingestion service via HTTPS.
12+
#
13+
# This setup assumes the customer has already configured an AWS CloudTrail Trail and its associated S3 bucket. The
14+
# required details (e.g., bucket ARN, topic ARN, and regions) are either passed as module variables or derived from
15+
# data sources.
16+
#
17+
# Note: Sysdig's Secure UI provides the necessary information to guide customers in setting up the required resources.
1118
#-----------------------------------------------------------------------------------------------------------------------
1219

1320
#-----------------------------------------------------------------------------------------
@@ -21,14 +28,25 @@ data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
2128

2229
data "sysdig_secure_tenant_external_id" "external_id" {}
2330

31+
data "sysdig_secure_cloud_ingestion_assets" "assets" {
32+
cloud_provider = "aws"
33+
cloud_provider_id = data.aws_caller_identity.current.account_id
34+
}
35+
2436
#-----------------------------------------------------------------------------------------
2537
# Generate a unique name for resources using random suffix and account ID hash
2638
#-----------------------------------------------------------------------------------------
2739
locals {
2840
account_id_hash = substr(md5(data.aws_caller_identity.current.account_id), 0, 4)
29-
role_name = "${var.name}-${random_id.suffix.hex}-${local.account_id_hash}"
30-
bucket_arn = regex("^([^/]+)", var.folder_arn)[0]
31-
trusted_identity = var.is_gov_cloud_onboarding ? data.sysdig_secure_trusted_cloud_identity.trusted_identity.gov_identity : data.sysdig_secure_trusted_cloud_identity.trusted_identity.identity
41+
role_name = "${var.name}-${random_id.suffix.hex}-${local.account_id_hash}"
42+
bucket_arn = regex("^([^/]+)", var.folder_arn)[0]
43+
bucket_name = var.is_gov_cloud_onboarding ? replace(local.bucket_arn, "arn:aws-us-gov:s3:::", "") : replace(local.bucket_arn, "arn:aws:s3:::", "")
44+
bucket_region = data.aws_s3_bucket.cloudtrail_bucket.region
45+
trusted_identity = var.is_gov_cloud_onboarding ? data.sysdig_secure_trusted_cloud_identity.trusted_identity.gov_identity : data.sysdig_secure_trusted_cloud_identity.trusted_identity.identity
46+
47+
topic_name = split(":", var.topic_arn)[5]
48+
routing_key = data.sysdig_secure_cloud_ingestion_assets.assets.aws.sns_routing_key
49+
ingestion_url = data.sysdig_secure_cloud_ingestion_assets.assets.aws.sns_routing_url
3250
}
3351

3452
#-----------------------------------------------------------------------------------------------------------------------
@@ -41,8 +59,8 @@ resource "random_id" "suffix" {
4159

4260
# AWS IAM Role that will be used by CloudIngestion to access the CloudTrail-associated s3 bucket
4361
resource "aws_iam_role" "cloudlogs_s3_access" {
44-
name = local.role_name
45-
tags = var.tags
62+
name = local.role_name
63+
tags = var.tags
4664
assume_role_policy = data.aws_iam_policy_document.assume_cloudlogs_s3_access_role.json
4765
}
4866

@@ -89,40 +107,67 @@ data "aws_iam_policy_document" "cloudlogs_s3_access" {
89107
"${local.bucket_arn}/*"
90108
]
91109
}
110+
}
92111

93-
statement {
94-
sid = "CloudlogsS3AccessList"
112+
# Fetch the S3 bucket information
113+
data "aws_s3_bucket" "cloudtrail_bucket" {
114+
bucket = local.bucket_name
115+
}
95116

96-
effect = "Allow"
117+
#-----------------------------------------------------------------------------------------------------------------------
118+
# SNS Topic and Subscription for CloudTrail notifications
119+
#-----------------------------------------------------------------------------------------------------------------------
120+
resource "aws_sns_topic" "cloudtrail_notifications" {
121+
count = var.create_topic ? 1 : 0
122+
name = local.topic_name
123+
tags = var.tags
124+
}
97125

98-
actions = [
99-
"s3:List*"
126+
resource "aws_sns_topic_policy" "cloudtrail_notifications" {
127+
count = var.create_topic ? 1 : 0
128+
arn = aws_sns_topic.cloudtrail_notifications[0].arn
129+
policy = jsonencode({
130+
Version = "2012-10-17"
131+
Statement = [
132+
{
133+
Sid = "AllowCloudTrailPublish"
134+
Effect = "Allow"
135+
Principal = {
136+
Service = "cloudtrail.amazonaws.com"
137+
}
138+
Action = "SNS:Publish"
139+
Resource = aws_sns_topic.cloudtrail_notifications[0].arn
140+
}
100141
]
142+
})
143+
}
101144

102-
resources = [
103-
local.bucket_arn,
104-
"${local.bucket_arn}/*"
105-
]
106-
}
145+
resource "aws_sns_topic_subscription" "cloudtrail_notifications" {
146+
topic_arn = var.topic_arn
147+
protocol = "https"
148+
endpoint = local.ingestion_url
149+
150+
depends_on = [aws_sns_topic.cloudtrail_notifications]
107151
}
108152

109153
#-----------------------------------------------------------------------------------------------------------------------------------------
110-
# Call Sysdig Backend to add the cloud logs integration to the Sysdig Cloud Account
111-
#
112-
# Note (optional): To ensure this gets called after all cloud resources are created, add
113-
# explicit dependency using depends_on
154+
# Call Sysdig Backend to add the cloud logs integration
114155
#-----------------------------------------------------------------------------------------------------------------------------------------
115156
resource "sysdig_secure_cloud_auth_account_component" "aws_cloud_logs" {
116-
account_id = var.sysdig_secure_account_id
117-
type = "COMPONENT_CLOUD_LOGS"
118-
instance = "secure-runtime"
119-
version = "v0.1.0"
157+
account_id = var.sysdig_secure_account_id
158+
type = "COMPONENT_CLOUD_LOGS"
159+
instance = "secure-runtime"
160+
version = "v1.0.0"
120161
cloud_logs_metadata = jsonencode({
121162
aws = {
122-
cloudtrailS3Bucket = {
123-
folder_arn = var.folder_arn
124-
role_name = local.role_name
125-
regions = var.regions
163+
cloudtrailSns = {
164+
role_name = local.role_name
165+
topic_arn = var.topic_arn
166+
subscription_arn = aws_sns_topic_subscription.cloudtrail_notifications.arn
167+
bucket_region = local.bucket_region
168+
bucket_arn = local.bucket_arn
169+
ingested_regions = var.regions
170+
routing_key = local.routing_key
126171
}
127172
}
128173
})

modules/integrations/cloud-logs/variables.tf

+21
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,24 @@ variable "is_gov_cloud_onboarding" {
3434
default = false
3535
description = "true/false whether secure-for-cloud should be deployed in a govcloud account/org or not"
3636
}
37+
38+
variable "topic_arn" {
39+
type = string
40+
description = "SNS Topic ARN that will forward CloudTrail notifications to Sysdig Secure"
41+
42+
validation {
43+
condition = var.topic_arn != ""
44+
error_message = "Topic ARN must not be empty"
45+
}
46+
47+
validation {
48+
condition = can(regex("^arn:(aws|aws-us-gov):sns:[a-z0-9-]+:[0-9]+:.+$", var.topic_arn))
49+
error_message = "Topic ARN must be a valid SNS ARN format"
50+
}
51+
}
52+
53+
variable "create_topic" {
54+
type = bool
55+
default = false
56+
description = "true/false whether terraform should create the SNS Topic"
57+
}

modules/integrations/cloud-logs/versions.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ terraform {
88
}
99
sysdig = {
1010
source = "sysdiglabs/sysdig"
11-
version = "~> 1.39"
11+
version = "~> 1.44"
1212
}
1313
random = {
1414
source = "hashicorp/random"

0 commit comments

Comments
 (0)