diff --git a/modules/integrations/cloud-logs/README.md b/modules/integrations/cloud-logs/README.md index ce400bf..33182ba 100644 --- a/modules/integrations/cloud-logs/README.md +++ b/modules/integrations/cloud-logs/README.md @@ -3,12 +3,36 @@ This Module creates the resources required to send CloudTrail logs to Sysdig by enabling access to the CloudTrail associated s3 bucket through a dedicated IAM role. -The following resources will be created in each instrumented account: +The following resources will be created based on the deployment scenario: -- An IAM Role and associated policies that gives the ingestion component in Sysdig's account permission to list and - retrieve items from it. +1. For single-account deployments: + - An IAM Role in the account with permissions to access the S3 bucket directly + - SNS Topic and Subscription for CloudTrail notifications -If instrumenting an AWS Gov account/organization, resources will be created in `aws-us-gov` region. +2. For organizational deployments (same account): + - An IAM Role in the management account with permissions to access the S3 bucket directly + - SNS Topic and Subscription for CloudTrail notifications + +3. For organizational cross-account deployments: + - A CloudFormation StackSet that deploys an IAM role directly in the bucket account + - The role in the bucket account allows Sysdig to access S3 data directly + - SNS Topic and Subscription for CloudTrail notifications + +Additional features include: +- Support for KMS-encrypted S3 buckets by granting the necessary KMS decryption permissions +- Support for AWS GovCloud deployments + +## Important Notes for Cross-Account Access + +When using this module with organizational cross-account access (where CloudTrail bucket is in a different AWS account), the module automatically deploys a StackSet to configure the role in the bucket account. +The StackSet deployment requires appropriate permissions in the organization. The deploying account must have permission to create and manage StackSets in the organization. + +### Working with KMS-encrypted S3 buckets + +For KMS-encrypted S3 buckets, this module configures the necessary decrypt permissions on the IAM role. When using KMS encryption: +1. Provide the KMS key ARN using the `kms_key_arn` variable +2. For cross-account scenarios, specify the bucket account ID using the `bucket_account_id` variable +3. Ensure the KMS key policy allows the created role to use the decrypt operation @@ -18,14 +42,16 @@ If instrumenting an AWS Gov account/organization, resources will be created in ` |---------------------------------------------------------------------------|-----------| | [terraform](#requirement\_terraform) | >= 1.0.0 | | [aws](#requirement\_aws) | >= 5.60.0 | -| [sysdig](#requirement\_sysdig) | ~>1.48 | +| [sysdig](#requirement\_sysdig) | ~>1.52 | | [random](#requirement\_random) | >= 3.1 | ## Providers -| Name | Version | -|---------------------------------------------------|-----------| -| [aws](#provider\_aws) | >= 5.60.0 | +| Name | Version | +|-------------------------------------------------------------|-----------| +| [aws](#provider\_aws) | >= 5.60.0 | +| [sysdig](#provider\_sysdig) | ~>1.52 | +| [random](#provider\_random) | >= 3.1 | ## Modules @@ -38,11 +64,18 @@ No modules. | [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | | [aws_iam_role.cloudlogs_s3_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role_policy.cloudlogs_s3_access_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | +| [aws_sns_topic.cloudtrail_notifications](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | +| [aws_sns_topic_policy.cloudtrail_notifications](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource | +| [aws_sns_topic_subscription.cloudtrail_notifications](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource | +| [aws_cloudformation_stack_set.cloudlogs_s3_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack_set) | resource | +| [aws_cloudformation_stack_set_instance.cloudlogs_s3_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack_set_instance) | resource | | [aws_iam_policy_document.assume_cloudlogs_s3_access_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.cloudlogs_s3_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | | [sysdig_secure_trusted_cloud_identity.trusted_identity](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_trusted_cloud_identity) | data source | | [sysdig_secure_tenant_external_id.external_id](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_tenant_external_id) | data source | +| [sysdig_secure_cloud_ingestion_assets.assets](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/data-sources/secure_cloud_ingestion_assets) | data source | | [sysdig_secure_cloud_auth_account_component.aws_cloud_logs](https://registry.terraform.io/providers/sysdiglabs/sysdig/latest/docs/resources/secure_cloud_auth_account_component) | resource | ## Inputs @@ -50,17 +83,24 @@ No modules. | Name | Description | Type | Default | Required | |------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------------|:--------:| | [sysdig\_secure\_account\_id](#input\_sysdig\_secure\_account\_id) | (Required) ID of the Sysdig Cloud Account to enable Cloud Logs integration for (in case of organization, ID of the Sysdig management account) | `string` | n/a | yes | -| [folder\_arn](#input\_folder\_arn) | (Required) The ARN of your CloudTrail Bucket Folder | `string` | n/a | yes | -| [tags](#input\_tags) | (Optional) Name to be assigned to all child resources. A suffix may be added internally when required. | `map(string)` |
{
"product": "sysdig-secure-for-cloud"
} | no |
-| [name](#input\_name) | (Optional) Sysdig secure-for-cloud tags. always include 'product' default tag for resource-group proper functioning | `string` | sysdig-secure-cloudlogs | no |
+| [bucket\_arn](#input\_bucket\_arn) | (Required) The ARN of your CloudTrail Bucket | `string` | n/a | yes |
+| [topic\_arn](#input\_topic\_arn) | SNS Topic ARN that will forward CloudTrail notifications to Sysdig Secure | `string` | n/a | yes |
+| [create\_topic](#input\_create\_topic) | true/false whether terraform should create the SNS Topic | `bool` | `false` | no |
+| [kms\_key\_arn](#input\_kms\_key\_arn) | (Optional) ARN of the KMS key used to encrypt the S3 bucket. If provided, the IAM role will be granted permissions to decrypt using this key. | `string` | `null` | no |
+| [bucket\_account\_id](#input\_bucket\_account\_id) | (Optional) AWS Account ID that owns the S3 bucket, if different from the account where the module is being applied. Required for cross-account organizational deployments. | `string` | `null` | no |
+| [tags](#input\_tags) | (Optional) Sysdig secure-for-cloud tags. always include 'product' default tag for resource-group proper functioning | `map(string)` | {
"product": "sysdig-secure-for-cloud"
} | no |
+| [name](#input\_name) | (Optional) Name to be assigned to all child resources. A suffix may be added internally when required. | `string` | sysdig-secure-cloudlogs | no |
| [regions](#input\_regions) | (Optional) The list of AWS regions we want to scrape data from | `set(string)` | `[]` | no |
| [is\_gov\_cloud](#input\_is\_gov\_cloud\_onboarding) | true/false whether secure-for-cloud should be deployed in a govcloud account/org or not | `bool` | `false` | no |
+| [org\_units](#input\_org\_units) | (Optional) List of AWS Organizations organizational unit (OU) IDs in which to create the StackSet instances. Required for cross-account organizational deployments. | `list(string)` | `[]` | no |
+| [timeout](#input\_timeout) | (Optional) The timeout for StackSet operations | `string` | `"30m"` | no |
## Outputs
| Name | Description |
|-----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| [cloud\_logs\_component\_id](#output\_cloud\_logs\_component\_id) | Component identifier of Cloud Logs integration created in Sysdig Backend for Log Ingestion |
+| [kms\_policy\_instructions](#output\_kms\_policy\_instructions) | Instructions for updating KMS key policy when KMS encryption is enabled |
diff --git a/modules/integrations/cloud-logs/main.tf b/modules/integrations/cloud-logs/main.tf
index 4c821a2..2b01d2b 100644
--- a/modules/integrations/cloud-logs/main.tf
+++ b/modules/integrations/cloud-logs/main.tf
@@ -2,19 +2,22 @@
# This Terraform module creates the necessary resources to enable Sysdig's backend to fetch data from the
# CloudTrail-associated S3 bucket in the customer's AWS account. The setup includes:
#
-# 1. An AWS IAM Role with the appropriate permissions to allow Sysdig's backend to access the S3 bucket where
-# CloudTrail logs are stored. Sysdig's trusted identity is specified as the Principal in the assume role policy,
-# enabling the backend to assume the role in the customer account and perform required actions.
+# 1. For single-account deployments:
+# - An AWS IAM Role in the account with permissions to access the S3 bucket directly
#
-# 2. An AWS SNS Topic and Subscription for CloudTrail notifications, ensuring Sysdig's backend is notified whenever
-# new logs are published to the S3 bucket. The SNS Topic allows CloudTrail to publish notifications, while the
-# subscription forwards these notifications to Sysdig's ingestion service via HTTPS.
+# 2. For organizational deployments (same account):
+# - An AWS IAM Role in the management account with permissions to access the S3 bucket directly
#
-# This setup assumes the customer has already configured an AWS CloudTrail Trail and its associated S3 bucket. The
-# required details (e.g., bucket ARN, topic ARN, and regions) are either passed as module variables or derived from
-# data sources.
+# 3. For organizational cross-account deployments:
+# - A CloudFormation StackSet deploys an IAM role directly in the bucket account
+# - The role in the bucket account allows Sysdig to access S3 data directly
#
-# Note: Sysdig's Secure UI provides the necessary information to guide customers in setting up the required resources.
+# Common resources for all scenarios:
+# - An AWS SNS Topic and Subscription for CloudTrail notifications, ensuring Sysdig's backend is notified whenever
+# new logs are published to the S3 bucket
+# - Support for KMS-encrypted S3 buckets, with roles granted proper decrypt permissions
+#
+# This setup assumes the customer has already configured an AWS CloudTrail Trail and its associated S3 bucket.
#-----------------------------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------
@@ -22,6 +25,10 @@
#-----------------------------------------------------------------------------------------
data "aws_caller_identity" "current" {}
+data "aws_region" "current" {}
+
+data "aws_partition" "current" {}
+
data "sysdig_secure_trusted_cloud_identity" "trusted_identity" {
cloud_provider = "aws"
}
@@ -37,13 +44,24 @@ data "sysdig_secure_cloud_ingestion_assets" "assets" {
# Generate a unique name for resources using random suffix and account ID hash
#-----------------------------------------------------------------------------------------
locals {
- account_id_hash = substr(md5(data.aws_caller_identity.current.account_id), 0, 4)
- role_name = "${var.name}-${random_id.suffix.hex}-${local.account_id_hash}"
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
topic_name = split(":", var.topic_arn)[5]
+ topic_region = split(":", var.topic_arn)[3]
routing_key = data.sysdig_secure_cloud_ingestion_assets.assets.aws.sns_routing_key
ingestion_url = data.sysdig_secure_cloud_ingestion_assets.assets.aws.sns_routing_url
+
+ # Determine bucket owner account ID - use provided value or default to current account
+ bucket_account_id = var.bucket_account_id != null ? var.bucket_account_id : data.aws_caller_identity.current.account_id
+
+ # Flag for cross-account bucket access
+ is_cross_account = var.bucket_account_id != null && var.bucket_account_id != data.aws_caller_identity.current.account_id
+
+ account_id_hash = substr(md5(local.bucket_account_id), 0, 4)
+ role_name = "${var.name}-${random_id.suffix.hex}-${local.account_id_hash}"
+
+ # StackSet configuration
+ stackset_name = "${var.name}-${random_id.suffix.hex}-${local.account_id_hash}-stackset"
}
#-----------------------------------------------------------------------------------------------------------------------
@@ -54,17 +72,20 @@ resource "random_id" "suffix" {
byte_length = 3
}
-# AWS IAM Role that will be used by CloudIngestion to access the CloudTrail-associated s3 bucket
+# AWS IAM Role in the management account
+# Created for all scenarios EXCEPT organizational cross-account deployments
resource "aws_iam_role" "cloudlogs_s3_access" {
+ count = local.is_cross_account ? 0 : 1
name = local.role_name
tags = var.tags
assume_role_policy = data.aws_iam_policy_document.assume_cloudlogs_s3_access_role.json
}
-// AWS IAM Role Policy that will be used by CloudIngestion to access the CloudTrail-associated s3 bucket
+// AWS IAM Role Policy
resource "aws_iam_role_policy" "cloudlogs_s3_access_policy" {
+ count = local.is_cross_account ? 0 : 1
name = "cloudlogs_s3_access_policy"
- role = aws_iam_role.cloudlogs_s3_access.name
+ role = aws_iam_role.cloudlogs_s3_access[0].name
policy = data.aws_iam_policy_document.cloudlogs_s3_access.json
}
@@ -90,48 +111,60 @@ data "aws_iam_policy_document" "assume_cloudlogs_s3_access_role" {
# IAM Policy Document used for the bucket access policy
data "aws_iam_policy_document" "cloudlogs_s3_access" {
- statement {
- sid = "CloudlogsS3AccessGet"
+ # For same account bucket access
+ dynamic "statement" {
+ for_each = !local.is_cross_account ? [1] : []
+ content {
+ sid = "CloudlogsS3Access"
- effect = "Allow"
+ effect = "Allow"
- actions = [
- "s3:Get*",
- ]
+ actions = [
+ "s3:Get*",
+ "s3:List*"
+ ]
- resources = [
- var.bucket_arn,
- "${var.bucket_arn}/*"
- ]
+ resources = [
+ var.bucket_arn,
+ "${var.bucket_arn}/*"
+ ]
+ }
}
- statement {
- sid = "CloudlogsS3AccessList"
-
- effect = "Allow"
-
- actions = [
- "s3:List*"
- ]
-
- resources = [
- var.bucket_arn,
- "${var.bucket_arn}/*"
- ]
+ dynamic "statement" {
+ for_each = var.kms_key_arn != null && !local.is_cross_account ? [1] : []
+ content {
+ sid = "CloudlogsKMSDecrypt"
+
+ effect = "Allow"
+
+ actions = [
+ "kms:Decrypt"
+ ]
+
+ resources = [var.kms_key_arn]
+ }
}
}
#-----------------------------------------------------------------------------------------------------------------------
# SNS Topic and Subscription for CloudTrail notifications
#-----------------------------------------------------------------------------------------------------------------------
+provider aws {
+ alias = "sns"
+ region = local.topic_region
+}
+
resource "aws_sns_topic" "cloudtrail_notifications" {
count = var.create_topic ? 1 : 0
+ provider = aws.sns
name = local.topic_name
tags = var.tags
}
resource "aws_sns_topic_policy" "cloudtrail_notifications" {
count = var.create_topic ? 1 : 0
+ provider = aws.sns
arn = aws_sns_topic.cloudtrail_notifications[0].arn
policy = jsonencode({
Version = "2012-10-17"
@@ -151,10 +184,69 @@ resource "aws_sns_topic_policy" "cloudtrail_notifications" {
resource "aws_sns_topic_subscription" "cloudtrail_notifications" {
topic_arn = var.topic_arn
+ provider = aws.sns
protocol = "https"
endpoint = local.ingestion_url
- depends_on = [aws_sns_topic.cloudtrail_notifications]
+ depends_on = [aws_sns_topic.cloudtrail_notifications]
+}
+
+#-----------------------------------------------------------------------------------------------------------------------
+# Service-managed StackSet for creating a role in the bucket account for organizational deployments
+#-----------------------------------------------------------------------------------------------------------------------
+resource "aws_cloudformation_stack_set" "cloudlogs_s3_access" {
+ count = local.is_cross_account ? 1 : 0
+
+ name = local.stackset_name
+ description = "StackSet to configure S3 bucket and KMS permissions for Sysdig Cloud Logs integration"
+ template_body = templatefile("${path.module}/templates/stackset_template_body.tpl", {
+ bucket_arn = var.bucket_arn
+ kms_key_arn = var.kms_key_arn
+ })
+
+ parameters = {
+ RoleName = local.role_name
+ BucketAccountId = local.bucket_account_id
+ SysdigTrustedIdentity = local.trusted_identity
+ SysdigExternalId = data.sysdig_secure_tenant_external_id.external_id.external_id
+ KmsKeyArn = var.kms_key_arn
+ }
+
+ permission_model = "SERVICE_MANAGED"
+ capabilities = ["CAPABILITY_NAMED_IAM"]
+ call_as = "SELF"
+
+ # Explicitly set auto_deployment to disabled
+ auto_deployment {
+ enabled = false
+ retain_stacks_on_account_removal = false
+ }
+
+ lifecycle {
+ ignore_changes = [administration_role_arn]
+ }
+
+ tags = var.tags
+}
+
+resource "aws_cloudformation_stack_set_instance" "cloudlogs_s3_access" {
+ count = local.is_cross_account ? 1 : 0
+
+ stack_set_name = aws_cloudformation_stack_set.cloudlogs_s3_access[0].name
+
+ deployment_targets {
+ organizational_unit_ids = var.org_units
+ account_filter_type = "INTERSECTION"
+ accounts = [local.bucket_account_id]
+ }
+
+ region = data.aws_region.current.name
+
+ timeouts {
+ create = var.timeout
+ update = var.timeout
+ delete = var.timeout
+ }
}
#-----------------------------------------------------------------------------------------------------------------------------------------
@@ -164,7 +256,7 @@ resource "sysdig_secure_cloud_auth_account_component" "aws_cloud_logs" {
account_id = var.sysdig_secure_account_id
type = "COMPONENT_CLOUD_LOGS"
instance = "secure-runtime"
- version = "v1.0.0"
+ version = "v1.0.1"
cloud_logs_metadata = jsonencode({
aws = {
cloudtrailSns = {
@@ -173,7 +265,13 @@ resource "sysdig_secure_cloud_auth_account_component" "aws_cloud_logs" {
bucket_arn = var.bucket_arn
ingested_regions = var.regions
routing_key = local.routing_key
+ role_account_id = local.bucket_account_id
}
}
})
+
+ depends_on = [
+ aws_iam_role.cloudlogs_s3_access,
+ aws_cloudformation_stack_set_instance.cloudlogs_s3_access
+ ]
}
diff --git a/modules/integrations/cloud-logs/outputs.tf b/modules/integrations/cloud-logs/outputs.tf
index 35b6b1e..93405fa 100644
--- a/modules/integrations/cloud-logs/outputs.tf
+++ b/modules/integrations/cloud-logs/outputs.tf
@@ -1,5 +1,15 @@
output "cloud_logs_component_id" {
value = "${sysdig_secure_cloud_auth_account_component.aws_cloud_logs.type}/${sysdig_secure_cloud_auth_account_component.aws_cloud_logs.instance}"
description = "Component identifier of Cloud Logs integration created in Sysdig Backend for Log Ingestion"
- depends_on = [ sysdig_secure_cloud_auth_account_component.aws_cloud_logs ]
+ depends_on = [sysdig_secure_cloud_auth_account_component.aws_cloud_logs]
+}
+
+output "kms_policy_instructions" {
+ description = "Instructions for updating KMS key policy when KMS encryption is enabled"
+ value = (var.kms_key_arn != null) ? templatefile(
+ "${path.module}/templates/kms_policy_instructions.tpl",
+ {
+ role_arn = "arn:${data.aws_partition.current.partition}:iam::${local.bucket_account_id}:role/${local.role_name}"
+ }
+ ) : ""
}
diff --git a/modules/integrations/cloud-logs/templates/kms_policy_instructions.tpl b/modules/integrations/cloud-logs/templates/kms_policy_instructions.tpl
new file mode 100644
index 0000000..5f4dc5a
--- /dev/null
+++ b/modules/integrations/cloud-logs/templates/kms_policy_instructions.tpl
@@ -0,0 +1,15 @@
+IMPORTANT: MANUAL ACTION REQUIRED
+
+Please add the following statement to your KMS key policy to allow Sysdig to decrypt logs.
+This is necessary when KMS encryption is enabled for your S3 bucket.
+Without this policy addition, Sysdig may not be able to read your encrypted logs.
+
+{
+ "Sid": "Sysdig-Decrypt",
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": "${role_arn}"
+ },
+ "Action": "kms:Decrypt",
+ "Resource": "*"
+}
diff --git a/modules/integrations/cloud-logs/templates/stackset_template_body.tpl b/modules/integrations/cloud-logs/templates/stackset_template_body.tpl
new file mode 100644
index 0000000..2737787
--- /dev/null
+++ b/modules/integrations/cloud-logs/templates/stackset_template_body.tpl
@@ -0,0 +1,144 @@
+{
+ "AWSTemplateFormatVersion": "2010-09-09",
+ "Description": "StackSet to configure S3 bucket and KMS permissions for Sysdig Cloud Logs integration",
+ "Parameters": {
+ "RoleName": {
+ "Type": "String",
+ "Description": "Name of the role to be created in the bucket account"
+ },
+ "BucketAccountId": {
+ "Type": "String",
+ "Description": "The account id that the bucket resides in"
+ },
+ "SysdigTrustedIdentity": {
+ "Type": "String",
+ "Description": "ARN of the Sysdig service that needs to assume the role"
+ },
+ "SysdigExternalId": {
+ "Type": "String",
+ "Description": "External ID for secure role assumption by Sysdig"
+ },
+ "KmsKeyArn": {
+ "Type": "String",
+ "Description": "ARN of the KMS key used for encryption"
+ }
+ },
+ "Conditions": {
+ "IsBucketAccount": {
+ "Fn::Equals": [
+ {
+ "Ref": "AWS::AccountId"
+ },
+ {
+ "Ref": "BucketAccountId"
+ }
+ ]
+ },
+ "HasKMSKey": {
+ "Fn::Not": [
+ {
+ "Fn::Equals": [
+ {
+ "Ref": "KmsKeyArn"
+ },
+ ""
+ ]
+ }
+ ]
+ }
+ },
+ "Resources": {
+ "S3AccessRole": {
+ "Type": "AWS::IAM::Role",
+ "Condition": "IsBucketAccount",
+ "Properties": {
+ "RoleName": {
+ "Ref": "RoleName"
+ },
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Principal": {
+ "AWS": {
+ "Ref": "SysdigTrustedIdentity"
+ }
+ },
+ "Action": "sts:AssumeRole",
+ "Condition": {
+ "StringEquals": {
+ "sts:ExternalId": {
+ "Ref": "SysdigExternalId"
+ }
+ }
+ }
+ }
+ ]
+ },
+ "Policies": [
+ {
+ "PolicyName": "cloudlogs_s3_access_policy",
+ "PolicyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Sid": "S3BucketListAccess",
+ "Effect": "Allow",
+ "Action": [
+ "s3:ListBucket",
+ "s3:GetBucketLocation"
+ ],
+ "Resource": [
+ "${bucket_arn}"
+ ]
+ },
+ {
+ "Sid": "S3ObjectAccess",
+ "Effect": "Allow",
+ "Action": [
+ "s3:GetObject"
+ ],
+ "Resource": [
+ "${bucket_arn}/*"
+ ]
+ }
+ %{ if kms_key_arn != null && kms_key_arn != "" }
+ ,
+ {
+ "Sid": "KMSDecryptAccess",
+ "Effect": "Allow",
+ "Action": "kms:Decrypt",
+ "Resource": "${kms_key_arn}"
+ }
+ %{ endif }
+ ]
+ }
+ }
+ ],
+ "Tags": [
+ {
+ "Key": "Name",
+ "Value": "Sysdig Secure CloudTrail Logs Access Role"
+ },
+ {
+ "Key": "Purpose",
+ "Value": "Allow Sysdig to access S3 bucket for CloudTrail logs"
+ }
+ ]
+ }
+ }
+ },
+ "Outputs": {
+ "S3AccessRoleArn": {
+ "Description": "ARN of the IAM role created in the bucket account for S3 access",
+ "Condition": "IsBucketAccount",
+ "Value": {
+ "Fn::GetAtt": [
+ "S3AccessRole",
+ "Arn"
+ ]
+ }
+ }
+ }
+}
diff --git a/modules/integrations/cloud-logs/variables.tf b/modules/integrations/cloud-logs/variables.tf
index 7f9a22a..00cdb41 100644
--- a/modules/integrations/cloud-logs/variables.tf
+++ b/modules/integrations/cloud-logs/variables.tf
@@ -6,6 +6,16 @@ variable "sysdig_secure_account_id" {
variable "bucket_arn" {
description = "(Required) The ARN of your CloudTrail Bucket"
type = string
+
+ validation {
+ condition = var.bucket_arn != ""
+ error_message = "Bucket ARN must not be empty"
+ }
+
+ validation {
+ condition = can(regex("^arn:(aws|aws-us-gov):s3:::.*$", var.bucket_arn))
+ error_message = "Bucket ARN must be a valid S3 ARN format"
+ }
}
variable "tags" {
@@ -18,7 +28,7 @@ variable "tags" {
}
variable "name" {
- description = "(Optional) Name to be assigned to all child resources. A suffix may be added internally when required. Use default value unless you need to install multiple instances"
+ description = "(Optional) Name to be assigned to all child resources. A suffix may be added internally when required."
type = string
default = "sysdig-secure-cloudlogs"
}
@@ -55,3 +65,27 @@ variable "create_topic" {
default = false
description = "true/false whether terraform should create the SNS Topic"
}
+
+variable "bucket_account_id" {
+ type = string
+ default = null
+ description = "(Optional) AWS Account ID that owns the S3 bucket, if different from the account where the module is being applied. Required for organizational cross-account deployments."
+}
+
+variable "timeout" {
+ description = "The maximum amount of time that Terraform will wait for the StackSet operation to complete"
+ type = string
+ default = "30m"
+}
+
+variable "org_units" {
+ type = list(string)
+ description = "List of AWS Organizations organizational unit (OU) IDs in which to create the StackSet instances. Required for cross-account organizational deployments."
+ default = []
+}
+
+variable "kms_key_arn" {
+ description = "ARN of the KMS key used to encrypt the S3 bucket. If provided, the IAM role will be granted decrypt permissions."
+ type = string
+ default = null
+}
diff --git a/modules/integrations/cloud-logs/versions.tf b/modules/integrations/cloud-logs/versions.tf
index 6ed3774..8ff6aca 100644
--- a/modules/integrations/cloud-logs/versions.tf
+++ b/modules/integrations/cloud-logs/versions.tf
@@ -8,7 +8,7 @@ terraform {
}
sysdig = {
source = "sysdiglabs/sysdig"
- version = "~> 1.48"
+ version = "~> 1.52"
}
random = {
source = "hashicorp/random"