# The centralized bucket for ELB Logging data "aws_elb_service_account" "main" {} # ELB logs use a single aws account to place logs module "elb_logging_logging_bucket" { source = "../../thirdparty/terraform-aws-s3logging-bucket" bucket_name = "xdr-elb-${var.environment}-access-logs" lifecycle_rules = [ { id = "expire-old-logs" enabled = true prefix = "" expiration = 30 noncurrent_version_expiration = 30 abort_incomplete_multipart_upload_days = 7 } ] tags = merge(local.standard_tags, var.tags, { "Note" = "ELB Logging Does Not Support SSE-KMS. Only SSE-S3 is supported." }) versioning_enabled = true } resource "aws_s3_bucket" "elb_logging_bucket" { bucket = "xdr-elb-${var.environment}" tags = merge(local.standard_tags, var.tags) } resource "aws_s3_bucket_acl" "s3_acl_elb_logging_bucket" { bucket = aws_s3_bucket.elb_logging_bucket.id acl = "private" } resource "aws_s3_bucket_versioning" "s3_version_elb_logging_bucket" { bucket = aws_s3_bucket.elb_logging_bucket.id versioning_configuration { status = "Enabled" } } resource "aws_s3_bucket_logging" "elb_logging_bucket" { bucket = aws_s3_bucket.elb_logging_bucket.id target_bucket = module.elb_logging_logging_bucket.s3_bucket_name target_prefix = "${var.aws_account_id}-${var.aws_region}-elblogs/" } # tfsec:ignore:aws-s3-encryption-customer-key Risk is low for AES-256 encryption resource "aws_s3_bucket_server_side_encryption_configuration" "s3_sse_elb_logging_bucket" { bucket = aws_s3_bucket.elb_logging_bucket.id rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" # ELB logging only supports SSE-S3 } } } resource "aws_s3_bucket_public_access_block" "aws_elb_bucket_block_public_access" { block_public_acls = true block_public_policy = true bucket = aws_s3_bucket.elb_logging_bucket.id ignore_public_acls = true restrict_public_buckets = true } data "aws_iam_policy_document" "aws_elb_bucket_policy" { statement { effect = "Allow" actions = ["s3:PutObject"] # principals { # type = "AWS" # identifiers = [ for a in local.responsible_accounts[var.environment]: "arn:${var.aws_partition}:iam::${a}:root" ] #} principals { type = "AWS" identifiers = [data.aws_elb_service_account.main.arn] } resources = ["arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}/*"] } statement { effect = "Allow" actions = ["s3:PutObject"] principals { type = "Service" identifiers = ["delivery.logs.amazonaws.com"] } resources = ["arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}/*"] condition { test = "StringEquals" variable = "s3:x-amz-acl" values = ["bucket-owner-full-control"] } } statement { effect = "Allow" actions = ["s3:GetBucketAcl"] principals { type = "Service" identifiers = ["delivery.logs.amazonaws.com"] } resources = ["arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}"] } } resource "aws_s3_bucket_policy" "aws_elb_bucket_policy" { bucket = aws_s3_bucket.elb_logging_bucket.id policy = data.aws_iam_policy_document.aws_elb_bucket_policy.json # Ordering bug, see https://github.com/terraform-providers/terraform-provider-aws/issues/7628 depends_on = [aws_s3_bucket_public_access_block.aws_elb_bucket_block_public_access] } #### SQS Queue for Splunk resource "aws_s3_bucket_notification" "on_new_elb_log" { bucket = aws_s3_bucket.elb_logging_bucket.bucket topic { topic_arn = aws_sns_topic.new_elb_log_event.arn events = [ "s3:ObjectCreated:*", ] filter_suffix = "" } } resource "aws_sns_topic" "new_elb_log_event" { name = "s3-notification-topic-${aws_s3_bucket.elb_logging_bucket.bucket}" kms_master_key_id = aws_kms_key.new_object_key.id } resource "aws_sns_topic_policy" "elb_log" { arn = aws_sns_topic.new_elb_log_event.arn policy = data.aws_iam_policy_document.elblog_bucket_can_publish.json } data "aws_iam_policy_document" "elblog_bucket_can_publish" { statement { actions = [ "SNS:Publish", ] effect = "Allow" condition { test = "ArnLike" variable = "aws:SourceArn" values = [ aws_s3_bucket.elb_logging_bucket.arn ] } principals { type = "AWS" identifiers = ["*"] } resources = [ aws_sns_topic.new_elb_log_event.arn ] sid = "allowpublish" } statement { actions = [ "SNS:Subscribe", "SNS:Receive", ] effect = "Allow" principals { type = "AWS" identifiers = ["*"] } condition { test = "ArnEquals" values = [aws_sqs_queue.new_elblog.arn] variable = "aws:SourceArn" } resources = [ aws_sns_topic.new_elb_log_event.arn ] sid = "sid_allow_subscribe" } } resource "aws_sqs_queue" "new_elblog" { name = "new-objects-for-${aws_s3_bucket.elb_logging_bucket.bucket}" visibility_timeout_seconds = 300 # wait 5 minutes before allowing a different splunk instance to process the same message message_retention_seconds = 604800 # Keep a message in the queue for 7 days receive_wait_time_seconds = 0 # how long to wait for a message before returning redrive_policy = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.elblog-dlg.arn}\",\"maxReceiveCount\":4}" tags = merge(local.standard_tags, var.tags) kms_master_key_id = aws_kms_key.new_object_key.id kms_data_key_reuse_period_seconds = 3600 } data "aws_iam_policy_document" "sns_topic_elblog_can_publish" { statement { effect = "Allow" principals { identifiers = [ "*", ] type = "AWS" } actions = [ "SQS:SendMessage", ] resources = [ aws_sqs_queue.new_elblog.arn ] condition { test = "ArnEquals" values = [ aws_sns_topic.new_elb_log_event.arn ] variable = "aws:SourceArn" } } } // Dead Letter queue, use same parameters as main queue resource "aws_sqs_queue" "elblog-dlg" { name = "new-objects-for-${aws_s3_bucket.elb_logging_bucket.bucket}-dlq" message_retention_seconds = 300 receive_wait_time_seconds = 0 tags = merge(local.standard_tags, var.tags) kms_master_key_id = aws_kms_key.new_object_key.id kms_data_key_reuse_period_seconds = 3600 } resource "aws_sqs_queue_policy" "elblog_bucket_can_publish" { policy = data.aws_iam_policy_document.sns_topic_elblog_can_publish.json queue_url = aws_sqs_queue.new_elblog.id } resource "aws_sns_topic_subscription" "elblog_bucket_change_notification_to_queue" { topic_arn = aws_sns_topic.new_elb_log_event.arn protocol = "sqs" endpoint = aws_sqs_queue.new_elblog.arn } //AWS Provider outdated arguments <4.4.0 /*resource "aws_s3_bucket" "elb_logging_bucket" { bucket = "xdr-elb-${var.environment}" acl = "private" tags = merge(local.standard_tags, var.tags) versioning { enabled = true } logging { target_bucket = module.elb_logging_logging_bucket.s3_bucket_name target_prefix = "${var.aws_account_id}-${var.aws_region}-elblogs/" } server_side_encryption_configuration { rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" # ELB logging only supports SSE-S3 } } } } */