
ECS FargateとRDSでPHPアプリケーションを運用する際、リソースの異常検知や負荷に応じたスケール管理は必須です。
しかし、これらの仕組みを個別に手動で設定するのは手間がかかります。
本記事では、AWS CDK(Cloud Development Kit)を用いて、ECSとRDSの監視アラーム、ECSのオートスケーリング、そしてそのイベントをSlackに集約する通知基盤をIaCとして一括で構築する方法を解説します。
監視・通知アーキテクチャの全体像
採用するアーキテクチャは以下の通りです。
| 機能 | AWSサービス | 役割 |
| 監視 | CloudWatch | メトリクスを収集・アラーム発報 |
| 自動応答 | Application Auto Scaling | ECSの負荷に応じてタスク数を自動調整 |
| 通知ルーティング | Amazon SNS | アラームやスケーリングイベントを中継 |
| 通知先 | AWS Chatbot $\rightarrow$ Slack | SNSからの通知を整形しSlackへ送信 |
事前準備: AWS ChatbotとSlackの連携
CDKデプロイの前に、AWSアカウントとSlackを連携させるためのAWS Chatbotクライアントを作成しておく必要があります。
- AWS Chatbotコンソールで、Slackワークスペースとチャンネルを連携させます。
- この設定により、通知先のSlackチャンネルIDとワークスペースIDが取得できます。これらはCDKコード内で使用します。
1. 外部サービスとの認証(OAuthプロセス)が必要
AWS Chatbotは、AWSアカウントと外部サービス(SlackやMicrosoft Teams)の連携を提供します。この連携は、Slack側でAWS Chatbotアプリをインストールし、AWSアカウントへのアクセスを許可するOAuth認証プロセスをユーザー(管理者)がブラウザ上で行う必要があります。
CDKはAWSアカウント内のリソースをプログラマブルにデプロイしますが、Slackワークスペース側の認証フローをプログラムで自動実行することは、セキュリティ上の理由からできません。
2. AWS Chatbot Clientの事前設定が必要
CDKのaws-chatbotモジュールで定義できるのは、連携が完了したワークスペースを参照し、その上でチャンネル設定(どのSNSトピックの通知をどのSlackチャンネルに送るか)を行う部分のみです。
CDKでnew chatbot.SlackChannelConfiguration(...)を作成する前に、通知先のSlackワークスペースID (slackWorkspaceId) を特定する必要があります。このワークスペースIDは、手動でChatbotコンソールからSlackとの連携を完了させた際に初めてAWS側に登録される情報です。
監視とオートスケール基盤の構築
今回は、ECSサービスとRDSインスタンスが既に存在することを前提に、その監視・スケール設定を定義するCDKスタックを作成します。
CDKスタックのセットアップ
必要なCDKライブラリをインポートし、スタックを定義します。
// lib/monitoring-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as actions from 'aws-cdk-lib/aws-cloudwatch-actions';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as autoscaling from 'aws-cdk-lib/aws-applicationautoscaling';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as chatbot from 'aws-cdk-lib/aws-chatbot';
// 環境依存の定数を定義 (適宜置き換えてください)
const CLUSTER_NAME = 'your-ecs-cluster-name';
const SERVICE_NAME = 'your-ecs-service-name';
const RDS_IDENTIFIER = 'your-rds-instance-identifier';
const SLACK_CHANNEL_ID = 'C01234567'; // 取得したチャンネルID
const SLACK_WORKSPACE_ID = 'T01234567'; // 取得したワークスペースID
export class MonitoringStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 既存のECSサービスを参照
const ecsService = ecs.FargateService.fromFargateServiceAttributes(this, 'ExistingEcsService', {
serviceArn: cdk.Stack.of(this).formatArn({
service: 'ecs',
resource: 'service',
resourceName: `${CLUSTER_NAME}/${SERVICE_NAME}`,
sep: '/',
}),
cluster: ecs.Cluster.fromClusterAttributes(this, 'ExistingCluster', {
clusterName: CLUSTER_NAME,
vpc: ({} as any), // 参照のため空オブジェクト
securityGroups: [],
}),
});
}
}
通知用SNSトピックとChatbotの設定
アラームやイベントが通知を送るSNSトピックを作成し、それをAWS Chatbotに連携させます。
// 1. 通知用SNSトピックの作成
const alarmTopic = new sns.Topic(this, 'AlarmTopic', {
displayName: 'System-Monitoring-Notifications',
});
// 2. AWS ChatbotとSNSトピックの連携 (Slackへのルーティング)
new chatbot.SlackChannelConfiguration(this, 'ChatbotConfig', {
slackChannelConfigurationName: 'EcsRdsMonitoring',
slackWorkspaceId: SLACK_WORKSPACE_ID,
slackChannelId: SLACK_CHANNEL_ID,
notificationTopics: [alarmTopic], // このトピックへの通知がSlackに送られる
});
ECSとRDSの監視アラーム設定
主要なメトリクスに対してCloudWatchアラームを作成し、アクションとして上記SNSトピックを設定します。
// --- ECS Fargate アラーム ---
// ECS CPU利用率が80%を超えた場合にアラーム
const ecsCpuAlarm = new cloudwatch.Alarm(this, 'EcsCpuHighAlarm', {
metric: cloudwatch.Metric.fromNamespaceAndName('AWS/ECS', 'CPUUtilization').with({
dimensionsMap: { ClusterName: CLUSTER_NAME, ServiceName: SERVICE_NAME },
}),
threshold: 80,
evaluationPeriods: 2,
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
alarmDescription: 'ECS Service CPU utilization is too high.',
});
ecsCpuAlarm.addAlarmAction(new actions.SnsAction(alarmTopic));
// ecsCpuAlarm.addOkAction(new actions.SnsAction(alarmTopic)); // 復旧時も通知したい場合は追加
// --- RDS アラーム ---
// RDS CPU利用率が70%を超えた場合にアラーム
const rdsCpuAlarm = new cloudwatch.Alarm(this, 'RdsCpuHighAlarm', {
metric: cloudwatch.Metric.fromNamespaceAndName('AWS/RDS', 'CPUUtilization').with({
dimensionsMap: { DBInstanceIdentifier: RDS_IDENTIFIER },
}),
threshold: 70,
evaluationPeriods: 3,
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
alarmDescription: 'RDS CPU utilization is too high.',
});
rdsCpuAlarm.addAlarmAction(new actions.SnsAction(alarmTopic));
ECSサービスのオートスケーリング設定
ECSサービスをCPU利用率$60%$を目標に自動スケーリングするように設定します。
// 3. ECSサービスのオートスケーリング設定
// サービスのDesired Countをスケーリング対象にする
const scalableTarget = autoscaling.ScalableTarget.forEcsService(this, 'EcsScalableTarget', {
service: ecsService,
minCapacity: 1, // 最小タスク数
maxCapacity: 5, // 最大タスク数
});
// 目標CPU利用率 60% を維持するように調整するターゲット追跡スケーリングポリシー
scalableTarget.scaleToTrackMetric('CpuScalingPolicy', {
metric: ecsService.metricCpuUtilization(),
targetValue: 60,
scaleOutCooldown: cdk.Duration.seconds(60),
scaleInCooldown: cdk.Duration.seconds(300),
});
オートスケールイベントのSlack通知設定
スケーリング操作の成功イベントをEventBridgeで捕捉し、Slackに通知します。
// 4. オートスケールイベントを捕捉しSNSトピックへルーティング
new events.Rule(this, 'AutoScalingNotificationRule', {
description: 'Notify Slack on successful ECS Auto Scaling events.',
eventPattern: {
source: ['aws.application-autoscaling'],
detailType: ['Application Auto Scaling Policy Execution'],
detail: {
// 成功したスケーリング操作のみを通知
statusCode: ['Successful'],
},
},
// ターゲットは既存のSNSトピック
targets: [new targets.SnsTopic(alarmTopic)],
});
まとめ
CDKを使うことで、TypeScriptコードで以下の堅牢な運用基盤を構築できました。
- ECS/RDSの重要なメトリクス監視
- CloudWatch AlarmsとChatbotによるSlackへの即時通知
- ECSサービスの負荷に応じた自動スケーリング(スケールイン/アウト)
- スケーリング操作完了時の通知
インフラをコード化することで、再現性、バージョン管理、レビューが可能になり、システムの信頼性が大きく向上します。


