data "aws_caller_identity" "current" {}

resource "datadog_monitor" "replication_failures_monitor" {
  count              = var.replication_failures_monitor_configuration.enabled ? 1 : 0
  name               = "${local.bucket_name} replication failures monitor"
  type               = "metric alert"
  message            = "Replication operations failed for bucket ${local.bucket_name}, rule {{ruleid.name}}. Notify: ${var.notification_endpoints}"
  escalation_message = "Replication operations still failing for bucket ${local.bucket_name}, rule {{ruleid.name}}. Escalation to ${var.escalation_notification_endpoints}"

  query = "sum(last_5m):sum:aws.s3.operations_failed_replication.sum{sourcebucket:${local.bucket_name}} by {ruleid} > ${var.replication_failures_monitor_configuration.critical_threshold}"

  monitor_thresholds {
    critical          = var.replication_failures_monitor_configuration.critical_threshold
    critical_recovery = var.replication_failures_monitor_configuration.critical_recovery_threshold
    warning           = var.replication_failures_monitor_configuration.warning_threshold
    warning_recovery  = var.replication_failures_monitor_configuration.warning_recovery_threshold
  }

  renotify_interval   = 60
  evaluation_delay    = 600
  require_full_window = false
  notify_no_data      = false

  tags = local.tags
}

resource "datadog_monitor" "replication_latency_monitor" {
  count              = var.replication_latency_monitor_configuration.enabled ? 1 : 0
  name               = "${local.bucket_name} replication latency monitor"
  type               = "metric alert"
  message            = "Replication latency is high for bucket ${local.bucket_name}, rule {{ruleid.name}}. Notify: ${var.notification_endpoints}"
  escalation_message = "Replication latency is still high for bucket ${local.bucket_name}, rule {{ruleid.name}}. Escalation to ${var.escalation_notification_endpoints}"

  query = "max(last_5m):max:aws.s3.replication_latency{sourcebucket:${local.bucket_name}} by {ruleid} > ${var.replication_latency_monitor_configuration.critical_threshold}"

  monitor_thresholds {
    critical          = var.replication_latency_monitor_configuration.critical_threshold
    critical_recovery = var.replication_latency_monitor_configuration.critical_recovery_threshold
    warning           = var.replication_latency_monitor_configuration.warning_threshold
    warning_recovery  = var.replication_latency_monitor_configuration.warning_recovery_threshold
  }

  renotify_interval   = 60
  evaluation_delay    = 600
  require_full_window = false
  notify_no_data      = true

  tags = local.tags
}

resource "datadog_monitor" "guardduty_s3_malware" {
  count = var.guardduty_malware_monitor_configuration.enabled ? 1 : 0

  name = "GuardDuty S3 Malware Detection - ${local.bucket_name} - {{log.attributes.title}}"
  type = "log alert"

  message = <<-EOM
CRITICAL: S3 Malware Detected by GuardDuty - {{log.attributes.title}}

Account: ${data.aws_caller_identity.current.account_id}
Bucket: ${local.bucket_name}
Object: {{log.attributes.s3_object_key}}
Finding Time: {{log.attributes.time}}
Finding ID: {{log.attributes.detail.id}}

**Investigation:**
The GuardDuty finding DOES NOT contain the uploader's identity.
To find the IAM Role/User who uploaded this file, run the following query in **AWS Athena** in Shared account.

```
SELECT
  record.eventtime,
  record.useridentity.arn,
  record.useridentity.principalid,
  record.sourceipaddress,
  record.eventname,
  record.requestparameters

FROM "${data.aws_caller_identity.current.account_id}_cloudtrail_logs"
CROSS JOIN UNNEST(records) AS t(record)
WHERE 
  year = 'YYYY' AND month = 'MM' AND day = 'DD'

  AND record.recipientaccountid = '${data.aws_caller_identity.current.account_id}'
  AND record.eventsource = 's3.amazonaws.com'
  AND record.eventname IN ('PutObject', 'CompleteMultipartUpload', 'CopyObject')
  AND record.requestparameters LIKE '%${local.bucket_name}%'
  AND record.requestparameters LIKE '%%{{log.attributes.s3_object_key}}%'
ORDER BY record.eventtime DESC;
```

${var.notification_endpoints}

**To resolve this alert, acknowledge it in Datadog after investigation.**
EOM

  query = <<-EOT
logs("@detail.resource.s3BucketDetails.arn:\"arn:aws:s3:::${local.bucket_name}\" @evt.name:\"Object:S3/MaliciousFile\" @source:aws.guardduty")
  .index("*")
  .rollup("count")
  .last("5m") >= 1
EOT

  monitor_thresholds {
    critical = 1
  }

  evaluation_delay    = 0
  require_full_window = true
  notify_audit        = false
  on_missing_data     = "show_no_data"
  renotify_interval   = 10
  include_tags        = true
  enable_logs_sample  = false

  tags     = local.tags
  priority = 1
}
