AWS CDKとは
AWS CDK(Cloud Development Kit)は、Amazon Web Services(AWS)のクラウドリソースをプログラム的に構築およびデプロイするためのフレームワークです。CDKを使用すると、プログラミング言語(TypeScript、Python、Java、C#など)を使用して、AWSインフラストラクチャのコードを記述できます。CDKは、AWSリソースのプロビジョニングと設定をコードで管理するためのツールセットを提供し、インフラストラクチャのコード化による可読性、保守性、再利用性を向上させます。
アーキテクチャー
今回実現したい機能はLambdaでエラー発生またはSQSがDLQに溜まってしまった場合、システム管理者へメール送信します。
Lambdaのエラー監視とSQS DLQの数量監視でSNSを用いてメール送信機能を実現しました。
SNSのTopicの事前作成
エラー通知用のSNS Topicを事前に作成した上で、サブスクリプションのメール通知先のメールアドレスを追加しておきます。
//通知先の作成
const batchResultNotifyTopic = sns.Topic.fromTopicArn(this, <id>, <topic-ARN>);
const batchResultNotifyDestination = new SnsDestination(batchResultNotifyTopic);
※SDK
CDKの作成
amplify cli
まずはamplify cli を用いてCDKを作成する
amplify add custom
✔ How do you want to define this custom resource? · AWS CDK
✔ Provide a name for your custom resource · testcdk
✅ Created skeleton CDK stack in amplify/backend/custom/testcdk directory
✔ Do you want to edit the CDK stack now? (Y/n) · yes
Edit the file in your editor: ***custom/testcdk/cdk-stack.ts
? Press enter to continue
import * as cdk from '@aws-cdk/core';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import { AmplifyDependentResourcesAttributes } from '../../types/amplify-dependent-resources-ref';
//import * as iam from '@aws-cdk/aws-iam';
//import * as sns from '@aws-cdk/aws-sns';
//import * as subs from '@aws-cdk/aws-sns-subscriptions';
//import * as sqs from '@aws-cdk/aws-sqs';
export class cdkStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
super(scope, id, props);
/* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
new cdk.CfnParameter(this, 'env', {
type: 'String',
description: 'Current Amplify CLI env name',
});
}
}
Lambda依存関係の追加
import { AmplifyDependentResourcesAttributes } from "../../types/amplify-dependent-resources-ref";
const dependencies: AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency(this,
amplifyResourceProps.category,
amplifyResourceProps.resourceName,
[
{
category: "function", // api, auth, storage, function, etc.
resourceName: "alretNotification" //先に作ったエラー通知先のlamda
// find the resource at "amplify/backend/<category>/<resourceName>"
}, /* add more dependencies as needed */
{
category: 'custom',
resourceName: '<resource-name>' // SQSリソース名
}
]
);
cdk.Fn.ref関数を使用して、依存関係の出力を参照します
const myFunctionArn = cdk.Fn.ref(dependencies.function.<resource-name>.Arn)
Roleインポート
batchFnction.forEach(functionName => {
//Lamdaの取得
// Roleインポート
const targetLamda: lambda.IFunction = lambda.Function.fromFunctionAttributes(this, functionName + 'Lambda', {
functionArn: cdk.Fn.ref(dependencies.function[functionName].Arn),
role: iam.Role.fromRoleArn(this, functionName + 'Role', `arn:aws:iam::${cdk.Stack.of(this).account}:role/${cdk.Fn.ref(dependencies.function[functionName].LambdaExecutionRole)}`)
});
});
Lambda非同期失敗のSNS通知
batchFnction.forEach(functionName => {
//Lamdaの実行結果の送信先設定
// 非同期処理失敗時SNS送信
//※sns:Publishのポリシーも自動的に追加される
targetLamda.configureAsyncInvoke({
onFailure: batchResultNotifyDestination,// 前述の通知先
});
※SDK
https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda.FunctionAttributes.html
https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda.Function.html
SQS DLQの検知と送信
Cloud WatchのAlarm機能を利用して、DLQの件数が1を超えたら、SNS送信を行います。
//
//SQS(DLQ)にメッセージ検知し、SNS送信
//
const dlqList = [
{ name: <DLQ Name>, Arn: <DLQ ARN> },
]
dlqList.forEach(dlq => {
//sqsの取得
const dlqQueue = sqs.Queue.fromQueueArn(this, dlq.name + 'Queue', cdk.Fn.ref(dlq.Arn));
//アラーム作成(1分間に1件/1データポイント中発生すれば、アラーム)
const alarm = new cloudwatch.Alarm(this, `Alarm-${dlq.name}`, {
alarmName: `Alarm-${dlq.name}-${cdk.Fn.ref('env')}`,
metric: dlqQueue.metricApproximateNumberOfMessagesVisible(),
period: cdk.Duration.seconds(60), //メトリックまたは式を評価して、アラームの個々のデータポイントを作成する時間の長さ
evaluationPeriods: 1, //アラーム状態を判断するときに評価する最新の期間またはデータポイントの数
threshold: 1,
datapointsToAlarm: 1, //period期間中のEvaluationPeriodsの内、DatapointsToAlarm回発生すれば、アラーム通知
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD //評価の比較演算子
});
//アラーム通知先設定
alarm.addAlarmAction(new SnsAction(batchResultNotifyTopic));
})
Construct Props
属性 | タイプ | 説明 |
---|---|---|
evaluationPeriods | number | アラーム状態を判断するときに評価する最新の期間またはデータポイントの数 |
metric | IMetric | アラームを追加するメトリック |
threshold | number | 閾値、指定された統計が比較される値 |
actionsEnabled? | boolean | このアラームのアクションが有効かどうか。 |
alarmDescription? | string | アラームの説明 |
alarmName? | string | アラームの名前 |
comparisonOperator? | ComparisonOperator | メトリクスが違反しているかどうかを確認するために使用する比較。 |
datapointsToAlarm? | number | アラームをトリガーするために違反する必要があるデータポイントの数。 |
evaluateLowSampleCountPercentile? | string | データ ポイントが少なすぎて統計的に有意でない場合に、データを評価し、アラーム状態を変更する可能性があるかどうかを指定します。 |
period? | Duration | メトリックまたは式を評価して、アラームの個々のデータポイントを作成する時間の長さ |
statistic? | string | 集計に使用する関数。 |
treatMissingData? | TreatMissingDat | このアラームが欠落しているデータ ポイントを処理する方法を設定します。 |
ComparisonOperatorメンバー
名前 | 説明 |
---|---|
GREATER_THAN_OR_EQUAL_TO_THRESHOLD | 指定された統計がしきい値以上です。 |
GREATER_THAN_THRESHOLD | 指定された統計はしきい値を厳密に超えています。 |
LESS_THAN_THRESHOLD | 指定された統計は厳密にしきい値未満です。 |
LESS_THAN_OR_EQUAL_TO_THRESHOLD | 指定された統計がしきい値以下です。 |
LESS_THAN_LOWER_OR_GREATER_THAN_UPPER_THRESHOLD | 指定された統計量が異常モデルの帯域よりも小さいか大きいです。 |
GREATER_THAN_UPPER_THRESHOLD | 指定された統計量が異常モデルの帯域よりも大きいです。 |
LESS_THAN_LOWER_THRESHOLD | 指定された統計量は、異常モデルの帯域よりも低いです。 |
※SDK
https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-cloudwatch.Alarm.html
トラブルシューティング
遭遇したトラブルをメモします。
- CloudWatch アラームトリガーの SNS 通知を受信しなかったのはなぜですか?
ご参考