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"
#           ]
#        }
}
