resource "aws_dynamodb_table" "work_orders" { name = "WorkOrders" billing_mode = "PAY_PER_REQUEST" hash_key = "work_order_id" attribute { name = "work_order_id" type = "S" } stream_enabled = true stream_view_type = "NEW_AND_OLD_IMAGES" lifecycle { prevent_destroy = true } } resource "aws_dynamodb_table" "work_order_comments" { name = "WorkOrderComments" billing_mode = "PAY_PER_REQUEST" hash_key = "work_order_id" range_key = "comment_id" attribute { name = "work_order_id" type = "S" } attribute { name = "comment_id" type = "S" } stream_enabled = true stream_view_type = "NEW_AND_OLD_IMAGES" lifecycle { prevent_destroy = true } } locals { wo_ddb_alarm_tables = { "WorkOrders" = aws_dynamodb_table.work_orders.name "WorkOrderComments" = aws_dynamodb_table.work_order_comments.name } } resource "aws_cloudwatch_metric_alarm" "wo_ddb_throttles" { for_each = local.wo_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" "wo_ddb_system_errors" { for_each = local.wo_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 } } }