locals {
  datadog_aws_account_id = "464622532012"
}

data "aws_region" "current" {}

data "aws_caller_identity" "current" {}

data "aws_iam_account_alias" "current" {}

data "aws_iam_policy" "security_audit" {
  name = "SecurityAudit"
}

resource "datadog_integration_aws_account" "integration" {
  # Caution should be taken when adding new tags here as they will be propagated
  # to all AWS metrics and resources.
  account_tags = [
    "aws_account_alias:${data.aws_iam_account_alias.current.account_alias}",
  ]
  aws_account_id = data.aws_caller_identity.current.account_id
  aws_partition  = "aws"

  aws_regions {
    include_all = true
  }

  auth_config {
    aws_auth_config_role {
      role_name = var.aws_role_name
    }
  }

  logs_config {
    lambda_forwarder {}
  }

  metrics_config {
    automute_enabled          = var.metrics_config.automute_enabled
    collect_cloudwatch_alarms = var.metrics_config.collect_cloudwatch_alarms
    collect_custom_metrics    = var.metrics_config.collect_custom_metrics
    enabled                   = var.metrics_config.enabled

    dynamic "tag_filters" {
      for_each = var.metrics_config.tag_filters

      content {
        namespace = tag_filters.value.namespace
        tags      = tag_filters.value.tags
      }
    }

    namespace_filters {
      exclude_only = var.metrics_config.excluded_namespaces
    }
  }

  resources_config {
    cloud_security_posture_management_collection = var.resources_config.cloud_security_posture_management_collection_enabled
    extended_collection                          = var.resources_config.extended_collection_enabled
  }

  traces_config {
    xray_services {
      include_only = var.traces_config.included_services
    }
  }
}

resource "aws_iam_role" "datadog_integration_role" {
  name               = var.aws_role_name
  assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
}

data "aws_iam_policy_document" "assume_role_policy" {
  statement {
    sid     = "DatadogAWSTrustRelationship"
    actions = ["sts:AssumeRole"]

    principals {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::${local.datadog_aws_account_id}:root",
      ]

    }
    condition {
      test     = "StringEquals"
      values   = [datadog_integration_aws_account.integration.auth_config.aws_auth_config_role.external_id]
      variable = "sts:ExternalId"
    }
  }
}

data "aws_iam_policy_document" "datadog_integration_policy_document" {
  # checkov:skip=CKV_AWS_111:Allow "*" resources in this policy for Datadog.
  statement {
    actions = [
      "account:GetAccountInformation",
      "airflow:GetEnvironment",
      "airflow:ListEnvironments",
      "apigateway:GET",
      "autoscaling:Describe*",
      "backup:List*",
      "bcm-data-exports:GetExport",
      "bcm-data-exports:ListExports",
      "budgets:ViewBudget",
      "cloudfront:GetDistributionConfig",
      "cloudfront:ListDistributions",
      "cloudtrail:DescribeTrails",
      "cloudtrail:GetTrail",
      "cloudtrail:GetTrailStatus",
      "cloudtrail:ListTrails",
      "cloudtrail:LookupEvents",
      "cloudwatch:Describe*",
      "cloudwatch:Get*",
      "cloudwatch:List*",
      "codedeploy:BatchGet*",
      "codedeploy:List*",
      "cur:DescribeReportDefinitions",
      "directconnect:Describe*",
      "dynamodb:Describe*",
      "dynamodb:List*",
      "ec2:Describe*",
      "ecs:Describe*",
      "ecs:List*",
      "eks:DescribeCluster",
      "eks:ListClusters",
      "elasticache:Describe*",
      "elasticache:List*",
      "elasticfilesystem:DescribeAccessPoints",
      "elasticfilesystem:DescribeFileSystems",
      "elasticfilesystem:DescribeTags",
      "elasticloadbalancing:Describe*",
      "elasticmapreduce:Describe*",
      "elasticmapreduce:List*",
      "es:DescribeElasticsearchDomains",
      "es:ListDomainNames",
      "es:ListTags",
      "events:CreateEventBus",
      "fsx:DescribeFileSystems",
      "fsx:ListTagsForResource",
      "health:DescribeAffectedEntities",
      "health:DescribeEventDetails",
      "health:DescribeEvents",
      "iam:ListAccountAliases",
      "kinesis:Describe*",
      "kinesis:List*",
      "lambda:List*",
      "logs:DeleteSubscriptionFilter",
      "logs:DescribeDeliveries",
      "logs:DescribeDeliverySources",
      "logs:DescribeLogGroups",
      "logs:DescribeLogStreams",
      "logs:DescribeSubscriptionFilters",
      "logs:FilterLogEvents",
      "logs:GetDeliveryDestination",
      "logs:PutSubscriptionFilter",
      "logs:TestMetricFilter",
      "network-firewall:DescribeLoggingConfiguration",
      "network-firewall:ListFirewalls",
      "oam:ListAttachedLinks",
      "oam:ListSinks",
      "organizations:Describe*",
      "organizations:List*",
      "rds:Describe*",
      "rds:List*",
      "redshift-serverless:ListNamespaces",
      "redshift:DescribeClusters",
      "redshift:DescribeLoggingStatus",
      "route53:List*",
      "s3:GetBucketLocation",
      "s3:GetBucketLogging",
      "s3:GetBucketNotification",
      "s3:GetBucketTagging",
      "s3:ListAllMyBuckets",
      "s3:PutBucketNotification",
      "ses:Get*",
      "ses:List*",
      "sns:GetSubscriptionAttributes",
      "sns:List*",
      "sns:Publish",
      "sqs:ListQueues",
      "ssm:GetServiceSetting",
      "ssm:ListCommands",
      "states:DescribeStateMachine",
      "states:ListStateMachines",
      "support:DescribeTrustedAdvisor*",
      "support:RefreshTrustedAdvisorCheck",
      "tag:GetResources",
      "tag:GetTagKeys",
      "tag:GetTagValues",
      "timestream:DescribeEndpoints",
      "wafv2:ListLoggingConfigurations",
      "xray:BatchGetTraces",
      "xray:GetTraceSummaries"
    ]
    resources = ["*"]
  }
}

resource "aws_iam_role_policy" "datadog_role_policy_attachment" {
  name   = "datadog-integration-policy"
  role   = aws_iam_role.datadog_integration_role.id
  policy = data.aws_iam_policy_document.datadog_integration_policy_document.json
}

resource "aws_iam_role_policy_attachment" "datadog_role_policy_attachment" {
  role       = aws_iam_role.datadog_integration_role.id
  policy_arn = data.aws_iam_policy.security_audit.arn
}
