elb_bucket.tf 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. # The centralized bucket for ELB Logging
  2. data "aws_elb_service_account" "main" {} # ELB logs use a single aws account to place logs
  3. module "elb_logging_logging_bucket" {
  4. source = "../../thirdparty/terraform-aws-s3logging-bucket"
  5. bucket_name = "xdr-elb-${var.environment}-access-logs"
  6. lifecycle_rules = list(
  7. {
  8. id = "expire-old-logs"
  9. enabled = true
  10. prefix = ""
  11. expiration = 30
  12. noncurrent_version_expiration = 30
  13. abort_incomplete_multipart_upload_days = 7
  14. })
  15. tags = merge(var.standard_tags, var.tags, { "Note" = "ELB Logging Does Not Support SSE-KMS. Only SSE-S3 is supported." } )
  16. versioning_enabled = true
  17. }
  18. resource "aws_s3_bucket" "elb_logging_bucket" {
  19. bucket = "xdr-elb-${var.environment}"
  20. acl = "private"
  21. tags = merge(var.standard_tags, var.tags)
  22. versioning {
  23. enabled = true
  24. }
  25. logging {
  26. target_bucket = module.elb_logging_logging_bucket.s3_bucket_name
  27. target_prefix = "${var.aws_account_id}-${var.aws_region}-elblogs/"
  28. }
  29. server_side_encryption_configuration {
  30. rule {
  31. apply_server_side_encryption_by_default {
  32. sse_algorithm = "AES256" # ELB logging only supports SSE-S3
  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. principals {
  53. type = "AWS"
  54. identifiers = [ data.aws_elb_service_account.main.arn ]
  55. }
  56. resources = ["arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}/*"]
  57. }
  58. statement {
  59. effect = "Allow"
  60. actions = [ "s3:PutObject" ]
  61. principals {
  62. type = "Service"
  63. identifiers = [ "delivery.logs.amazonaws.com" ]
  64. }
  65. resources = [ "arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}/*" ]
  66. condition {
  67. test = "StringEquals"
  68. variable = "s3:x-amz-acl"
  69. values = [ "bucket-owner-full-control" ]
  70. }
  71. }
  72. statement {
  73. effect = "Allow"
  74. actions = [ "s3:GetBucketAcl" ]
  75. principals {
  76. type = "Service"
  77. identifiers = [ "delivery.logs.amazonaws.com" ]
  78. }
  79. resources = [ "arn:${var.aws_partition}:s3:::${aws_s3_bucket.elb_logging_bucket.bucket}" ]
  80. }
  81. }
  82. resource "aws_s3_bucket_policy" "aws_elb_bucket_policy" {
  83. bucket = aws_s3_bucket.elb_logging_bucket.id
  84. policy = data.aws_iam_policy_document.aws_elb_bucket_policy.json
  85. # Ordering bug, see https://github.com/terraform-providers/terraform-provider-aws/issues/7628
  86. depends_on = [ aws_s3_bucket_public_access_block.aws_elb_bucket_block_public_access ]
  87. }
  88. #### SQS Queue for Splunk
  89. resource "aws_s3_bucket_notification" "on_new_elb_log" {
  90. bucket = aws_s3_bucket.elb_logging_bucket.bucket
  91. topic {
  92. topic_arn = aws_sns_topic.new_elb_log_event.arn
  93. events = [
  94. "s3:ObjectCreated:*",
  95. ]
  96. filter_suffix = ""
  97. }
  98. }
  99. resource "aws_sns_topic" "new_elb_log_event" {
  100. name = "s3-notification-topic-${aws_s3_bucket.elb_logging_bucket.bucket}"
  101. kms_master_key_id = aws_kms_key.new_object_key.id
  102. }
  103. resource "aws_sns_topic_policy" "elb_log" {
  104. arn = aws_sns_topic.new_elb_log_event.arn
  105. policy = data.aws_iam_policy_document.elblog_bucket_can_publish.json
  106. }
  107. data "aws_iam_policy_document" "elblog_bucket_can_publish" {
  108. statement {
  109. actions = [
  110. "SNS:Publish",
  111. ]
  112. effect = "Allow"
  113. condition {
  114. test = "ArnLike"
  115. variable = "aws:SourceArn"
  116. values = [
  117. aws_s3_bucket.elb_logging_bucket.arn
  118. ]
  119. }
  120. principals {
  121. type = "AWS"
  122. identifiers = ["*"]
  123. }
  124. resources = [
  125. aws_sns_topic.new_elb_log_event.arn
  126. ]
  127. sid = "allowpublish"
  128. }
  129. statement {
  130. actions = [
  131. "SNS:Subscribe",
  132. "SNS:Receive",
  133. ]
  134. effect = "Allow"
  135. principals {
  136. type = "AWS"
  137. identifiers = ["*"]
  138. }
  139. condition {
  140. test = "ArnEquals"
  141. values = [ aws_sqs_queue.new_elblog.arn ]
  142. variable = "aws:SourceArn"
  143. }
  144. resources = [
  145. aws_sns_topic.new_elb_log_event.arn
  146. ]
  147. sid = "sid_allow_subscribe"
  148. }
  149. }
  150. resource "aws_sqs_queue" "new_elblog" {
  151. name = "new-objects-for-${aws_s3_bucket.elb_logging_bucket.bucket}"
  152. visibility_timeout_seconds = 300 # wait 5 minutes before allowing a different splunk instance to process the same message
  153. message_retention_seconds = 604800 # Keep a message in the queue for 7 days
  154. receive_wait_time_seconds = 0 # how long to wait for a message before returning
  155. redrive_policy = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.elblog-dlg.arn}\",\"maxReceiveCount\":4}"
  156. tags = merge(var.standard_tags, var.tags)
  157. kms_master_key_id = aws_kms_key.new_object_key.id
  158. kms_data_key_reuse_period_seconds = 3600
  159. }
  160. data "aws_iam_policy_document" "sns_topic_elblog_can_publish" {
  161. statement {
  162. effect = "Allow"
  163. principals {
  164. identifiers = [
  165. "*",
  166. ]
  167. type = "AWS"
  168. }
  169. actions = [
  170. "SQS:SendMessage",
  171. ]
  172. resources = [
  173. aws_sqs_queue.new_elblog.arn
  174. ]
  175. condition {
  176. test = "ArnEquals"
  177. values = [
  178. aws_sns_topic.new_elb_log_event.arn
  179. ]
  180. variable = "aws:SourceArn"
  181. }
  182. }
  183. }
  184. // Dead Letter queue, use same parameters as main queue
  185. resource "aws_sqs_queue" "elblog-dlg" {
  186. name = "new-objects-for-${aws_s3_bucket.elb_logging_bucket.bucket}-dlq"
  187. message_retention_seconds = 300
  188. receive_wait_time_seconds = 0
  189. tags = merge(var.standard_tags, var.tags)
  190. kms_master_key_id = aws_kms_key.new_object_key.id
  191. kms_data_key_reuse_period_seconds = 3600
  192. }
  193. resource "aws_sqs_queue_policy" "elblog_bucket_can_publish" {
  194. policy = data.aws_iam_policy_document.sns_topic_elblog_can_publish.json
  195. queue_url = aws_sqs_queue.new_elblog.id
  196. }
  197. resource "aws_sns_topic_subscription" "elblog_bucket_change_notification_to_queue" {
  198. topic_arn = aws_sns_topic.new_elb_log_event.arn
  199. protocol = "sqs"
  200. endpoint = aws_sqs_queue.new_elblog.arn
  201. }