# The centralized bucket for AWS config
module "xdr_config_logging_bucket" {
  source = "../../thirdparty/terraform-aws-s3logging-bucket"

  bucket_name = "xdr-config-${var.environment}-access-logs"
  lifecycle_rules = [
    {
      id                            = "expire-old-logs"
      enabled                       = true
      prefix                        = ""
      expiration                    = 30
      noncurrent_version_expiration = 30
      abort_incomplete_multipart_upload_days = 7
    }
  ]
  tags = merge(var.standard_tags, var.tags)
  versioning_enabled = true
}

resource "aws_s3_bucket" "xdr_config_bucket" {
  bucket = "xdr-config-${var.environment}"
  acl    = "private"
  tags   = merge(var.standard_tags, var.tags)

  versioning {
    enabled = true
  }

  logging {
    target_bucket = module.xdr_config_logging_bucket.s3_bucket_name
    target_prefix = "${var.aws_account_id}-${var.aws_region}-awsconfig/"
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "aws:kms"
        kms_master_key_id = aws_kms_key.config_encryption.arn
      }
    }
  }
}

resource "aws_s3_bucket_public_access_block" "awsconfig_bucket_block_public_access" {
  block_public_acls       = true
  block_public_policy     = true
  bucket                  = aws_s3_bucket.xdr_config_bucket.id
  ignore_public_acls      = true
  restrict_public_buckets = true
}

data "aws_iam_policy_document" "awsconfig_bucket_policy" {
  statement {
    sid = "AWSConfigBucketPermissionsCheck"
    effect = "Allow"
    principals {
      type = "Service"
      identifiers = [ "config.amazonaws.com" ]
    }
    actions = [ "s3:GetBucketAcl" ]
    resources = [ aws_s3_bucket.xdr_config_bucket.arn ]
  }
  statement {
    sid = "AWSConfigBucketExistenceCheck"
    effect = "Allow"
    principals {
      type = "Service"
      identifiers = [ "config.amazonaws.com" ]
    }
    actions = [ "s3:ListBucket" ]
    resources = [ aws_s3_bucket.xdr_config_bucket.arn ]
  }
  statement {
    sid = "AWSConfigBucketDelivery"
    effect = "Allow"
    principals {
      type = "Service"
      identifiers = [ "config.amazonaws.com" ]
    }
    actions = [ "s3:PutObject" ]
    resources = [ "${aws_s3_bucket.xdr_config_bucket.arn}/AWSLogs/*" ]
    condition {
      test = "StringEquals"
      variable = "s3:x-amz-acl"
      values = [ "bucket-owner-full-control" ]
    }
  }
}

resource "aws_s3_bucket_policy" "awsconfig_bucket_policy" {
  bucket = aws_s3_bucket.xdr_config_bucket.id
  policy = data.aws_iam_policy_document.awsconfig_bucket_policy.json

  # Ordering bug, see https://github.com/terraform-providers/terraform-provider-aws/issues/7628
  depends_on = [ aws_s3_bucket_public_access_block.awsconfig_bucket_block_public_access ]
}

resource "aws_kms_key" "config_encryption" {
  description             = "This key is used to encrypt AWS config"
  deletion_window_in_days = 30
  policy = data.aws_iam_policy_document.config_encryption_key_policy.json
  enable_key_rotation = true
  tags = merge(var.standard_tags, var.tags)
}

resource "aws_kms_alias" "config_encryption" {
  name          = "alias/aws_config"
  target_key_id = aws_kms_key.config_encryption.key_id
}

data "aws_iam_policy_document" "config_encryption_key_policy" {
  statement {
    actions   = ["kms:*"]
    effect    = "Allow"
    resources = ["*"]

    principals {
      type        = "AWS"
      identifiers = ["arn:${var.aws_partition}:iam::${var.aws_account_id}:root"]
    }
  }

  statement {
    actions   = ["kms:GenerateDataKey*"]
    effect    = "Allow"
    resources = ["*"]

    principals {
      type        = "Service"
      identifiers = ["config.amazonaws.com"]
    }
  }

  statement {
    actions = [
      "kms:Encrypt*",
      "kms:Decrypt*",
      "kms:ReEncrypt*",
      "kms:GenerateDataKey*",
      "kms:Describe*",
    ]
    effect    = "Allow"
    resources = ["*"]

    principals {
      type        = "Service"
      identifiers = ["config.amazonaws.com"]
    }
  }

  statement {
    actions   = ["kms:Describe*"]
    effect    = "Allow"
    resources = ["*"]

    principals {
      type        = "Service"
      identifiers = ["config.amazonaws.com"]
    }
  }
}
