Browse Source

Merge pull request #52 from mdr-engineering/feature/ftd_MSOCI-1412_WAF_Firehose

Sets up a kinesis firehose to send WAF logs to the HEC
Frederick Damstra 5 years ago
parent
commit
7b79fb3fb4

+ 203 - 0
base/kinesis_firehose_waf_logs/main.tf

@@ -0,0 +1,203 @@
+resource "aws_kinesis_firehose_delivery_stream" "aws-waf-logs-splunk" {
+  name        = "aws-waf-logs-splunk"
+  destination = "splunk"
+
+  server_side_encryption {
+    enabled = true
+  }
+
+  s3_configuration {
+    role_arn           = aws_iam_role.aws-waf-logs-splunk.arn
+    bucket_arn         = aws_s3_bucket.aws-waf-logs-splunk.arn
+    buffer_size        = 10
+    buffer_interval    = 400
+    compression_format = "GZIP"
+    kms_key_arn        = aws_kms_key.aws-waf-logs-splunk.arn
+  }
+
+  splunk_configuration {
+    hec_endpoint               = "https://${var.hec_pub}:8088"
+    hec_token                  = var.aws_waf_logs_hec_token
+    hec_acknowledgment_timeout = 600
+    hec_endpoint_type          = "Raw"
+    s3_backup_mode             = "FailedEventsOnly"
+    cloudwatch_logging_options {
+      enabled = true
+      log_group_name = "kinesis"
+      log_stream_name = "aws-waf-logs-splunk"
+    }
+  }
+
+
+  tags = merge(var.standard_tags, var.tags)
+}
+
+resource "aws_cloudwatch_log_group" "kinesis" {
+  name = "kinesis"
+  retention_in_days = 7
+  kms_key_id = var.cloudtrail_key_arn
+  tags = merge(var.standard_tags, var.tags)
+}
+
+resource "aws_cloudwatch_log_stream" "kinesis" {
+  name           = "aws-waf-logs-splunk"
+  log_group_name = aws_cloudwatch_log_group.kinesis.name
+}
+
+resource "aws_s3_bucket" "aws-waf-logs-splunk" {
+  bucket = "aws-waf-logs-splunk-${var.environment}-${var.account_name}"
+  acl    = "private"
+
+  versioning { enabled = false }
+
+  server_side_encryption_configuration {
+    rule {
+      apply_server_side_encryption_by_default {
+        kms_master_key_id = aws_kms_key.aws-waf-logs-splunk.arn
+        sse_algorithm     = "aws:kms"
+      }
+    }
+  }
+
+  tags   = merge(var.standard_tags, var.tags, { "Purpose" = "Failed events from AWS Kinesis" })
+}
+
+resource "aws_kms_key" "aws-waf-logs-splunk" {
+  description             = "KMS Key for Failed AWS Kinesis Transmission to the HEC"
+  deletion_window_in_days = 10
+  enable_key_rotation     = true
+  policy                  = data.aws_iam_policy_document.aws-waf-logs-splunk.json
+
+  tags   = merge(var.standard_tags, var.tags, { "Purpose" = "Failed events from AWS Kinesis" })
+}
+
+data "aws_iam_policy_document" "aws-waf-logs-splunk" {
+  statement {
+    sid = "AllowThisAccount"
+    effect = "Allow"
+    principals {
+      identifiers = ["arn:${var.aws_partition}:iam::${var.aws_account_id}:root"]
+      type = "AWS"
+    }
+    actions = [
+      "kms:*"
+    ]
+    resources = ["*"]
+  }
+  statement {
+    sid = "AllowKinesis"
+    effect = "Allow"
+    principals {
+      identifiers = ["firehose.amazonaws.com"]
+      type = "Service"
+    }
+    actions = [
+      "kms:GenerateDataKey",
+      "kms:Decrypt"
+    ]
+    resources = [ "*" ]
+  }
+}
+
+
+resource "aws_iam_role" "aws-waf-logs-splunk" {
+  name = "aws-waf-logs-splunk"
+  path = "/aws_services/"
+
+  assume_role_policy = <<EOF
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Sid": "",
+      "Effect": "Allow",
+      "Principal": {
+        "Service": "firehose.amazonaws.com"
+      },
+      "Action": "sts:AssumeRole"
+    }
+  ]
+}
+EOF
+
+  tags = merge(var.standard_tags, var.tags)
+}
+
+resource "aws_iam_role_policy" "aws-waf-logs-splunk" {
+  name = "aws-waf-logs-splunk"
+  role = aws_iam_role.aws-waf-logs-splunk.id
+
+  # From https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html#using-iam-splunk
+  policy = <<-EOF
+{
+    "Version": "2012-10-17",
+    "Statement":
+    [
+        {
+            "Effect": "Allow",
+            "Action": [
+                "s3:AbortMultipartUpload",
+                "s3:GetBucketLocation",
+                "s3:GetObject",
+                "s3:ListBucket",
+                "s3:ListBucketMultipartUploads",
+                "s3:PutObject"
+            ],
+            "Resource": [
+                "${aws_s3_bucket.aws-waf-logs-splunk.arn}",
+                "${aws_s3_bucket.aws-waf-logs-splunk.arn}/*"
+            ]
+        },
+        {
+           "Effect": "Allow",
+           "Action": [
+               "kms:Decrypt",
+               "kms:GenerateDataKey"
+           ],
+           "Resource": [
+               "${aws_kms_key.aws-waf-logs-splunk.arn}"
+           ],
+           "Condition": {
+               "StringEquals": {
+                   "kms:ViaService": "s3.${var.aws_region}.amazonaws.com"
+               },
+               "StringLike": {
+                   "kms:EncryptionContext:aws:s3:arn": "${aws_s3_bucket.aws-waf-logs-splunk.arn}/*"
+               }
+           }
+        },
+        {
+           "Effect": "Allow",
+           "Action": [
+               "kinesis:DescribeStream",
+               "kinesis:GetShardIterator",
+               "kinesis:GetRecords",
+               "kinesis:ListShards"
+           ],
+           "Resource": "${aws_kinesis_firehose_delivery_stream.aws-waf-logs-splunk.arn}"
+        },
+        {
+           "Effect": "Allow",
+           "Action": [
+               "logs:PutLogEvents"
+           ],
+           "Resource": [
+             "arn:${var.aws_partition}:logs:${var.aws_region}:${var.aws_account_id}:log-group:kinesis:*"
+           ]
+        }
+    ]
+}
+EOF
+# Removed from above policy as I think it's unneeded
+#        ,
+#        {
+#           "Effect": "Allow",
+#           "Action": [
+#               "lambda:InvokeFunction",
+#               "lambda:GetFunctionConfiguration"
+#           ],
+#           "Resource": [
+#               "arn:aws:lambda:region:account-id:function:function-name:function-version"
+#           ]
+#        }
+}

+ 0 - 0
base/kinesis_firehose_waf_logs/outputs.tf


+ 17 - 0
base/kinesis_firehose_waf_logs/vars.tf

@@ -0,0 +1,17 @@
+variable "tags" {
+  description = "Tags to add to the resource (in addition to global standard tags)"
+  type        = map
+  default     = { }
+}
+
+variable "cloudtrail_key_arn" { type = string }
+variable "aws_waf_logs_hec_token" { type = string }
+variable "hec_pub" { type = string }
+variable "standard_tags" { type = map }
+variable "account_name" { type = string }
+variable "aws_account_id" { type = string }
+variable "aws_partition_alias" { type = string }
+variable "environment" { type = string }
+variable "account_map" { type = map }
+variable "aws_region" { type = string }
+variable "aws_partition" { type = string }

+ 3 - 0
base/kinesis_firehose_waf_logs/version.tf

@@ -0,0 +1,3 @@
+terraform {
+  required_version = "~> 0.12"
+}