elb_bucket.tf 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. # The centralized bucket for ELB Logging
  2. module "elb_logging_logging_bucket" {
  3. source = "../../thirdparty/terraform-aws-s3logging-bucket"
  4. bucket_name = "xdr-elb-${var.environment}-access-logs"
  5. lifecycle_rules = list(
  6. {
  7. id = "expire-old-logs"
  8. enabled = true
  9. prefix = ""
  10. expiration = 30
  11. noncurrent_version_expiration = 30
  12. abort_incomplete_multipart_upload_days = 7
  13. })
  14. tags = merge(var.standard_tags, var.tags)
  15. versioning_enabled = true
  16. }
  17. resource "aws_s3_bucket" "elb_logging_bucket" {
  18. bucket = "xdr-elb-${var.environment}"
  19. acl = "private"
  20. tags = merge(var.standard_tags, var.tags)
  21. versioning {
  22. enabled = true
  23. }
  24. logging {
  25. target_bucket = module.elb_logging_logging_bucket.s3_bucket_name
  26. target_prefix = "${var.aws_account_id}-${var.aws_region}-elblogs/"
  27. }
  28. server_side_encryption_configuration {
  29. rule {
  30. apply_server_side_encryption_by_default {
  31. sse_algorithm = "aws:kms"
  32. kms_master_key_id = aws_kms_key.elb_encryption.arn
  33. }
  34. }
  35. }
  36. }
  37. resource "aws_s3_bucket_public_access_block" "aws_elb_bucket_block_public_access" {
  38. block_public_acls = true
  39. block_public_policy = true
  40. bucket = aws_s3_bucket.elb_logging_bucket.id
  41. ignore_public_acls = true
  42. restrict_public_buckets = true
  43. }
  44. data "aws_iam_policy_document" "aws_elb_bucket_policy" {
  45. statement {
  46. effect = "Allow"
  47. actions = ["s3:PutObject"]
  48. principals {
  49. type = "AWS"
  50. identifiers = [ for a in var.responsible_accounts[var.environment]: "arn:${var.aws_partition}:iam::${a}:root" ]
  51. }
  52. resources = ["arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}/*"]
  53. }
  54. statement {
  55. effect = "Allow"
  56. actions = [ "s3:PutObject" ]
  57. principals {
  58. type = "Service"
  59. identifiers = [ "delivery.logs.amazonaws.com" ]
  60. }
  61. resources = [ "arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}/*" ]
  62. condition {
  63. test = "StringEquals"
  64. variable = "s3:x-amz-acl"
  65. values = [ "bucket-owner-full-control" ]
  66. }
  67. }
  68. statement {
  69. effect = "Allow"
  70. actions = [ "s3:GetBucketAcl" ]
  71. principals {
  72. type = "Service"
  73. identifiers = [ "delivery.logs.amazonaws.com" ]
  74. }
  75. resources = [ "arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}" ]
  76. }
  77. }
  78. resource "aws_s3_bucket_policy" "aws_elb_bucket_policy" {
  79. bucket = aws_s3_bucket.elb_logging_bucket.id
  80. policy = data.aws_iam_policy_document.aws_elb_bucket_policy.json
  81. # Ordering bug, see https://github.com/terraform-providers/terraform-provider-aws/issues/7628
  82. depends_on = [ aws_s3_bucket_public_access_block.aws_elb_bucket_block_public_access ]
  83. }
  84. resource "aws_kms_key" "elb_encryption" {
  85. description = "This key is used to encrypt ELB Logs"
  86. deletion_window_in_days = 30
  87. policy = data.aws_iam_policy_document.elb_encryption_key_policy.json
  88. enable_key_rotation = true
  89. tags = merge(var.standard_tags, var.tags)
  90. }
  91. resource "aws_kms_alias" "elb_encryption" {
  92. name = "alias/aws_elb_logs"
  93. target_key_id = aws_kms_key.elb_encryption.key_id
  94. }
  95. data "aws_iam_policy_document" "elb_encryption_key_policy" {
  96. statement {
  97. actions = ["kms:*"]
  98. effect = "Allow"
  99. resources = ["*"]
  100. principals {
  101. type = "AWS"
  102. identifiers = ["arn:${var.aws_partition}:iam::${var.aws_account_id}:root"]
  103. }
  104. }
  105. statement {
  106. actions = [
  107. "kms:Encrypt*",
  108. "kms:GenerateDataKey*",
  109. ]
  110. effect = "Allow"
  111. resources = ["*"]
  112. principals {
  113. type = "AWS"
  114. identifiers = [ for a in var.responsible_accounts[var.environment]: "arn:${var.aws_partition}:iam::${a}:root" ]
  115. }
  116. }
  117. statement {
  118. actions = [
  119. "kms:Encrypt*",
  120. "kms:Decrypt*",
  121. "kms:ReEncrypt*",
  122. "kms:GenerateDataKey*",
  123. "kms:Describe*",
  124. ]
  125. effect = "Allow"
  126. resources = ["*"]
  127. principals {
  128. type = "Service"
  129. identifiers = [ "delivery.logs.amazonaws.com"]
  130. }
  131. }
  132. statement {
  133. actions = ["kms:Describe*"]
  134. effect = "Allow"
  135. resources = ["*"]
  136. principals {
  137. type = "Service"
  138. identifiers = [ "delivery.logs.amazonaws.com" ]
  139. }
  140. }
  141. }
  142. #### SQS Queue for Splunk
  143. resource "aws_s3_bucket_notification" "on_new_elb_log" {
  144. bucket = aws_s3_bucket.elb_logging_bucket.bucket
  145. topic {
  146. topic_arn = aws_sns_topic.new_elb_log_event.arn
  147. events = [
  148. "s3:ObjectCreated:*",
  149. ]
  150. filter_suffix = ""
  151. }
  152. }
  153. resource "aws_sns_topic" "new_elb_log_event" {
  154. name = "s3-notification-topic-${aws_s3_bucket.elb_logging_bucket.bucket}"
  155. kms_master_key_id = aws_kms_key.new_object_key.id
  156. }
  157. resource "aws_sns_topic_policy" "elb_log" {
  158. arn = aws_sns_topic.new_elb_log_event.arn
  159. policy = data.aws_iam_policy_document.elblog_bucket_can_publish.json
  160. }
  161. data "aws_iam_policy_document" "elblog_bucket_can_publish" {
  162. statement {
  163. actions = [
  164. "SNS:Publish",
  165. ]
  166. effect = "Allow"
  167. condition {
  168. test = "ArnLike"
  169. variable = "aws:SourceArn"
  170. values = [
  171. aws_s3_bucket.elb_logging_bucket.arn
  172. ]
  173. }
  174. principals {
  175. type = "AWS"
  176. identifiers = ["*"]
  177. }
  178. resources = [
  179. aws_sns_topic.new_elb_log_event.arn
  180. ]
  181. sid = "allowpublish"
  182. }
  183. statement {
  184. actions = [
  185. "SNS:Subscribe",
  186. "SNS:Receive",
  187. ]
  188. effect = "Allow"
  189. principals {
  190. type = "AWS"
  191. identifiers = ["*"]
  192. }
  193. condition {
  194. test = "ArnEquals"
  195. values = [ aws_sqs_queue.new_elblog.arn ]
  196. variable = "aws:SourceArn"
  197. }
  198. resources = [
  199. aws_sns_topic.new_elb_log_event.arn
  200. ]
  201. sid = "sid_allow_subscribe"
  202. }
  203. }
  204. resource "aws_sqs_queue" "new_elblog" {
  205. name = "new-objects-for-${aws_s3_bucket.elb_logging_bucket.bucket}"
  206. visibility_timeout_seconds = 300 # wait 5 minutes before allowing a different splunk instance to process the same message
  207. message_retention_seconds = 604800 # Keep a message in the queue for 7 days
  208. receive_wait_time_seconds = 0 # how long to wait for a message before returning
  209. redrive_policy = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.elblog-dlg.arn}\",\"maxReceiveCount\":4}"
  210. tags = merge(var.standard_tags, var.tags)
  211. kms_master_key_id = aws_kms_key.new_object_key.id
  212. kms_data_key_reuse_period_seconds = 3600
  213. }
  214. data "aws_iam_policy_document" "sns_topic_elblog_can_publish" {
  215. statement {
  216. effect = "Allow"
  217. principals {
  218. identifiers = [
  219. "*",
  220. ]
  221. type = "AWS"
  222. }
  223. actions = [
  224. "SQS:SendMessage",
  225. ]
  226. resources = [
  227. aws_sqs_queue.new_elblog.arn
  228. ]
  229. condition {
  230. test = "ArnEquals"
  231. values = [
  232. aws_sns_topic.new_elb_log_event.arn
  233. ]
  234. variable = "aws:SourceArn"
  235. }
  236. }
  237. }
  238. // Dead Letter queue, use same parameters as main queue
  239. resource "aws_sqs_queue" "elblog-dlg" {
  240. name = "new-objects-for-${aws_s3_bucket.elb_logging_bucket.bucket}-dlq"
  241. message_retention_seconds = 300
  242. receive_wait_time_seconds = 0
  243. tags = merge(var.standard_tags, var.tags)
  244. kms_master_key_id = aws_kms_key.new_object_key.id
  245. kms_data_key_reuse_period_seconds = 3600
  246. }
  247. resource "aws_sqs_queue_policy" "elblog_bucket_can_publish" {
  248. policy = data.aws_iam_policy_document.sns_topic_elblog_can_publish.json
  249. queue_url = aws_sqs_queue.new_elblog.id
  250. }
  251. resource "aws_sns_topic_subscription" "elblog_bucket_change_notification_to_queue" {
  252. topic_arn = aws_sns_topic.new_elb_log_event.arn
  253. protocol = "sqs"
  254. endpoint = aws_sqs_queue.new_elblog.arn
  255. }