data "aws_caller_identity" "current" {}

resource "aws_kms_key" "key" {
  policy                  = data.aws_iam_policy_document.key_policy_document.json
  enable_key_rotation     = var.enable_key_rotation
  deletion_window_in_days = var.deletion_window_in_days
  tags                    = local.tags
}

resource "aws_kms_alias" "alias" {
  target_key_id = aws_kms_key.key.id
  name          = local.alias
}

data "aws_iam_policy_document" "key_policy_document" {
  override_policy_documents = var.key_policy_overrides

  statement {
    sid    = "Allow IAM access"
    effect = "Allow"
    principals {
      type        = "AWS"
      identifiers = [data.aws_caller_identity.current.account_id]
    }
    actions   = ["kms:*"]
    resources = ["*"]
  }

  statement {
    sid    = "Allow AWS Services to describe key"
    effect = "Allow"
    principals {
      type        = "Service"
      identifiers = local.authorized_service_identifiers
    }
    actions   = ["kms:DescribeKey"]
    resources = ["*"]
  }

  statement {
    sid    = "Allow CloudWatch Logs to use key"
    effect = "Allow"
    principals {
      type        = "Service"
      identifiers = local.cloudwatch_logs_service_identifiers
    }
    actions = [
      "kms:Encrypt",
      "kms:Decrypt",
      "kms:ReEncrypt*",
      "kms:GenerateDataKey*",
    ]
    resources = ["*"]
    condition {
      test     = "ArnEquals"
      variable = "kms:EncryptionContext:aws:logs:arn"
      values = formatlist("arn:aws:logs:%s:%s:log-group:%s",
        var.aws_region,
        data.aws_caller_identity.current.account_id,
        var.authorized_cloudwatch_log_groups
      )
    }
  }
}

resource "aws_iam_policy" "iam_kms_decrypt_only_policy" {
  name   = "KMS-${local.name}-decrypt-only-policy"
  policy = data.aws_iam_policy_document.iam_kms_decrypt_only_policy_document.json
  tags   = local.tags
}

data "aws_iam_policy_document" "iam_kms_decrypt_only_policy_document" {
  statement {
    sid    = "AllowDecryptOnly"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
    ]
    resources = [aws_kms_key.key.arn]
  }
}

resource "aws_iam_policy" "iam_kms_encrypt_decrypt_policy" {
  name   = "KMS-${local.name}-encrypt-decrypt-policy"
  policy = data.aws_iam_policy_document.iam_kms_encrypt_decrypt_policy_document.json
  tags   = local.tags
}

data "aws_iam_policy_document" "iam_kms_encrypt_decrypt_policy_document" {
  statement {
    sid    = "AllowEncryptDecrypt"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
      "kms:Encrypt",
      "kms:GenerateDataKey*",
      "kms:ReEncrypt*",
    ]
    resources = [aws_kms_key.key.arn]
  }

  statement {
    sid    = "AllowGrantsForAWS"
    effect = "Allow"
    actions = ["kms:CreateGrant"]
    resources = [aws_kms_key.key.arn]
    condition {
      test     = "Bool"
      variable = "kms:GrantIsForAWSResource"
      values = [true]
    }
  }
}
