diff --git a/README.md b/README.md
index 14fe36e..ff9ade3 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,7 @@ Full contributing [guidelines are covered here](.github/contributing.md).
| [additional\_iam\_policy\_statements](#input\_additional\_iam\_policy\_statements) | Map of dynamic policy statements to attach to Lambda Function role | `any` | `{}` | no |
| [allowed\_aws\_principals\_for\_sns\_subscribe](#input\_allowed\_aws\_principals\_for\_sns\_subscribe) | List of AWS principals allowed to subscribe to the SNS topic (only applicable to org deployments). | `list(string)` | `[]` | no |
| [cloudtrail\_bucket\_name](#input\_cloudtrail\_bucket\_name) | Bucket containing the Cloudtrail logs that you want to process. ControlTower bucket name follows this naming convention `aws-controltower-logs-{{account_id}}-{{region}}` | `string` | `""` | no |
+| [cloudtrail\_bucket\_notifications\_sns\_arn](#input\_cloudtrail\_bucket\_notifications\_sns\_arn) | SNS topic ARN for bucket notifications. If not provided, a new SNS topic will be created along with the bucket notifications configuration. | `string` | `null` | no |
| [cloudtrail\_log\_group](#input\_cloudtrail\_log\_group) | CloudWatch Log group for CloudTrail events. | `string` | `""` | no |
| [create\_iam\_role](#input\_create\_iam\_role) | Determines whether a an IAM role is created or to use an existing IAM role | `bool` | `true` | no |
| [event\_batch\_size](#input\_event\_batch\_size) | Batch events into chunks of `event_batch_size` | `number` | `100` | no |
@@ -117,7 +118,6 @@ Full contributing [guidelines are covered here](.github/contributing.md).
| [aws_iam_policy_document.lambda_permissions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.sns_topic_policy_bucket_notifications](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
-| [aws_s3_bucket.cloudtrail_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source |
----
### Default excluded scoped actions
diff --git a/deployment_organization.tf b/deployment_organization.tf
index 1df5830..637f8cb 100644
--- a/deployment_organization.tf
+++ b/deployment_organization.tf
@@ -8,20 +8,11 @@
# Ref: https://aws.amazon.com/blogs/compute/fanout-s3-event-notifications-to-multiple-endpoints/
-#--------------------------------------------------------------------------------------
-# aws_s3_bucket
-#--------------------------------------------------------------------------------------
-data "aws_s3_bucket" "cloudtrail_bucket" {
- count = var.standalone ? 0 : 1
-
- bucket = var.cloudtrail_bucket_name
-}
-
#--------------------------------------------------------------------------------------
# aws_sns_topic
#--------------------------------------------------------------------------------------
resource "aws_sns_topic" "bucket_notifications" {
- count = var.standalone ? 0 : 1
+ count = var.standalone || var.cloudtrail_bucket_notifications_sns_arn != null ? 0 : 1
name = var.naming_prefix
# Cannot use AWS managed KMS key with S3 bucket notifications
@@ -38,13 +29,13 @@ locals {
}
}
data "aws_iam_policy_document" "sns_topic_policy_bucket_notifications" {
- count = var.standalone ? 0 : 1
+ count = var.standalone || var.cloudtrail_bucket_notifications_sns_arn != null ? 0 : 1
statement {
sid = "AllowS3BucketNotificationToSNSPublish"
actions = ["SNS:Publish"]
effect = "Allow"
- resources = [aws_sns_topic.bucket_notifications[0].arn]
+ resources = [try(aws_sns_topic.bucket_notifications[0].arn, var.cloudtrail_bucket_notifications_sns_arn)]
principals {
type = "Service"
identifiers = ["s3.amazonaws.com"]
@@ -52,7 +43,7 @@ data "aws_iam_policy_document" "sns_topic_policy_bucket_notifications" {
condition {
test = "ArnEquals"
variable = "aws:SourceArn"
- values = [data.aws_s3_bucket.cloudtrail_bucket[0].arn]
+ values = ["arn:aws:s3:::${var.cloudtrail_bucket_name}"]
}
condition {
test = "StringEquals"
@@ -61,13 +52,13 @@ data "aws_iam_policy_document" "sns_topic_policy_bucket_notifications" {
}
}
dynamic "statement" {
- for_each = !var.standalone ? local.allowed_aws_principals_for_sns_subscribe : {}
+ for_each = var.standalone || var.cloudtrail_bucket_notifications_sns_arn != null ? {} : local.allowed_aws_principals_for_sns_subscribe
content {
sid = "AllowAWSPrincipalToSNSSubscribe${statement.key}"
actions = ["sns:Subscribe"]
effect = "Allow"
- resources = [aws_sns_topic.bucket_notifications[0].arn]
+ resources = [try(aws_sns_topic.bucket_notifications[0].arn, var.cloudtrail_bucket_notifications_sns_arn)]
principals {
type = "AWS"
identifiers = [statement.value]
@@ -77,9 +68,9 @@ data "aws_iam_policy_document" "sns_topic_policy_bucket_notifications" {
}
resource "aws_sns_topic_policy" "bucket_notifications" {
- count = var.standalone ? 0 : 1
+ count = var.standalone || var.cloudtrail_bucket_notifications_sns_arn != null ? 0 : 1
- arn = aws_sns_topic.bucket_notifications[0].arn
+ arn = try(aws_sns_topic.bucket_notifications[0].arn, var.cloudtrail_bucket_notifications_sns_arn)
policy = data.aws_iam_policy_document.sns_topic_policy_bucket_notifications[0].json
}
@@ -88,12 +79,12 @@ resource "aws_sns_topic_policy" "bucket_notifications" {
# aws_s3_bucket_notification
#--------------------------------------------------------------------------------------
resource "aws_s3_bucket_notification" "bucket_notification" {
- count = var.standalone ? 0 : 1
+ count = var.standalone || var.cloudtrail_bucket_notifications_sns_arn != null ? 0 : 1
- bucket = data.aws_s3_bucket.cloudtrail_bucket[0].id
+ bucket = var.cloudtrail_bucket_name
topic {
- topic_arn = aws_sns_topic.bucket_notifications[0].arn
+ topic_arn = try(aws_sns_topic.bucket_notifications[0].arn, var.cloudtrail_bucket_notifications_sns_arn)
events = ["s3:ObjectCreated:*"]
filter_suffix = ".json.gz"
}
@@ -129,7 +120,7 @@ data "aws_iam_policy_document" "bucket_notifications" {
condition {
test = "ArnEquals"
variable = "aws:SourceArn"
- values = [aws_sns_topic.bucket_notifications[0].arn]
+ values = [try(aws_sns_topic.bucket_notifications[0].arn, var.cloudtrail_bucket_notifications_sns_arn)]
}
}
}
@@ -147,7 +138,7 @@ resource "aws_sqs_queue_policy" "bucket_notifications" {
resource "aws_sns_topic_subscription" "bucket_notifications" {
count = var.standalone ? 0 : 1
- topic_arn = aws_sns_topic.bucket_notifications[0].arn
+ topic_arn = try(aws_sns_topic.bucket_notifications[0].arn, var.cloudtrail_bucket_notifications_sns_arn)
protocol = "sqs"
endpoint = aws_sqs_queue.bucket_notifications[0].arn
}
diff --git a/main.tf b/main.tf
index d6c4b82..f4b1458 100644
--- a/main.tf
+++ b/main.tf
@@ -12,7 +12,7 @@ data "aws_iam_policy_document" "lambda_permissions" {
content {
sid = "S3AccessBucket"
actions = ["s3:ListBucket"]
- resources = [data.aws_s3_bucket.cloudtrail_bucket[0].arn]
+ resources = ["arn:aws:s3:::${var.cloudtrail_bucket_name}"]
}
}
@@ -21,7 +21,7 @@ data "aws_iam_policy_document" "lambda_permissions" {
content {
sid = "S3AccessBucketObject"
actions = ["s3:GetObject"]
- resources = ["${data.aws_s3_bucket.cloudtrail_bucket[0].arn}/*"]
+ resources = ["arn:aws:s3:::${var.cloudtrail_bucket_name}/*"]
}
}
diff --git a/variables.tf b/variables.tf
index aaf192e..b8c65bf 100644
--- a/variables.tf
+++ b/variables.tf
@@ -89,6 +89,12 @@ variable "naming_prefix" {
default = "clickops-notifier"
}
+variable "cloudtrail_bucket_notifications_sns_arn" {
+ type = string
+ description = "SNS topic ARN for bucket notifications. If not provided, a new SNS topic will be created along with the bucket notifications configuration."
+ default = null
+}
+
variable "tags" {
type = map(string)
description = "Tags to add to resources in addition to the default_tags for the provider"