elb-with-acks.tf 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #------------------------------------------------------------------------------
  2. # An external ELB for the indexers for HEC, because acknowledgements
  3. #------------------------------------------------------------------------------
  4. #### NOTE:
  5. #### Firehose/Kinesis requires a Classic ELB. An ALB is not supported.
  6. #### See "Data Not Delivered to Splunk" at https://docs.aws.amazon.com/firehose/latest/dev/troubleshooting.html
  7. ####
  8. #### "If you use an AWS load balancer, make sure that it is a Classic Load Balancer. Kinesis Data Firehose does
  9. #### not support Application Load Balancers or Network Load Balancers."
  10. #########################
  11. # DNS Entry
  12. module "public_dns_record_hec_ack" {
  13. source = "../../../submodules/dns/public_ALIAS_record"
  14. name = "${var.prefix}-hec-ack"
  15. target_dns_name = aws_elb.hec_classiclb.dns_name
  16. target_zone_id = aws_elb.hec_classiclb.zone_id
  17. dns_info = var.dns_info
  18. providers = {
  19. aws.mdr-common-services-commercial = aws.mdr-common-services-commercial
  20. }
  21. }
  22. #########################
  23. # Certificate
  24. resource "aws_acm_certificate" "hec_classiclb_cert" {
  25. domain_name = "${var.prefix}-hec-ack.${var.dns_info["public"]["zone"]}"
  26. validation_method = "DNS"
  27. lifecycle {
  28. create_before_destroy = true
  29. }
  30. tags = merge(local.standard_tags, var.tags)
  31. }
  32. resource "aws_acm_certificate_validation" "hec_classiclb_cert_validation" {
  33. certificate_arn = aws_acm_certificate.hec_classiclb_cert.arn
  34. validation_record_fqdns = [for record in aws_route53_record.hec_classiclb_cert_validation : record.fqdn]
  35. }
  36. resource "aws_route53_record" "hec_classiclb_cert_validation" {
  37. provider = aws.mdr-common-services-commercial
  38. for_each = {
  39. for dvo in aws_acm_certificate.hec_classiclb_cert.domain_validation_options : dvo.domain_name => {
  40. name = dvo.resource_record_name
  41. record = dvo.resource_record_value
  42. type = dvo.resource_record_type
  43. }
  44. }
  45. allow_overwrite = true
  46. name = each.value.name
  47. records = [each.value.record]
  48. ttl = 60
  49. type = each.value.type
  50. zone_id = var.dns_info["public"]["zone_id"]
  51. }
  52. #########################
  53. # ELB
  54. resource "aws_elb" "hec_classiclb" {
  55. tags = merge(local.standard_tags, var.tags)
  56. name = "${var.prefix}-hec-classic"
  57. security_groups = [aws_security_group.hec_elb_security_group.id]
  58. # tflint-ignore: aws_elb_invalid_subnet - Incorrectly errors out that these are invalid
  59. subnets = var.public_subnets
  60. internal = false # tfsec:ignore:aws-elb-alb-not-public This is intentionally public
  61. listener {
  62. instance_port = 8088
  63. instance_protocol = "https"
  64. lb_port = 8088
  65. lb_protocol = "https"
  66. ssl_certificate_id = aws_acm_certificate.hec_classiclb_cert.arn
  67. }
  68. listener {
  69. instance_port = 8088
  70. instance_protocol = "https"
  71. lb_port = 443
  72. lb_protocol = "https"
  73. ssl_certificate_id = aws_acm_certificate.hec_classiclb_cert.arn
  74. }
  75. health_check {
  76. healthy_threshold = 10
  77. unhealthy_threshold = 2
  78. timeout = 5
  79. target = "HTTPS:8088/services/collector/health/1.0"
  80. interval = 30
  81. }
  82. # Access logs are a feedback loop. They create logs that are then sent back through the HEC.
  83. # They should remain disabled.
  84. #access_logs {
  85. # bucket = "xdr-elb-${ var.environment }"
  86. # enabled = true
  87. #}
  88. }
  89. # AWS Firehose / Splunk requirement for ELB cookies to have
  90. # cookie_expiration_period=0. Terraform does not support that directly
  91. # and expects >=1. Not specifying an expiration period causes a period
  92. # of 0. See https://github.com/terraform-providers/terraform-provider-aws/issues/12678
  93. resource "aws_lb_cookie_stickiness_policy" "hec_classiclb_sticky_443" {
  94. name = "sticky443-2"
  95. load_balancer = aws_elb.hec_classiclb.id
  96. lb_port = 443
  97. }
  98. # AWS Firehose / Splunk requirement for ELB cookies to have
  99. # cookie_expiration_period=0. Terraform does not support that directly
  100. # and expects >=1. Not specifying an expiration period causes a period
  101. # of 0. See https://github.com/terraform-providers/terraform-provider-aws/issues/12678
  102. resource "aws_lb_cookie_stickiness_policy" "hec_classiclb_sticky_8088" {
  103. name = "sticky8088"
  104. load_balancer = aws_elb.hec_classiclb.id
  105. lb_port = 8088
  106. }
  107. # Attach the instnaces to the ELB
  108. resource "aws_autoscaling_attachment" "hec_classic_asg_attachments" {
  109. for_each = toset([module.indexer0.asg_name[0], module.indexer1.asg_name[0], module.indexer2.asg_name[0]])
  110. elb = aws_elb.hec_classiclb.id
  111. autoscaling_group_name = each.key
  112. }
  113. # See https://github.com/terraform-providers/terraform-provider-aws/issues/995
  114. resource "aws_load_balancer_policy" "listener_policy-tls-1-2" {
  115. load_balancer_name = aws_elb.hec_classiclb.name
  116. policy_name = "elb-tls-1-2"
  117. policy_type_name = "SSLNegotiationPolicyType"
  118. policy_attribute {
  119. name = "Reference-Security-Policy"
  120. value = "ELBSecurityPolicy-TLS-1-2-2017-01" # PFS, TLS1.2, and GCM; most "restrictive" policy
  121. }
  122. # Workaround for bug above. If changing TLS policy then be
  123. # prepared to taint the resource. Tested/working taint commands
  124. # (as of 2020-06-25) are:
  125. # terraform taint --module customer.indexer_cluster aws_load_balancer_policy.listener_policy-tls-1-2
  126. # terraform taint --module customer.indexer_cluster aws_load_balancer_listener_policy.hec_classiclb_listener_443
  127. # terraform taint --module customer.indexer_cluster aws_load_balancer_listener_policy.hec_classiclb_listener_8088
  128. #
  129. # As of this time, w/ terraform 0.11.14, you have to taint all three
  130. # to effect a change here.
  131. #
  132. # 2020-11-04 - Confirmed this is still a bug in 0.13
  133. lifecycle {
  134. ignore_changes = [policy_attribute]
  135. }
  136. }
  137. # Have to make sure to add the sticky policy here too or it causes
  138. # the listener to lose the sticky policy set above and terraform
  139. # attempts to re-add it on each apply run
  140. resource "aws_load_balancer_listener_policy" "hec_classiclb_listener_443" {
  141. load_balancer_name = aws_elb.hec_classiclb.name
  142. load_balancer_port = 443
  143. policy_names = [
  144. aws_load_balancer_policy.listener_policy-tls-1-2.policy_name,
  145. aws_lb_cookie_stickiness_policy.hec_classiclb_sticky_443.name,
  146. ]
  147. }
  148. # Have to make sure to add the sticky policy here too or it causes
  149. # the listener to lose the sticky policy set above and terraform
  150. # attempts to re-add it on each apply run
  151. resource "aws_load_balancer_listener_policy" "hec_classiclb_listener_8088" {
  152. load_balancer_name = aws_elb.hec_classiclb.name
  153. load_balancer_port = 8088
  154. policy_names = [
  155. aws_load_balancer_policy.listener_policy-tls-1-2.policy_name,
  156. aws_lb_cookie_stickiness_policy.hec_classiclb_sticky_8088.name,
  157. ]
  158. }