account_alerts.tf 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. # An SNS queue for email alerts
  2. # tfsec:ignore:aws-sns-enable-topic-encryption
  3. resource "aws_sns_topic" "account-alerts" {
  4. name = "account-alerts"
  5. tags = merge(local.standard_tags, var.tags)
  6. }
  7. resource "aws_sns_topic_policy" "account-alerts" {
  8. arn = aws_sns_topic.account-alerts.arn
  9. policy = data.aws_iam_policy_document.account-alerts.json
  10. }
  11. data "aws_iam_policy_document" "account-alerts" {
  12. statement {
  13. sid = "AllowAllAccountsToPublish"
  14. actions = ["SNS:Publish"]
  15. effect = "Allow"
  16. resources = [aws_sns_topic.account-alerts.arn]
  17. principals {
  18. type = "AWS"
  19. identifiers = [for a in local.responsible_accounts[var.environment] : "arn:${var.aws_partition}:iam::${a}:root"]
  20. }
  21. }
  22. statement {
  23. sid = "AllowCloudWatchToPublic"
  24. actions = ["SNS:Publish"]
  25. effect = "Allow"
  26. resources = [aws_sns_topic.account-alerts.arn]
  27. principals {
  28. type = "Service"
  29. identifiers = ["cloudwatch.amazonaws.com"]
  30. }
  31. }
  32. }
  33. # Unfortunately, terraform does not support email destinations, so we can't manage subscriptions here.
  34. # SQS to get alerts into Splunk
  35. resource "aws_sqs_queue" "account-alerts" {
  36. name = "account-alerts"
  37. visibility_timeout_seconds = 300 # wait 5 minutes before allowing a different splunk instance to process the same message
  38. message_retention_seconds = 604800 # Keep a message in the queue for 7 days
  39. receive_wait_time_seconds = 0 # how long to wait for a message before returning
  40. redrive_policy = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.account-alerts-dlq.arn}\",\"maxReceiveCount\":4}"
  41. tags = merge(local.standard_tags, var.tags)
  42. kms_master_key_id = aws_kms_key.account-alerts-key.id
  43. kms_data_key_reuse_period_seconds = 3600
  44. }
  45. data "aws_iam_policy_document" "account-alerts-sns-topic-can-publish" {
  46. statement {
  47. effect = "Allow"
  48. principals {
  49. identifiers = ["*"]
  50. type = "AWS"
  51. }
  52. actions = ["SQS:SendMessage"]
  53. resources = [aws_sqs_queue.account-alerts.arn]
  54. condition {
  55. test = "ArnEquals"
  56. values = [aws_sns_topic.account-alerts.arn]
  57. variable = "aws:SourceArn"
  58. }
  59. }
  60. }
  61. // Dead Letter queue, use same parameters as main queue
  62. resource "aws_sqs_queue" "account-alerts-dlq" {
  63. name = "account-alerts-dlq"
  64. message_retention_seconds = 300
  65. receive_wait_time_seconds = 0
  66. tags = merge(local.standard_tags, var.tags)
  67. kms_master_key_id = aws_kms_key.account-alerts-key.id
  68. kms_data_key_reuse_period_seconds = 3600
  69. }
  70. resource "aws_sqs_queue_policy" "account-alerts-can-publish" {
  71. policy = data.aws_iam_policy_document.account-alerts-sns-topic-can-publish.json
  72. queue_url = aws_sqs_queue.account-alerts.id
  73. }
  74. resource "aws_sns_topic_subscription" "account-alerts-to-queue" {
  75. topic_arn = aws_sns_topic.account-alerts.arn
  76. protocol = "sqs"
  77. endpoint = aws_sqs_queue.account-alerts.arn
  78. }
  79. resource "aws_kms_key" "account-alerts-key" {
  80. description = "Encryption of SNS and SQS queue for account alerts notifications"
  81. policy = data.aws_iam_policy_document.account-alerts-kms-policy.json
  82. enable_key_rotation = true
  83. }
  84. data "aws_iam_policy_document" "account-alerts-kms-policy" {
  85. statement {
  86. sid = "AllowServices"
  87. effect = "Allow"
  88. principals {
  89. identifiers = ["cloudwatch.amazonaws.com", "sns.amazonaws.com", "sqs.amazonaws.com"]
  90. type = "Service"
  91. }
  92. actions = [
  93. "kms:GenerateDataKey",
  94. "kms:Decrypt"
  95. ]
  96. resources = ["*"]
  97. }
  98. statement {
  99. sid = "AllowOtherAccounts"
  100. effect = "Allow"
  101. principals {
  102. type = "AWS"
  103. identifiers = [for a in local.responsible_accounts[var.environment] : "arn:${var.aws_partition}:iam::${a}:root"]
  104. }
  105. actions = [
  106. "kms:GenerateDataKey",
  107. "kms:Encrypt"
  108. ]
  109. resources = ["*"]
  110. }
  111. # allow account to modify/manage key
  112. statement {
  113. sid = "AllowThisAccount"
  114. effect = "Allow"
  115. principals {
  116. identifiers = ["arn:${var.aws_partition}:iam::${var.aws_account_id}:root"]
  117. type = "AWS"
  118. }
  119. actions = [
  120. "kms:*"
  121. ]
  122. resources = ["*"]
  123. }
  124. }
  125. resource "aws_kms_alias" "account-alerts-key-alias" {
  126. name = "alias/account-alerts-key"
  127. target_key_id = aws_kms_key.account-alerts-key.key_id
  128. }