Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Provides AWS CloudFormation patterns for CloudWatch monitoring, metrics, alarms, dashboards, logs, and observability. Use when creating CloudWatch metrics, alarms, dashboards, log groups, log subscriptions, anomaly detection, synthesized canaries, Application Signals, and implementing template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references, and CloudWatch best practices for monitoring production infrastructure.
.claude/skills/giuseppe-trisciuoglio-aws-cloudformation-cloudwatch/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-11 | ✗→✓ | ▲ Improved | 158% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 71% | 0% |
| case-02 | ✓→✗ | ▼ Worse | 133% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 191% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 272% | 0% |
Creates CloudWatch monitoring infrastructure using CloudFormation templates: metrics, alarms, dashboards, log groups, anomaly detection, synthesized canaries, and Application Signals.
Follow these steps to create CloudWatch monitoring infrastructure with CloudFormation:
Specify metric namespaces, dimensions, and threshold values:
yamlParameters: ErrorRateThreshold: Type: Number Default: 5 Description: Error rate threshold for alarms (percentage) LatencyThreshold: Type: Number Default: 1000 Description: Latency threshold in milliseconds CpuUtilizationThreshold: Type: Number Default: 80 Description: CPU utilization threshold (percentage) LogRetentionDays: Type: Number Default: 30 AllowedValues: - 1 - 3 - 7 - 14 - 30 - 60 - 90 - 120 - 365 Description: Number of days to retain log events
Set up alarms for CPU, memory, disk, and custom metrics:
yamlResources: HighCpuAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub "${AWS::StackName}-high-cpu" AlarmDescription: Trigger when CPU utilization exceeds threshold MetricName: CPUUtilization Namespace: AWS/EC2 Dimensions: - Name: InstanceId Value: !Ref InstanceId Statistic: Average Period: 60 EvaluationPeriods: 3 Threshold: !Ref CpuUtilizationThreshold ComparisonOperator: GreaterThanThreshold AlarmActions: - !Ref AlarmTopic ErrorRateAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub "${AWS::StackName}-error-rate" MetricName: ErrorRate Namespace: !Ref CustomNamespace Dimensions: - Name: Service Value: !Ref ServiceName Statistic: Average Period: 60 EvaluationPeriods: 5 Threshold: !Ref ErrorRateThreshold ComparisonOperator: GreaterThanThreshold
Define SNS topics for notification delivery:
yamlResources: AlarmNotificationTopic: Type: AWS::SNS::Topic Properties: DisplayName: !Sub "${AWS::StackName}-alarms" TopicName: !Sub "${AWS::StackName}-alarms" AlarmTopicPolicy: Type: AWS::SNS::TopicPolicy Properties: PolicyDocument: Statement: - Effect: Allow Principal: Service: cloudwatch.amazonaws.com Action: sns:Publish Resource: !Ref AlarmNotificationTopic Topics: - !Ref AlarmNotificationTopic
Build visualization widgets for metrics across resources:
yamlResources: MonitoringDashboard: Type: AWS::CloudWatch::Dashboard Properties: DashboardName: !Sub "${AWS::StackName}-dashboard" DashboardBody: !Sub | { "widgets": [ { "type": "metric", "x": 0, "y": 0, "width": 12, "height": 6, "properties": { "title": "CPU Utilization", "metrics": [["AWS/EC2", "CPUUtilization", "InstanceId", "${InstanceId}"]], "period": 300, "stat": "Average", "region": "${AWS::Region}" } } ] }
Configure retention policies and encryption settings:
yamlResources: ApplicationLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/aws/applications/${Environment}/${ApplicationName}" RetentionInDays: !Ref LogRetentionDays KmsKeyId: !Ref LogEncryptionKey
Create metrics from log data:
yamlResources: ErrorMetricFilter: Type: AWS::Logs::MetricFilter Properties: LogGroupName: !Ref ApplicationLogGroup FilterPattern: '[level="ERROR", msg]' MetricTransformations: - MetricValue: "1" MetricNamespace: !Sub "${AWS::StackName}/Application" MetricName: ErrorCount
Build multi-condition alarm logic:
yamlResources: SystemHealthComposite: Type: AWS::CloudWatch::CompositeAlarm Properties: AlarmName: !Sub "${AWS::StackName}-system-health" AlarmRule: !Or - !Ref HighCpuAlarm - !Ref ErrorRateAlarm AlarmActions: - !Ref AlarmTopic
Create saved queries for log analysis:
yamlResources: ErrorAnalysisQuery: Type: AWS::Logs::QueryDefinition Properties: Name: !Sub "${AWS::StackName}-errors" LogGroupNames: - !Ref ApplicationLogGroup QueryString: | fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc | limit 100
Before deploying, validate the CloudFormation template:
bashaws cloudformation validate-template --template-body file://template.yaml
For parameterized templates, test with sample values:
bashaws cloudformation validate-template \ --template-body file://monitoring.yaml \ --capabilities CAPABILITY_IAM
Deploy the stack and verify resources:
bash# Deploy stack aws cloudformation create-stack \ --stack-name my-monitoring-stack \ --template-body file://monitoring.yaml \ --parameters file://parameters.json \ --capabilities CAPABILITY_IAM # Wait for completion aws cloudformation wait stack-create-complete \ --stack-name my-monitoring-stack # Verify alarms are in OK state aws cloudwatch describe-alarms --stack-name my-monitoring-stack # Check dashboard accessibility aws cloudwatch get-dashboard --dashboard-name my-monitoring-stack-dashboard
Test alarm actions before production:
bash# Set alarm to testing state aws cloudwatch set-alarm-state \ --alarm-name my-alarm \ --state-value ALARM \ --state-reason "Testing alarm action"
set-alarm-state before productionyamlAWSTemplateFormatVersion: '2010-09-09' Description: Complete CloudWatch monitoring setup Parameters: Environment: Type: String Default: prod AllowedValues: [dev, staging, prod] Resources: # SNS Topic for notifications AlarmTopic: Type: AWS::SNS::Topic Properties: DisplayName: !Sub "${Environment}-alarms" # Alarm for high CPU CpuAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub "${AWS::StackName}-cpu-high" MetricName: CPUUtilization Namespace: AWS/EC2 Statistic: Average Period: 300 EvaluationPeriods: 2 Threshold: 80 ComparisonOperator: GreaterThanThreshold AlarmActions: - !Ref AlarmTopic # Dashboard Dashboard: Type: AWS::CloudWatch::Dashboard Properties: DashboardName: !Ref AWS::StackName DashboardBody: !Sub | { "widgets": [{ "type": "metric", "properties": { "metrics": [["AWS/EC2", "CPUUtilization"]], "period": 300, "stat": "Average" } }] }
yamlResources: AppLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/app/${Environment}" RetentionInDays: 30 ErrorMetricFilter: Type: AWS::Logs::MetricFilter Properties: LogGroupName: !Ref AppLogGroup FilterPattern: '"ERROR"' MetricTransformations: - MetricValue: "1" MetricNamespace: !Sub "${AWS::StackName}/App" MetricName: ErrorCount ErrorAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: !Sub "${AWS::StackName}-errors" MetricName: ErrorCount MetricNamespace: !Sub "${AWS::StackName}/App" Statistic: Sum Period: 300 EvaluationPeriods: 1 Threshold: 1 ComparisonOperator: GreaterThanOrEqualToThreshold
For detailed implementation guidance, see:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 7,647 | 5,995 | -22% | 1 | 1 | 0% | 1,564 | 4,555 | +191% | 0 | 0 | — |
case-02 | pass→fail | 13,550 | 9,635 | -29% | 1 | 1 | 0% | 2,181 | 5,078 | +133% | 0 | 0 | — |
case-03 | pass→pass | 6,470 | 5,161 | -20% | 1 | 1 | 0% | 1,151 | 4,287 | +272% | 0 | 0 | — |
case-04 | pass→pass | 5,542 | 5,441 | -2% | 1 | 1 | 0% | 995 | 4,342 | +336% | 0 | 0 | — |
case-05 | fail→fail | 9,972 | 8,701 | -13% | 1 | 1 | 0% | 1,775 | 4,900 | +176% | 0 | 0 | — |
case-06 | pass→pass | 11,539 | 6,873 | -40% | 1 | 1 | 0% | 2,063 | 4,611 | +124% | 0 | 0 | — |
case-07 | pass→pass | 4,059 | 3,986 | -2% | 1 | 1 | 0% | 700 | 4,079 | +483% | 0 | 0 | — |
case-08 | pass→pass | 10,651 | 7,380 | -31% | 1 | 1 | 0% | 949 | 4,663 | +391% | 0 | 0 | — |
case-09 | pass→pass | 3,948 | 3,779 | -4% | 1 | 1 | 0% | 599 | 3,861 | +545% | 0 | 0 | — |
case-10 | pass→pass | 7,034 | 4,511 | -36% | 1 | 1 | 0% | 1,237 | 4,043 | +227% | 0 | 0 | — |
case-15 | pass→pass | 12,526 | 8,548 | -32% | 1 | 1 | 0% | 2,099 | 4,717 | +125% | 0 | 0 | — |
case-11 | fail→pass | 10,647 | 13,197 | +24% | 1 | 1 | 0% | 1,652 | 4,264 | +158% | 0 | 0 | — |
case-12 | fail→pass | 14,111 | 4,868 | -66% | 1 | 1 | 0% | 2,370 | 4,053 | +71% | 0 | 0 | — |
case-13 | pass→pass | 7,799 | 4,177 | -46% | 1 | 1 | 0% | 1,245 | 3,934 | +216% | 0 | 0 | — |
case-14 | pass→pass | 8,515 | 8,237 | -3% | 1 | 1 | 0% | 1,630 | 4,865 | +198% | 0 | 0 | — |
case-16 | pass→pass | 15,245 | 14,800 | -3% | 1 | 1 | 0% | 2,552 | 6,012 | +136% | 0 | 0 | — |
case-17 | pass→pass | 9,941 | 9,148 | -8% | 1 | 1 | 0% | 1,988 | 5,316 | +167% | 0 | 0 | — |
case-18 | pass→pass | 13,022 | 9,392 | -28% | 1 | 1 | 0% | 2,534 | 5,215 | +106% | 0 | 0 | — |
case-19 | fail→fail | 8,505 | 6,177 | -27% | 1 | 1 | 0% | 1,307 | 4,248 | +225% | 0 | 0 | — |
case-20 | pass→pass | 5,734 | 4,584 | -20% | 1 | 1 | 0% | 1,035 | 4,209 | +307% | 0 | 0 | — |
case-21 | pass→pass | 8,012 | 6,631 | -17% | 1 | 1 | 0% | 1,445 | 4,594 | +218% | 0 | 0 | — |
case-22 | pass→pass | 10,846 | 7,915 | -27% | 1 | 1 | 0% | 1,930 | 4,797 | +149% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.