Ver Fonte

Applies Best Practices from tfsec for all modules used by modelclient

I'm not turning on static code checking yet, but I'm starting down the
path. The changes in this PR allow all of modelclient to be applied with
the static checking enabled in the root terragrunt.hcl

To be tagged v4.2.0
Fred Damstra [afs macbook] há 3 anos atrás
pai
commit
e77da55456

+ 6 - 0
base/account_standards/default-vpc.tf

@@ -1,8 +1,14 @@
 # Make the default VPC compliant
+# tfsec:ignore:aws-vpc-no-default-vpc - tfsec says "Don't use the default VPC". We're just making a note not to.
 resource "aws_default_vpc" "default" {
   tags = merge(var.standard_tags, var.tags, { "Notes" = "Not connected. For testing only. VPC not for production use." })
 }
 
+resource "aws_kms_key" "default-flowlogs" {
+  enable_key_rotation     = true
+  deletion_window_in_days = 30
+}
+
 resource "aws_flow_log" "default-flowlogs" {
   iam_role_arn    = aws_iam_role.flowlogs.arn
   log_destination = aws_cloudwatch_log_group.vpc_flow_logs.arn

+ 105 - 110
base/account_standards/iam.tf

@@ -10,26 +10,26 @@ resource "aws_iam_instance_profile" "default_instance_profile" {
   role = aws_iam_role.default_instance_role.name
 }
 
+data "aws_iam_policy_document" "default_instance_role" {
+  statement {
+    sid     = "AssumeRoleAnywhere"
+    effect  = "Allow"
+    actions = ["sts:AssumeRole"]
+
+    principals {
+      type = "Service"
+
+      identifiers = [
+        "ec2.amazonaws.com",
+        "ssm.amazonaws.com",
+      ]
+    }
+  }
+}
+
 resource "aws_iam_role" "default_instance_role" {
   name               = "msoc-default-instance-role"
-  assume_role_policy = <<EOF
-{
-    "Version": "2012-10-17",
-    "Statement": [
-      {
-        "Sid": "AssumeRoleAnywhere",
-        "Effect": "Allow",
-        "Principal": {
-          "Service": [
-            "ec2.amazonaws.com",
-            "ssm.amazonaws.com"
-            ]
-        },
-        "Action": "sts:AssumeRole"
-      }
-    ]
-  }
-EOF
+  assume_role_policy = data.aws_iam_policy_document.default_instance_role.json
 }
 
 data "aws_iam_policy_document" "default_instance_policy_doc" {
@@ -241,107 +241,102 @@ locals {
   trusted_principals = var.aws_partition == "aws" ? local.trusted_principals_commercial : local.trusted_principals_govcloud
 }
 
+data "aws_iam_policy_document" "splunk_addon_for_aws_assume_role" {
+  statement {
+    sid     = ""
+    effect  = "Allow"
+    actions = ["sts:AssumeRole"]
+
+    principals {
+      type        = "AWS"
+      identifiers = local.trusted_principals
+    }
+  }
+}
 
 resource "aws_iam_role" "splunk_addon_for_aws" {
   name = "splunk-addon-for-aws"
   path = "/instance/"
 
-  assume_role_policy = <<EOF
-{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Sid": "",
-      "Effect": "Allow",
-      "Principal": {
-        "AWS": ${jsonencode(local.trusted_principals)}
-      },
-      "Action": "sts:AssumeRole"
-    }
-  ]
+  assume_role_policy = data.aws_iam_policy_document.splunk_addon_for_aws_assume_role.json
 }
-EOF
+
+data "aws_iam_policy_document" "policy" {
+  statement {
+    sid       = ""
+    effect    = "Allow"
+    resources = ["*"]
+
+    actions = [
+      "sqs:GetQueueAttributes",
+      "sqs:ListQueues",
+      "sqs:ReceiveMessage",
+      "sqs:GetQueueUrl",
+      "sqs:SendMessage",
+      "sqs:DeleteMessage",
+      "s3:ListBucket",
+      "s3:GetObject",
+      "s3:GetBucketLocation",
+      "s3:ListAllMyBuckets",
+      "s3:GetBucketTagging",
+      "s3:GetAccelerateConfiguration",
+      "s3:GetBucketLogging",
+      "s3:GetLifecycleConfiguration",
+      "s3:GetBucketCORS",
+      "config:DeliverConfigSnapshot",
+      "config:DescribeConfigRules",
+      "config:DescribeConfigRuleEvaluationStatus",
+      "config:GetComplianceDetailsByConfigRule",
+      "config:GetComplianceSummaryByConfigRule",
+      "iam:GetUser",
+      "iam:ListUsers",
+      "iam:GetAccountPasswordPolicy",
+      "iam:ListAccessKeys",
+      "iam:GetAccessKeyLastUsed",
+      "autoscaling:Describe*",
+      "cloudwatch:Describe*",
+      "cloudwatch:Get*",
+      "cloudwatch:List*",
+      "sns:Get*",
+      "sns:List*",
+      "sns:Publish",
+      "logs:DescribeLogGroups",
+      "logs:DescribeLogStreams",
+      "logs:GetLogEvents",
+      "ec2:DescribeInstances",
+      "ec2:DescribeReservedInstances",
+      "ec2:DescribeSnapshots",
+      "ec2:DescribeRegions",
+      "ec2:DescribeKeyPairs",
+      "ec2:DescribeNetworkAcls",
+      "ec2:DescribeSecurityGroups",
+      "ec2:DescribeSubnets",
+      "ec2:DescribeVolumes",
+      "ec2:DescribeVpcs",
+      "ec2:DescribeImages",
+      "ec2:DescribeAddresses",
+      "lambda:ListFunctions",
+      "rds:DescribeDBInstances",
+      "cloudfront:ListDistributions",
+      "elasticloadbalancing:DescribeLoadBalancers",
+      "elasticloadbalancing:DescribeInstanceHealth",
+      "elasticloadbalancing:DescribeTags",
+      "elasticloadbalancing:DescribeTargetGroups",
+      "elasticloadbalancing:DescribeTargetHealth",
+      "elasticloadbalancing:DescribeListeners",
+      "inspector:Describe*",
+      "inspector:List*",
+      "kinesis:Get*",
+      "kinesis:DescribeStream",
+      "kinesis:ListStreams",
+      "kms:Decrypt",
+      "sts:AssumeRole",
+    ]
+  }
 }
 
 resource "aws_iam_role_policy" "splunk_addon_for_aws" {
   name   = "splunk-addon-for-aws"
   role   = aws_iam_role.splunk_addon_for_aws.id
-  policy = <<EOF
-{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Effect": "Allow",
-      "Action": [
-        "sqs:GetQueueAttributes",
-        "sqs:ListQueues",
-        "sqs:ReceiveMessage",
-        "sqs:GetQueueUrl",
-        "sqs:SendMessage",
-        "sqs:DeleteMessage",
-        "s3:ListBucket",
-        "s3:GetObject",
-        "s3:GetBucketLocation",
-        "s3:ListAllMyBuckets",
-        "s3:GetBucketTagging", 
-        "s3:GetAccelerateConfiguration", 
-        "s3:GetBucketLogging", 
-        "s3:GetLifecycleConfiguration", 
-        "s3:GetBucketCORS",
-        "config:DeliverConfigSnapshot",
-        "config:DescribeConfigRules",
-        "config:DescribeConfigRuleEvaluationStatus",
-        "config:GetComplianceDetailsByConfigRule",
-        "config:GetComplianceSummaryByConfigRule",
-        "iam:GetUser",
-        "iam:ListUsers",
-        "iam:GetAccountPasswordPolicy",
-        "iam:ListAccessKeys",
-        "iam:GetAccessKeyLastUsed", 
-        "autoscaling:Describe*",
-        "cloudwatch:Describe*",
-        "cloudwatch:Get*",
-        "cloudwatch:List*",
-        "sns:Get*",
-        "sns:List*",
-        "sns:Publish",
-        "logs:DescribeLogGroups",
-        "logs:DescribeLogStreams",
-        "logs:GetLogEvents",
-        "ec2:DescribeInstances",
-        "ec2:DescribeReservedInstances",
-        "ec2:DescribeSnapshots",
-        "ec2:DescribeRegions",
-        "ec2:DescribeKeyPairs",
-        "ec2:DescribeNetworkAcls",
-        "ec2:DescribeSecurityGroups",
-        "ec2:DescribeSubnets",
-        "ec2:DescribeVolumes",
-        "ec2:DescribeVpcs",
-        "ec2:DescribeImages",
-        "ec2:DescribeAddresses",
-        "lambda:ListFunctions",
-        "rds:DescribeDBInstances",
-        "cloudfront:ListDistributions",
-        "elasticloadbalancing:DescribeLoadBalancers",
-        "elasticloadbalancing:DescribeInstanceHealth",
-        "elasticloadbalancing:DescribeTags",
-        "elasticloadbalancing:DescribeTargetGroups",
-        "elasticloadbalancing:DescribeTargetHealth",
-        "elasticloadbalancing:DescribeListeners",
-        "inspector:Describe*",
-        "inspector:List*",
-        "kinesis:Get*",
-        "kinesis:DescribeStream",
-        "kinesis:ListStreams",
-        "kms:Decrypt",
-        "sts:AssumeRole"
-      ],
-      "Resource": [
-        "*"
-      ]
-    }
-  ]
-}
-EOF
+  policy = data.aws_iam_policy_document.policy.json
 }

+ 13 - 1
base/kinesis_firehose_waf_logs/main.tf

@@ -42,6 +42,8 @@ resource "aws_cloudwatch_log_stream" "kinesis" {
   name           = "aws-waf-logs-splunk"
   log_group_name = aws_cloudwatch_log_group.kinesis.name
 }
+
+# tfsec:ignore:aws-s3-enable-bucket-logging Don't log the logs
 resource "aws_s3_bucket" "aws-waf-logs-splunk" {
   bucket = "aws-waf-logs-splunk-${var.environment}-${var.account_name}"
 
@@ -53,6 +55,7 @@ resource "aws_s3_bucket_acl" "s3_acl_aws-waf-logs-splunk" {
   acl    = "private"
 }
 
+# tfsec:ignore:aws-s3-enable-versioning No versioning on logging buckets
 resource "aws_s3_bucket_versioning" "s3_version_aws-waf-logs-splunk" {
   bucket = aws_s3_bucket.aws-waf-logs-splunk.id
 
@@ -72,6 +75,15 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "s3_sse_aws-waf-lo
   }
 }
 
+resource "aws_s3_bucket_public_access_block" "aws-waf-logs-splunk" {
+  bucket = aws_s3_bucket.aws-waf-logs-splunk.id
+
+  block_public_acls       = true
+  block_public_policy     = true
+  ignore_public_acls      = true
+  restrict_public_buckets = true
+}
+
 resource "aws_kms_key" "aws-waf-logs-splunk" {
   description             = "KMS Key for Failed AWS Kinesis Transmission to the HEC"
   deletion_window_in_days = 10
@@ -230,4 +242,4 @@ EOF
 
   tags   = merge(var.standard_tags, var.tags, { "Purpose" = "Failed events from AWS Kinesis" })
 }
-*/
+*/

+ 6 - 1
base/sensu/main.tf

@@ -30,7 +30,7 @@ resource "aws_instance" "instance" {
   instance_initiated_shutdown_behavior = "stop"
   instance_type                        = var.instance_type
   key_name                             = "msoc-build"
-  monitoring                           = false
+  monitoring                           = true
   iam_instance_profile                 = "msoc-default-instance-profile"
 
   ami = local.ami_map[local.ami_selection]
@@ -39,6 +39,11 @@ resource "aws_instance" "instance" {
   # that could be removed.
   lifecycle { ignore_changes = [ami, key_name, user_data, ebs_block_device] }
 
+  metadata_options {
+    http_endpoint = "enabled"
+    http_tokens   = "required"
+  }
+
   # These device definitions are optional, but added for clarity.
   root_block_device {
     volume_type = "gp3"

+ 6 - 6
base/sensu/private_elb.tf

@@ -12,12 +12,12 @@ locals {
 #----------------------------------------------------------------------------
 
 resource "aws_alb" "sensu_internal" {
-  name               = "sensu-alb-internal-${var.environment}"
-  security_groups    = [aws_security_group.sensu_alb_server_internal.id]
-  internal           = true
-  subnets            = var.private_subnets
-  load_balancer_type = "application"
-
+  name                       = "sensu-alb-internal-${var.environment}"
+  security_groups            = [aws_security_group.sensu_alb_server_internal.id]
+  internal                   = true
+  subnets                    = var.private_subnets
+  load_balancer_type         = "application"
+  drop_invalid_header_fields = true
 
   access_logs {
     bucket  = "xdr-elb-${var.environment}"

+ 2 - 1
base/splunk_servers/app_s3_bucket/main.tf

@@ -15,6 +15,7 @@ resource "aws_s3_bucket_acl" "s3_acl_bucket" {
   acl    = "private"
 }
 
+# tfsec:ignore:aws-s3-enable-versioning no versioning needed
 resource "aws_s3_bucket_versioning" "s3_version_bucket" {
   bucket = aws_s3_bucket.bucket.id
   versioning_configuration {
@@ -136,4 +137,4 @@ resource "aws_s3_bucket_policy" "policy" {
     }
   }
 }
-*/
+*/

+ 5 - 0
base/splunk_servers/cluster_master/main.tf

@@ -35,6 +35,11 @@ resource "aws_instance" "instance" {
   monitoring                           = false
   iam_instance_profile                 = module.instance_profile.profile_id
 
+  metadata_options {
+    http_tokens = "required"
+  }
+
+
   ami = local.ami_map[local.ami_selection]
   # We need to ignore ebs_block_device changes, because if the AMI changes, so does the snapshot_id.
   # If they add a feature to block more specific changes (eg `ebs_block_devices[*].snapshot_id`), then

+ 9 - 5
base/splunk_servers/customer_searchhead/elb.tf

@@ -13,13 +13,14 @@ locals {
 
 resource "aws_lb" "searchhead-alb" {
   name               = local.alb_name
-  internal           = false
+  internal           = false # tfsec:ignore:aws-elb-alb-not-public Intentionally public
   load_balancer_type = "application"
   # Not supported for NLB
   security_groups = [aws_security_group.searchhead-alb-sg.id]
   # Note, changing subnets results in recreation of the resource
   subnets                          = var.public_subnets
   enable_cross_zone_load_balancing = true
+  drop_invalid_header_fields       = true
 
   access_logs {
     bucket  = "xdr-elb-${var.environment}"
@@ -102,6 +103,7 @@ resource "aws_security_group" "searchhead-alb-sg" {
 }
 
 resource "aws_security_group_rule" "searchhead-alb-https-in" {
+  description       = "HTTPS in"
   type              = "ingress"
   from_port         = 443
   to_port           = 443
@@ -112,6 +114,7 @@ resource "aws_security_group_rule" "searchhead-alb-https-in" {
 
 resource "aws_security_group_rule" "searchhead-http-in" {
   # Port 80 is open as a redirect to 443
+  description       = "Allow redirect from 80 to 443"
   type              = "ingress"
   from_port         = 80
   to_port           = 80
@@ -121,10 +124,11 @@ resource "aws_security_group_rule" "searchhead-http-in" {
 }
 
 resource "aws_security_group_rule" "searchhead-alb-8000-out" {
-  type      = "egress"
-  from_port = 8000
-  to_port   = 8000
-  protocol  = "tcp"
+  description = "Allow outbound to default splunk web"
+  type        = "egress"
+  from_port   = 8000
+  to_port     = 8000
+  protocol    = "tcp"
   # Maybe should limit to the local vpc, but I don't readily have that cidr available
   cidr_blocks       = [var.vpc_cidr]
   security_group_id = aws_security_group.searchhead-alb-sg.id

+ 4 - 0
base/splunk_servers/customer_searchhead/main.tf

@@ -37,6 +37,10 @@ resource "aws_instance" "instance" {
   monitoring                           = false
   iam_instance_profile                 = module.instance_profile.profile_id
 
+  metadata_options {
+    http_tokens = "required"
+  }
+
   ami = local.ami_map[local.ami_selection]
   # We need to ignore ebs_block_device changes, because if the AMI changes, so does the snapshot_id.
   # If they add a feature to block more specific changes (eg `ebs_block_devices[*].snapshot_id`), then

+ 2 - 1
base/splunk_servers/frozen_s3_bucket/main.tf

@@ -15,6 +15,7 @@ resource "aws_s3_bucket_acl" "s3_acl_bucket" {
   acl    = "private"
 }
 
+# tfsec:ignore:aws-s3-enable-versioning We don't version frozen data
 resource "aws_s3_bucket_versioning" "s3_version_bucket" {
   bucket = aws_s3_bucket.bucket.id
   versioning_configuration {
@@ -149,4 +150,4 @@ POLICY
     }
   }
 }
-*/
+*/

+ 6 - 0
base/splunk_servers/heavy_forwarder/main.tf

@@ -35,6 +35,12 @@ resource "aws_instance" "instance" {
   monitoring                           = false
   iam_instance_profile                 = module.instance_profile.profile_id
 
+  # tfsec:ignore:aws-ec2-enforce-http-token-imds TODO: Test if HF works with tokens. Not willing to introduce a possible breaking change here.
+  metadata_options {
+    http_tokens = "optional"
+  }
+
+
   ami = local.ami_map[local.ami_selection]
   # We need to ignore ebs_block_device changes, because if the AMI changes, so does the snapshot_id.
   # If they add a feature to block more specific changes (eg `ebs_block_devices[*].snapshot_id`), then

+ 3 - 2
base/splunk_servers/indexer_cluster/elb-with-acks.tf

@@ -69,8 +69,9 @@ resource "aws_elb" "hec_classiclb" {
   tags            = merge(var.standard_tags, var.tags)
   name            = "${var.prefix}-hec-classic"
   security_groups = [aws_security_group.hec_elb_security_group.id]
-  subnets         = var.public_subnets
-  internal        = false
+  # tflint-ignore: aws_elb_invalid_subnet - Incorrectly errors out that these are invalid
+  subnets  = var.public_subnets
+  internal = false # tfsec:ignore:aws-elb-alb-not-public This is intentionally public
 
   listener {
     instance_port      = 8088

+ 7 - 6
base/splunk_servers/indexer_cluster/elb-without-ack.tf

@@ -42,12 +42,13 @@ resource "aws_route53_record" "hec_cert_validation" {
 #########################
 # ELB
 resource "aws_lb" "hec" {
-  tags               = merge(var.standard_tags, var.tags)
-  name               = "${var.prefix}-hec"
-  load_balancer_type = "application"
-  security_groups    = [aws_security_group.hec_elb_security_group.id]
-  subnets            = var.public_subnets
-  internal           = false
+  tags                       = merge(var.standard_tags, var.tags)
+  name                       = "${var.prefix}-hec"
+  load_balancer_type         = "application"
+  security_groups            = [aws_security_group.hec_elb_security_group.id]
+  subnets                    = var.public_subnets
+  internal                   = false # tfsec:ignore:aws-elb-alb-not-public ELB is intentionally public
+  drop_invalid_header_fields = true
 
   # Access logs are a feedback loop. They create logs that are then sent back through the HEC.
   # They should remain disabled.

+ 1 - 1
base/splunk_servers/indexer_cluster/nlb-for-hec.tf

@@ -30,7 +30,7 @@ resource "aws_lb" "hec_static" {
   tags               = merge(var.standard_tags, var.tags)
   name               = "${var.prefix}-hec-static"
   load_balancer_type = "network"
-  internal           = false
+  internal           = false # tfsec:ignore:aws-elb-alb-not-public LB is intentionally public
 
   subnet_mapping {
     subnet_id     = var.public_subnets[0]

+ 1 - 1
base/splunk_servers/indexer_cluster/nlb-splunk-data.tf

@@ -23,7 +23,7 @@ module "public_dns_record_nlb" {
 resource "aws_lb" "nlb" {
   tags               = merge(var.standard_tags, var.tags, { "Name" : "${var.prefix}-splunk-indexers-nlb" })
   name               = "${var.prefix}-splunk-indexers-nlb"
-  internal           = false
+  internal           = false # tfsec:ignore:aws-elb-alb-not-public
   load_balancer_type = "network"
   #subnets            = data.terraform_remote_state.infra.public_subnets
 

+ 2 - 2
base/splunk_servers/indexer_cluster/security-group-elbs.tf

@@ -28,7 +28,7 @@ resource "aws_security_group_rule" "hec-https-in" {
   from_port         = 443
   to_port           = 443
   protocol          = "tcp"
-  cidr_blocks       = ["0.0.0.0/0"]
+  cidr_blocks       = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-ingress-sgr
   security_group_id = aws_security_group.hec_elb_security_group.id
 }
 
@@ -38,7 +38,7 @@ resource "aws_security_group_rule" "hec-in" {
   from_port         = 8088
   to_port           = 8088
   protocol          = "tcp"
-  cidr_blocks       = ["0.0.0.0/0"]
+  cidr_blocks       = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-ingress-sgr
   security_group_id = aws_security_group.hec_elb_security_group.id
 }
 

+ 15 - 8
base/splunk_servers/searchhead/elb.tf

@@ -16,6 +16,7 @@ resource "aws_lb" "searchhead-alb" {
   # Note, changing subnets results in recreation of the resource
   subnets                          = var.subnets
   enable_cross_zone_load_balancing = true
+  drop_invalid_header_fields       = true
 
   access_logs {
     bucket  = "xdr-elb-${var.environment}"
@@ -150,6 +151,7 @@ resource "aws_security_group" "searchhead-alb-sg" {
 }
 
 resource "aws_security_group_rule" "searchhead-alb-api-in" {
+  description       = "SH ALB API In"
   type              = "ingress"
   from_port         = 8089
   to_port           = 8089
@@ -159,6 +161,7 @@ resource "aws_security_group_rule" "searchhead-alb-api-in" {
 }
 
 resource "aws_security_group_rule" "searchhead-alb-https-in" {
+  description       = "SH HTTPS Inbound"
   type              = "ingress"
   from_port         = 443
   to_port           = 443
@@ -168,6 +171,7 @@ resource "aws_security_group_rule" "searchhead-alb-https-in" {
 }
 
 resource "aws_security_group_rule" "searchhead-alb-8000-in" {
+  description       = "SH web port inbound"
   type              = "ingress"
   from_port         = 8000
   to_port           = 8000
@@ -178,6 +182,7 @@ resource "aws_security_group_rule" "searchhead-alb-8000-in" {
 
 resource "aws_security_group_rule" "searchhead-http-in" {
   # Port 80 is open as a redirect to 443
+  description       = "SH Redirect 80 to 443"
   type              = "ingress"
   from_port         = 80
   to_port           = 80
@@ -187,20 +192,22 @@ resource "aws_security_group_rule" "searchhead-http-in" {
 }
 
 resource "aws_security_group_rule" "searchhead-alb-8000-out" {
-  type      = "egress"
-  from_port = 8000
-  to_port   = 8000
-  protocol  = "tcp"
+  description = "SH outbound on default http port"
+  type        = "egress"
+  from_port   = 8000
+  to_port     = 8000
+  protocol    = "tcp"
   # Maybe should limit to the local vpc, but I don't readily have that cidr available
   cidr_blocks       = ["10.0.0.0/8"]
   security_group_id = aws_security_group.searchhead-alb-sg.id
 }
 
 resource "aws_security_group_rule" "searchhead-alb-api-out" {
-  type      = "egress"
-  from_port = 8089
-  to_port   = 8089
-  protocol  = "tcp"
+  description = "SH API outbound"
+  type        = "egress"
+  from_port   = 8089
+  to_port     = 8089
+  protocol    = "tcp"
   # Maybe should limit to the local vpc, but I don't readily have that cidr available
   cidr_blocks       = ["10.0.0.0/8"]
   security_group_id = aws_security_group.searchhead-alb-sg.id

+ 4 - 0
base/splunk_servers/searchhead/main.tf

@@ -38,6 +38,10 @@ resource "aws_instance" "instance" {
   monitoring                           = false
   iam_instance_profile                 = local.is_moose ? module.moose_instance_profile[0].profile_id : "splunk-sh-instance-profile"
 
+  metadata_options {
+    http_tokens = "required"
+  }
+
   ami = local.ami_map[local.ami_selection]
   # We need to ignore ebs_block_device changes, because if the AMI changes, so does the snapshot_id.
   # If they add a feature to block more specific changes (eg `ebs_block_devices[*].snapshot_id`), then

+ 4 - 1
base/standard_vpc/security-groups.tf

@@ -6,6 +6,7 @@ locals {
   endpoint_cidr_blocks = var.allow_any_to_endpoints ? ["10.0.0.0/8"] : [module.vpc.vpc_cidr_block]
 }
 
+# tfsec:ignore:aws-vpc-no-public-egress-sgr We allow outbound to select IPs
 module "aws_endpoints_sg" {
   use_name_prefix = false
   source          = "terraform-aws-modules/security-group/aws"
@@ -23,7 +24,7 @@ module "aws_endpoints_sg" {
 }
 
 
-# "Allow
+# tfsec:ignore:aws-vpc-no-public-egress-sgr We allow outbound to select IPs
 module "allow_all_from_trusted_sg" {
   use_name_prefix = false
   source          = "terraform-aws-modules/security-group/aws"
@@ -38,6 +39,7 @@ module "allow_all_from_trusted_sg" {
   egress_rules        = ["all-all"]
 }
 
+# tfsec:ignore:aws-vpc-no-public-egress-sgr We allow outbound to select IPs
 module "allow_all_outbound_sg" {
   use_name_prefix = false
   source          = "terraform-aws-modules/security-group/aws"
@@ -49,6 +51,7 @@ module "allow_all_outbound_sg" {
   egress_rules = ["all-all"]
 }
 
+# tfsec:ignore:aws-vpc-no-public-egress-sgr We allow outbound to select IPs
 module "typical_host_security_group" {
   source = "../../submodules/security_group/typical_host"
 

+ 1 - 1
submodules/dns/private_A_record/main.tf

@@ -24,7 +24,7 @@ resource "aws_route53_record" "dns" {
   type     = "A"
   ttl      = 300
   zone_id  = var.dns_info["private"]["zone_id"]
-  records  = var.ip_addresses
+  records  = var.ip_addresses #checkov:skip=CKV2_AWS_23:IP Address Passed in from external resources
   provider = aws.c2
 }
 

+ 1 - 0
submodules/dns/public_ALIAS_record/main.tf

@@ -5,6 +5,7 @@ resource "aws_route53_record" "dns" {
   type    = "A"
   zone_id = var.dns_info["public"]["zone_id"]
 
+  #checkov:skip=CKV2_AWS_23:Resource Information is Passed into Module
   alias {
     name                   = var.target_dns_name
     zone_id                = var.target_zone_id

+ 3 - 0
submodules/iam/standard_iam_policies/policy-mdr_engineer.tf

@@ -35,6 +35,8 @@ data "aws_iam_policy_document" "mdr_engineer" {
       "*",
     ]
   }
+
+  #tfsec:ignore:aws-iam-no-policy-wildcards
   statement {
     effect = "Allow"
     actions = [
@@ -56,6 +58,7 @@ data "aws_iam_policy_document" "mdr_engineer" {
       "sts:AssumeRole"
     ]
 
+    #tfsec:ignore:aws-iam-no-policy-wildcards
     resources = [
       "arn:${local.aws_partition}:iam::*:role/user/mdr_engineer",
       "arn:${local.aws_partition}:iam::*:role/mdr_engineer",

+ 6 - 5
submodules/load_balancer/static_nlb_to_alb/elb.tf

@@ -2,11 +2,12 @@
 # EXTERNAL LB
 #----------------------------------------------------------------------------
 resource "aws_lb" "external" {
-  name_prefix        = substr("${var.name}-ext-lb", 0, 6)
-  security_groups    = [aws_security_group.lb_server_external.id]
-  internal           = false
-  subnets            = var.public_subnets
-  load_balancer_type = "application"
+  name_prefix                = substr("${var.name}-ext-lb", 0, 6)
+  security_groups            = [aws_security_group.lb_server_external.id]
+  internal                   = false #tfsec:ignore:aws-elb-alb-not-public
+  subnets                    = var.public_subnets
+  load_balancer_type         = "application"
+  drop_invalid_header_fields = true
 
   access_logs {
     bucket  = "xdr-elb-${var.environment}"

+ 6 - 4
submodules/load_balancer/static_nlb_to_alb/nlb.tf

@@ -2,7 +2,8 @@
 # EIP
 resource "aws_eip" "static" {
   count = 2
-  vpc   = true
+  #checkov:skip=CKV2_AWS_19:These EIPs are attached to the NLB
+  vpc = true
 
   tags = merge(var.tags, { Name = "${var.name}-nlb-external-${var.environment}" })
 }
@@ -10,9 +11,10 @@ resource "aws_eip" "static" {
 #########################
 # ELB
 resource "aws_lb" "static" {
-  name_prefix        = substr("${var.name}-static", 0, 6)
-  load_balancer_type = "network"
-  internal           = false
+  name_prefix                      = substr("${var.name}-static", 0, 6)
+  load_balancer_type               = "network"
+  internal                         = false #tfsec:ignore:aws-elb-alb-not-public
+  enable_cross_zone_load_balancing = true
 
   subnet_mapping {
     subnet_id     = var.public_subnets[0]

+ 1 - 1
submodules/security_group/typical_host/main.tf

@@ -81,7 +81,7 @@ resource "aws_security_group_rule" "ping_outbound" {
   from_port         = -1
   to_port           = -1
   protocol          = "icmp"
-  cidr_blocks       = ["0.0.0.0/0"]
+  cidr_blocks       = ["0.0.0.0/0"] # tfsec:ignore:aws-vpc-no-public-egress-sgr
 }
 
 resource "aws_security_group_rule" "github_access_ssh" {

+ 5 - 0
submodules/splunk/splunk_indexer_asg/main.tf

@@ -36,6 +36,11 @@ resource "aws_launch_template" "splunk_indexer" {
   ebs_optimized = true
   tags          = var.tags
 
+  metadata_options {
+    http_endpoint = "enabled"
+    http_tokens   = "required"
+  }
+
   network_interfaces {
     associate_public_ip_address = false
     delete_on_termination       = true

+ 10 - 1
thirdparty/terraform-aws-kinesis-firehose-splunk/main.tf

@@ -48,6 +48,7 @@ resource "aws_kinesis_firehose_delivery_stream" "kinesis_firehose" {
 }
 
 # S3 Bucket for Kinesis Firehose s3_backup_mode
+# tfsec:ignore:aws-s3-enable-bucket-logging tfsec:ignore:aws-s3-enable-versioning
 resource "aws_s3_bucket" "kinesis_firehose_s3_bucket" {
   bucket = var.s3_bucket_name
 
@@ -59,12 +60,19 @@ resource "aws_s3_bucket_acl" "kinesis_firehose_s3_bucket" {
   acl    = "private"
 }
 
+resource "aws_kms_key" "kinesis_firehose_s3_bucket" {
+  enable_key_rotation     = true
+  deletion_window_in_days = 30
+  tags                    = var.tags
+}
+
 resource "aws_s3_bucket_server_side_encryption_configuration" "kinesis_firehose_s3_bucket" {
   bucket = aws_s3_bucket.kinesis_firehose_s3_bucket.id
 
   rule {
     apply_server_side_encryption_by_default {
-      sse_algorithm = "AES256"
+      kms_master_key_id = aws_kms_key.kinesis_firehose_s3_bucket.arn
+      sse_algorithm     = "aws:kms"
     }
   }
 }
@@ -105,6 +113,7 @@ resource "aws_s3_bucket_public_access_block" "kinesis_firehose_s3_bucket" {
 }
 
 # Cloudwatch logging group for Kinesis Firehose
+# tfsec:ignore:aws-cloudwatch-log-group-customer-key # OK to use AWS key for this
 resource "aws_cloudwatch_log_group" "kinesis_logs" {
   name              = "/aws/kinesisfirehose/${var.firehose_name}"
   retention_in_days = var.cloudwatch_log_retention