# Resources for Cloud Cost Management integration.
# Note that it is currently not possible to Terraform the Datadog configuration so this needs to be done manually for now.
# There is an open feature request to add support for this: https://github.com/DataDog/terraform-provider-datadog/issues/2051

data "aws_iam_policy_document" "cloud_cost_bucket_policy" {
  count = var.cloud_cost_management_config.enabled ? 1 : 0

  statement {
    actions = [
      "s3:GetBucketPolicy",
      "s3:PutObject",
    ]

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

    resources = [
      module.cloud_cost_bucket[0].s3_bucket_arn_output,
      "${module.cloud_cost_bucket[0].s3_bucket_arn_output}/*"
    ]

    condition {
      test     = "StringEquals"
      variable = "aws:SourceAccount"
      values   = [data.aws_caller_identity.current.account_id]
    }

    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = ["arn:aws:cur:us-east-1:${data.aws_caller_identity.current.account_id}:definition/*"]
    }
  }
}

module "cloud_cost_bucket" {
  count = var.cloud_cost_management_config.enabled ? 1 : 0

  source = "git@github.com:theorchard/terraform-s3.git//modules/s3_bucket?ref=3.14.1"

  env                          = var.environment
  application_family           = var.application_family
  bucket_name                  = "${var.cloud_cost_management_config.bucket_name_prefix}-${var.service_name}-cloud-cost"
  permissions_boundary_enabled = false

  apply_server_side_encryption_by_default = {
    sse_algorithm = "AES256"
  }

  bucket_policy_overrides = [data.aws_iam_policy_document.cloud_cost_bucket_policy[0].json]
}

resource "aws_cur_report_definition" "datadog_cost_and_usage_report" {
  count = var.cloud_cost_management_config.enabled ? 1 : 0

  depends_on = [module.cloud_cost_bucket]

  report_name                = "datadog-cost-and-usage-reports"
  time_unit                  = "HOURLY"
  format                     = "Parquet"
  compression                = "Parquet"
  additional_schema_elements = ["RESOURCES", "SPLIT_COST_ALLOCATION_DATA"]
  s3_bucket                  = module.cloud_cost_bucket[0].s3_bucket_name_output
  s3_prefix                  = "cost-and-usage-reports"
  s3_region                  = data.aws_region.current.region
  refresh_closed_reports     = true
  report_versioning          = "CREATE_NEW_REPORT"
  additional_artifacts       = []
}

module "cloud_cost_bucket_read_policy" {
  count = var.cloud_cost_management_config.enabled ? 1 : 0

  source = "git@github.com:theorchard/terraform-iam-policy-templates.git//documents/s3/buckets_with_prefixes?ref=0.4.0"

  buckets = [{
    bucket = module.cloud_cost_bucket[0].s3_bucket_name_output
  }]
  action_types = ["read"]
}

data "aws_iam_policy_document" "datadog_cloud_cost_management_policy" {
  count = var.cloud_cost_management_config.enabled ? 1 : 0

  statement {
    sid = "DDCloudCostCheckAccuracy"
    actions = [
      "ce:Get*",
    ]
    resources = ["*"]
  }

  statement {
    sid = "DDCloudCostListCURs"
    actions = [
      "cur:DescribeReportDefinitions",
    ]
    resources = ["*"]
  }

  statement {
    sid = "DDCloudCostListOrganizations"
    actions = [
      "organizations:Describe*",
      "organizations:List*"
    ]
    resources = ["*"]
  }
}

resource "aws_iam_role_policy" "cloud_cost_bucket_read_policy" {
  count = var.cloud_cost_management_config.enabled ? 1 : 0

  name   = "S3-${module.cloud_cost_bucket[0].s3_bucket_name_output}-RO"
  policy = module.cloud_cost_bucket_read_policy[0].policy.json
  role   = aws_iam_role.datadog_integration_role.name
}

resource "aws_iam_role_policy" "datadog_cloud_cost_management_policy" {
  count = var.cloud_cost_management_config.enabled ? 1 : 0

  name   = "CostManagement-${var.environment}-${var.service_name}-RO"
  policy = data.aws_iam_policy_document.datadog_cloud_cost_management_policy[0].json
  role   = aws_iam_role.datadog_integration_role.name
}
