# An SNS queue for email alerts resource "aws_sns_topic" "account-alerts" { name = "account-alerts" tags = merge(var.standard_tags, var.tags) } resource "aws_sns_topic_policy" "account-alerts" { arn = aws_sns_topic.account-alerts.arn policy = data.aws_iam_policy_document.account-alerts.json } data "aws_iam_policy_document" "account-alerts" { statement { sid = "AllowAllAccountsToPublish" actions = [ "SNS:Publish" ] effect = "Allow" resources = [ aws_sns_topic.account-alerts.arn ] principals { type = "AWS" identifiers = [ for a in var.responsible_accounts[var.environment]: "arn:${var.aws_partition}:iam::${a}:root" ] } } statement { sid = "AllowCloudWatchToPublic" actions = [ "SNS:Publish" ] effect = "Allow" resources = [ aws_sns_topic.account-alerts.arn ] principals { type = "Service" identifiers = [ "cloudwatch.amazonaws.com" ] } } } # Unfortunately, terraform does not support email destinations, so we can't manage subscriptions here. # SQS to get alerts into Splunk resource "aws_sqs_queue" "account-alerts" { name = "account-alerts" 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.account-alerts-dlq.arn}\",\"maxReceiveCount\":4}" tags = merge(var.standard_tags, var.tags) kms_master_key_id = aws_kms_key.account-alerts-key.id kms_data_key_reuse_period_seconds = 3600 } data "aws_iam_policy_document" "account-alerts-sns-topic-can-publish" { statement { effect = "Allow" principals { identifiers = [ "*" ] type = "AWS" } actions = [ "SQS:SendMessage" ] resources = [ aws_sqs_queue.account-alerts.arn ] condition { test = "ArnEquals" values = [ aws_sns_topic.account-alerts.arn ] variable = "aws:SourceArn" } } } // Dead Letter queue, use same parameters as main queue resource "aws_sqs_queue" "account-alerts-dlq" { name = "account-alerts-dlq" message_retention_seconds = 300 receive_wait_time_seconds = 0 tags = merge(var.standard_tags, var.tags) kms_master_key_id = aws_kms_key.account-alerts-key.id kms_data_key_reuse_period_seconds = 3600 } resource "aws_sqs_queue_policy" "account-alerts-can-publish" { policy = data.aws_iam_policy_document.account-alerts-sns-topic-can-publish.json queue_url = aws_sqs_queue.account-alerts.id } resource "aws_sns_topic_subscription" "account-alerts-to-queue" { topic_arn = aws_sns_topic.account-alerts.arn protocol = "sqs" endpoint = aws_sqs_queue.account-alerts.arn } resource "aws_kms_key" "account-alerts-key" { description = "Encryption of SNS and SQS queue for account alerts notifications" policy = data.aws_iam_policy_document.account-alerts-kms-policy.json enable_key_rotation = true } data "aws_iam_policy_document" "account-alerts-kms-policy" { statement { sid = "AllowServices" effect = "Allow" principals { identifiers = ["cloudwatch.amazonaws.com", "sns.amazonaws.com", "sqs.amazonaws.com"] type = "Service" } actions = [ "kms:GenerateDataKey", "kms:Decrypt" ] resources = [ "*" ] } statement { sid = "AllowOtherAccounts" effect = "Allow" principals { type = "AWS" identifiers = [ for a in var.responsible_accounts[var.environment]: "arn:${var.aws_partition}:iam::${a}:root" ] } actions = [ "kms:GenerateDataKey", "kms:Encrypt" ] resources = [ "*" ] } # allow account to modify/manage key statement { sid = "AllowThisAccount" effect = "Allow" principals { identifiers = ["arn:${var.aws_partition}:iam::${var.aws_account_id}:root"] type = "AWS" } actions = [ "kms:*" ] resources = ["*"] } } resource "aws_kms_alias" "account-alerts-key-alias" { name = "alias/account-alerts-key" target_key_id = aws_kms_key.account-alerts-key.key_id }