CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pulumi--aws

A Pulumi package for creating and managing Amazon Web Services (AWS) cloud resources with infrastructure-as-code.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

cloudwatch.mddocs/monitoring/

CloudWatch Monitoring Guide

Comprehensive guide for monitoring AWS resources with Amazon CloudWatch.

Overview

CloudWatch provides monitoring and observability for AWS cloud resources and applications through metrics, logs, alarms, and dashboards.

Package

import * as aws from "@pulumi/aws";
import * as cloudwatch from "@pulumi/aws/cloudwatch";

Metrics and Alarms

Basic Metric Alarm

const cpuAlarm = new aws.cloudwatch.MetricAlarm("high-cpu", {
    name: "high-cpu-utilization",
    comparisonOperator: "GreaterThanThreshold",
    evaluationPeriods: 2,
    metricName: "CPUUtilization",
    namespace: "AWS/EC2",
    period: 300,
    statistic: "Average",
    threshold: 80,
    alarmDescription: "Alert when CPU exceeds 80%",
    dimensions: {
        InstanceId: instance.id,
    },
    alarmActions: [snsTopic.arn],
    okActions: [snsTopic.arn],
});

Composite Alarms

const compositeAlarm = new aws.cloudwatch.CompositeAlarm("system-health", {
    alarmName: "system-health-composite",
    alarmRule: pulumi.interpolate`
        ALARM(${cpuAlarm.arn}) OR 
        ALARM(${memoryAlarm.arn}) OR 
        ALARM(${diskAlarm.arn})
    `,
    alarmActions: [criticalTopic.arn],
});

Log Management

Log Groups and Streams

const logGroup = new aws.cloudwatch.LogGroup("application-logs", {
    name: "/aws/application/myapp",
    retentionInDays: 30,
    kmsKeyId: kmsKey.id,
    tags: {
        Application: "myapp",
        Environment: "production",
    },
});

const logStream = new aws.cloudwatch.LogStream("app-stream", {
    name: "application-stream",
    logGroupName: logGroup.name,
});

Log Metric Filters

const errorMetric = new aws.cloudwatch.LogMetricFilter("error-count", {
    name: "application-errors",
    logGroupName: logGroup.name,
    pattern: "[timestamp, request_id, level = ERROR*, ...]",
    metricTransformation: {
        name: "ErrorCount",
        namespace: "MyApp/Errors",
        value: "1",
        defaultValue: "0",
        unit: "Count",
    },
});

// Create alarm on the metric
const errorAlarm = new aws.cloudwatch.MetricAlarm("error-rate", {
    name: "high-error-rate",
    comparisonOperator: "GreaterThanThreshold",
    evaluationPeriods: 1,
    metricName: errorMetric.metricTransformation.name,
    namespace: errorMetric.metricTransformation.namespace,
    period: 60,
    statistic: "Sum",
    threshold: 10,
    alarmActions: [snsTopic.arn],
});

Log Insights Queries

const query = new aws.cloudwatch.QueryDefinition("slow-queries", {
    name: "Slow Database Queries",
    logGroupNames: [logGroup.name],
    queryString: `
        fields @timestamp, @message, duration
        | filter duration > 1000
        | sort duration desc
        | limit 20
    `,
});

Dashboards

Application Dashboard

const dashboard = new aws.cloudwatch.Dashboard("app-dashboard", {
    dashboardName: "application-metrics",
    dashboardBody: pulumi.all([
        instance.id,
        loadBalancer.arn,
    ]).apply(([instanceId, lbArn]) => JSON.stringify({
        widgets: [
            {
                type: "metric",
                properties: {
                    metrics: [
                        ["AWS/EC2", "CPUUtilization", { stat: "Average" }],
                        [".", "NetworkIn"],
                        [".", "NetworkOut"],
                    ],
                    period: 300,
                    stat: "Average",
                    region: "us-west-2",
                    title: "EC2 Metrics",
                    yAxis: {
                        left: { min: 0 },
                    },
                },
            },
            {
                type: "metric",
                properties: {
                    metrics: [
                        ["AWS/ApplicationELB", "TargetResponseTime", { stat: "Average" }],
                        [".", "RequestCount", { stat: "Sum" }],
                    ],
                    period: 60,
                    region: "us-west-2",
                    title: "Load Balancer Metrics",
                },
            },
            {
                type: "log",
                properties: {
                    query: `SOURCE '${logGroup.name}' | fields @timestamp, @message | sort @timestamp desc | limit 100`,
                    region: "us-west-2",
                    title: "Recent Logs",
                },
            },
        ],
    })),
});

Custom Metrics

Publishing Custom Metrics

// Lambda function to publish custom metrics
const metricPublisher = new aws.lambda.Function("metric-publisher", {
    runtime: "nodejs18.x",
    handler: "index.handler",
    role: lambdaRole.arn,
    code: new pulumi.asset.AssetArchive({
        "index.js": new pulumi.asset.StringAsset(`
            const { CloudWatchClient, PutMetricDataCommand } = require("@aws-sdk/client-cloudwatch");
            
            exports.handler = async (event) => {
                const client = new CloudWatchClient({});
                await client.send(new PutMetricDataCommand({
                    Namespace: "MyApp/Custom",
                    MetricData: [{
                        MetricName: "ProcessingTime",
                        Value: event.duration,
                        Unit: "Milliseconds",
                        Timestamp: new Date(),
                        Dimensions: [{
                            Name: "Environment",
                            Value: "production"
                        }]
                    }]
                }));
            };
        `),
    }),
});

Alarm on Custom Metrics

const customMetricAlarm = new aws.cloudwatch.MetricAlarm("custom-metric", {
    name: "high-processing-time",
    comparisonOperator: "GreaterThanThreshold",
    evaluationPeriods: 2,
    metricName: "ProcessingTime",
    namespace: "MyApp/Custom",
    period: 300,
    statistic: "Average",
    threshold: 5000,
    dimensions: {
        Environment: "production",
    },
    alarmActions: [snsTopic.arn],
});

Container Monitoring

ECS Container Insights

const cluster = new aws.ecs.Cluster("app-cluster", {
    name: "application-cluster",
    settings: [{
        name: "containerInsights",
        value: "enabled",
    }],
});

Lambda Insights

const lambdaFunction = new aws.lambda.Function("monitored-function", {
    runtime: "nodejs18.x",
    handler: "index.handler",
    role: lambdaRole.arn,
    code: new pulumi.asset.AssetArchive({
        ".": new pulumi.asset.FileArchive("./function"),
    }),
    layers: [
        "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:21",
    ],
});

Monitoring Patterns

Multi-Region Monitoring

// Create alarms in multiple regions
const regions = ["us-west-2", "us-east-1", "eu-west-1"];

const regionalAlarms = regions.map(region => {
    const provider = new aws.Provider(`provider-${region}`, { region });
    
    return new aws.cloudwatch.MetricAlarm(`alarm-${region}`, {
        name: `regional-alarm-${region}`,
        comparisonOperator: "GreaterThanThreshold",
        evaluationPeriods: 1,
        metricName: "Errors",
        namespace: "AWS/Lambda",
        period: 60,
        statistic: "Sum",
        threshold: 5,
        alarmActions: [snsTopic.arn],
    }, { provider });
});

Anomaly Detection

const anomalyAlarm = new aws.cloudwatch.MetricAlarm("anomaly-detection", {
    name: "traffic-anomaly",
    comparisonOperator: "LessThanLowerOrGreaterThanUpperThreshold",
    evaluationPeriods: 2,
    thresholdMetricId: "e1",
    metricQueries: [
        {
            id: "e1",
            expression: "ANOMALY_DETECTION_BAND(m1, 2)",
            label: "RequestCount (Expected)",
        },
        {
            id: "m1",
            metric: {
                metricName: "RequestCount",
                namespace: "AWS/ApplicationELB",
                period: 300,
                stat: "Sum",
            },
        },
    ],
});

Best Practices

  1. Set Appropriate Retention: Balance cost and compliance requirements
  2. Use Composite Alarms: Reduce alarm fatigue with intelligent grouping
  3. Enable Container Insights: For ECS/EKS workloads
  4. Create Dashboards: Centralize metrics visualization
  5. Tag Resources: Enable cost allocation and filtering
  6. Use Metric Math: Combine metrics for advanced calculations

Related Documentation

  • CloudWatch Service Reference
  • Core CloudWatch
  • Lambda Monitoring
  • SNS for Notifications

Install with Tessl CLI

npx tessl i tessl/npm-pulumi--aws@7.16.0

docs

monitoring

index.md

quickstart.md

README.md

tile.json