resource "aws_dynamodb_table" "purchase_orders" { name = "purchase-orders" billing_mode = "PAY_PER_REQUEST" hash_key = "po_number" deletion_protection_enabled = true attribute { name = "po_number" type = "S" } stream_enabled = true stream_view_type = "NEW_IMAGE" server_side_encryption { enabled = true kms_key_arn = data.aws_ssm_parameter.dynamodb_cmk_arn.value } point_in_time_recovery { enabled = true } lifecycle { prevent_destroy = true } } resource "aws_dynamodb_table" "verified_sites" { name = "verified-sites" billing_mode = "PAY_PER_REQUEST" hash_key = "siteCode" deletion_protection_enabled = true attribute { name = "siteCode" type = "S" } point_in_time_recovery { enabled = true } lifecycle { prevent_destroy = true } } resource "aws_dynamodb_table" "pending_site_review" { name = "pending-site-review" billing_mode = "PAY_PER_REQUEST" hash_key = "po_number" deletion_protection_enabled = true attribute { name = "po_number" type = "S" } point_in_time_recovery { enabled = true } lifecycle { prevent_destroy = true } } locals { po_ddb_alarm_tables = { "purchase-orders" = aws_dynamodb_table.purchase_orders.name "verified-sites" = aws_dynamodb_table.verified_sites.name "pending-site-review" = aws_dynamodb_table.pending_site_review.name } } resource "aws_cloudwatch_metric_alarm" "po_ddb_throttles" { for_each = local.po_ddb_alarm_tables alarm_name = "${each.key}-throttles" alarm_description = "${each.key} DynamoDB throttled requests" comparison_operator = "GreaterThanThreshold" evaluation_periods = 1 threshold = 0 treat_missing_data = "notBreaching" alarm_actions = [data.aws_sns_topic.site_alerts.arn] metric_query { id = "expr_1" expression = local.ddb_throttle_expr label = "Sum of throttled requests across all operations" return_data = true } dynamic "metric_query" { for_each = local.ddb_alarm_operations content { id = lower(metric_query.value) metric { metric_name = "ThrottledRequests" namespace = "AWS/DynamoDB" period = 300 stat = "Sum" dimensions = { TableName = each.value Operation = metric_query.value } } return_data = false } } } resource "aws_cloudwatch_metric_alarm" "po_ddb_system_errors" { for_each = local.po_ddb_alarm_tables alarm_name = "${each.key}-system-errors" alarm_description = "${each.key} DynamoDB server-side (5xx) errors" comparison_operator = "GreaterThanThreshold" evaluation_periods = 1 threshold = 0 treat_missing_data = "notBreaching" alarm_actions = [data.aws_sns_topic.site_alerts.arn] metric_query { id = "expr_1" expression = local.ddb_throttle_expr label = "Sum of system errors across all operations" return_data = true } dynamic "metric_query" { for_each = local.ddb_alarm_operations content { id = lower(metric_query.value) metric { metric_name = "SystemErrors" namespace = "AWS/DynamoDB" period = 300 stat = "Sum" dimensions = { TableName = each.value Operation = metric_query.value } } return_data = false } } }