2023年12月のリリースで Amazon CloudWatch Alarm から直接 AWS Lambda 関数を呼び出して,何かしらのアクション(復旧処理など)を実行できるようになった❗️今までは Amazon SNS と組み合わせて実行する必要があって,今までよりもシンプルに統合できるようになった.もちろん Amazon SNS でファンアウトすることによる拡張性も重要なので,個人的には AWS Lambda 関数を呼び出せれば十分というシンプルな場面で使えそうだなーと思っていたりする \( 'ω')/
AWS CDK で試す
AWS CDK では v2.119.0 から Amazon CloudWatch Alarm の Lambda アクションを設定できるようになっていた❗️試してみたサンプルコード (TypeScript) を載せておく.
👾 sandbox-cdk-cloudwatch-lambda-stack.ts
Amazon SQS キューの ApproximateNumberOfMessagesVisible
メトリクスを監視して,メッセージ数が増えたら Amazon CloudWatch Alarm から直接 AWS Lambda 関数を呼び出すようにした(Lambda 関数部分は割愛).今回のポイントは最後の addAlarmAction()
に aws_cloudwatch_actions.LambdaAction
を指定しているところ❗️
import { Duration, Stack, StackProps, aws_cloudwatch, aws_cloudwatch_actions, aws_iam, aws_lambda, aws_sqs, } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import path = require('path'); export class SandboxCdkCloudWatchLambdaStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const queue = new aws_sqs.Queue(this, 'SandboxCdkQueue', { queueName: 'sandbox-cdk-cloudwatch-lambda-queue', visibilityTimeout: Duration.seconds(30), receiveMessageWaitTime: Duration.seconds(20), }); const lambdaBasicExecutionRole = new aws_iam.Role(this, 'SandboxCdkLambdaBasicExecutionRole', { assumedBy: new aws_iam.ServicePrincipal('lambda.amazonaws.com'), managedPolicies: [ aws_iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole') ] }); const lambda = new aws_lambda.Function(this, 'SandboxCdkLambdaFunction', { functionName: 'sandbox-cdk-cloudwatch-lambda-function', runtime: aws_lambda.Runtime.PYTHON_3_12, code: aws_lambda.Code.fromAsset(path.join(__dirname, '../functions/hello')), handler: 'app.lambda_handler', role: lambdaBasicExecutionRole, }); const alarm = new aws_cloudwatch.Alarm(this, 'SandboxCdkCloudWatchAlarm', { alarmName: 'sandbox-cdk-cloudwatch-lambda-queue-alarm', metric: new aws_cloudwatch.Metric({ namespace: 'AWS/SQS', metricName: 'ApproximateNumberOfMessagesVisible', dimensionsMap: { QueueName: queue.queueName }, period: Duration.seconds(60), statistic: aws_cloudwatch.Stats.SUM, }), threshold: 5, evaluationPeriods: 1, }); alarm.addAlarmAction(new aws_cloudwatch_actions.LambdaAction(lambda)); } }
結果
Amazon SQS キューにメッセージを5件以上送信すると(今回は10件)アラーム状態になって AWS Lambda 関数が呼び出された👌
注意点
現時点(最新は v2.121.1)では同じ AWS Lambda 関数を複数の Amazon CloudWatch Alarm に紐付けるとエラーになってしまうという問題がある.プルリクエストも出ていて,近々直りそうな気もするけど注意しておくと良いかなーと👀
Error: There is already a Construct with name 'AlarmPermission' in Function [SandboxCdkLambdaFunction]