rebuy-de / aws-nuke

Nuke a whole AWS account and delete all its resources.
https://github.com/ekristen/aws-nuke
MIT License
5.77k stars 725 forks source link

Adding support for CloudWatch insight rules and anomaly detectors #1253

Closed swhite-oreilly closed 2 months ago

swhite-oreilly commented 3 months ago

This PR adds support for AWS CloudWatch insight rules and anomaly detectors.

Testing

Resources created with the script below and cleanup verified by adding the following to the config: CloudWatchAlarm CloudWatchAnomalyDetector CloudWatchDashboard CloudWatchInsightRule CloudWatchRUMApp

# Account ID
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
echo "Account ID: $ACCOUNT_ID"

# Creating a DB
aws rds create-db-instance \
    --db-instance-identifier mydb-instance \
    --db-instance-class db.t3.micro \
    --engine MySQL \
    --allocated-storage 20 \
    --master-username root \
    --master-user-password root1234 \
    --no-cli-pager
echo "DB created"

# Describe DB instances
aws rds describe-db-instances --query "DBInstances[*].[DBInstanceIdentifier,DBInstanceStatus]" --output text

# List CloudWatch metrics
aws cloudwatch list-metrics --namespace AWS/RDS --dimensions Name=DBInstanceIdentifier,Value=mydb-instance --no-cli-pager

# Get CPU utilization statistics
# Get current time in seconds since epoch
CURRENT_TIME=$(date -u +%s)
echo "Current time: $CURRENT_TIME"

# Calculate one hour ago in seconds
ONE_HOUR_AGO=$((CURRENT_TIME - 3600))
echo "One hour ago: $ONE_HOUR_AGO"

# Convert one hour ago to the desired format
ONE_HOUR_AGO_FORMATTED=$(date -u -d "@$ONE_HOUR_AGO" +'%Y-%m-%dT%H:%M:%SZ')
echo "One hour ago formatted: $ONE_HOUR_AGO_FORMATTED"

# Make AWS CLI call with obtained timestamps
aws cloudwatch get-metric-statistics \
    --namespace AWS/RDS \
    --metric-name CPUUtilization \
    --dimensions Name=DBInstanceIdentifier,Value=mydb-instance \
    --start-time $ONE_HOUR_AGO \
    --end-time $CURRENT_TIME \
    --period 3600 \
    --statistics Maximum
echo "get-metric-statistics called"

# Create a topic
TOPIC_ARN=$(aws sns create-topic --name my-topic --query TopicArn --output text)
echo "Topic: $TOPIC_ARN"

# Creating anomaly detection model
aws cloudwatch put-anomaly-detector \
    --namespace AWS/RDS \
    --metric-name CPUUtilization \
    --stat "Average" \
    --dimensions Name=DBInstanceIdentifier,Value=mydb-instance
echo "Anomaly detector created"

# Create cloudwatch alarm to track CPU utilization on the DB
aws cloudwatch put-metric-alarm \
    --alarm-name CPUUtilizationAlarm \
    --alarm-description "Alarm when CPU exceeds 70%" \
    --actions-enabled \
    --alarm-actions $TOPIC_ARN \
    --metric-name CPUUtilization \
    --namespace AWS/RDS \
    --statistic Average \
    --dimensions Name=DBInstanceIdentifier,Value=mydb-instance \
    --period 300 \
    --evaluation-periods 2 \
    --threshold 70 \
    --comparison-operator GreaterThanThreshold
echo "CPUUtilizationAlarm created"

# Create another cloudwatch alarm to track CPU utilization anomalies on the DB
aws cloudwatch put-metric-alarm \
    --alarm-name CPUUtilizationAnomalyAlarm \
    --alarm-description "Alarm for CPU utilization anomalies" \
    --actions-enabled \
    --alarm-actions $TOPIC_ARN \
    --metric-name CPUUtilization \
    --namespace AWS/RDS \
    --statistic Maximum \
    --dimensions Name=DBInstanceIdentifier,Value=mydb-instance \
    --period 300 \
    --evaluation-periods 2 \
    --treat-missing-data ignore \
    --threshold 1 \
    --comparison-operator GreaterThanThreshold
echo "CPUUtilizationAnomalyAlarm created"

# Create insight rule (found under Contributor Insights in the CloudWatch console)
aws cloudwatch put-insight-rule \
    --rule-name mydb-insight-rule \
    --rule-state ENABLED \
    --rule-definition '{
        "Schema": {
            "Name": "CloudWatchLogRule",
            "Version": 1
        },
        "LogGroupNames": [
            "mydb-instance"
        ],
        "LogFormat": "JSON",
        "Contribution": {
            "Keys": [
                "$.CPUUtilization"
            ],
            "ValueOf": "$.CPUUtilization",
            "Filters": [
                {
                    "Match": "$.CPUUtilization",
                    "GreaterThan": 70
                }
            ]
        },
        "AggregateOn": "Average"
    }'
echo "Insight rule created"

# Create CloudWatch dashboard
aws cloudwatch put-dashboard --dashboard-name mydb-dashboard --dashboard-body '{
  "widgets": [
    {
      "type": "metric",
      "x": 0,
      "y": 0,
      "width": 12,
      "height": 6,
      "properties": {
        "metrics": [
          [ "AWS/RDS", "CPUUtilization", "DBInstanceIdentifier", "mydb-instance" ]
        ],
        "period": 300,
        "stat": "Average",
        "region": "us-east-1",
        "title": "RDS Instance CPU"
      }
    }
  ]
}'
echo "Dashboard created"

# Put metric data
aws cloudwatch put-metric-data \
    --namespace Custom/RDS \
    --metric-name CPUUtilization \
    --dimensions Name=DBInstanceIdentifier,Value=mydb-instance \
    --value 70
echo "Metric data sent"

# List all resources for created cloudwatch resources
aws cloudwatch describe-alarms --no-cli-pager
aws cloudwatch describe-insight-rules --no-cli-pager
aws cloudwatch list-dashboards --no-cli-pager
aws cloudwatch describe-anomaly-detectors --no-cli-pager
ekristen commented 2 months ago

@swhite-oreilly this has been implemented via https://github.com/ekristen/aws-nuke/pull/270 of what is now the active fork of aws-nuke.

This project has now been deprecated in favor of this fork. Sven kindly granted me access to directly answer and close pull requests and issues so that we can notify users if their issues have been addressed or not. Please see the welcome issue for more information.