【CDKで構築】AWS ECS/RDSの監視・オートスケール基盤を自動構築しSlack通知する方法

B!

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クライアントを作成しておく必要があります。

  1. AWS Chatbotコンソールで、Slackワークスペースチャンネルを連携させます。
  2. この設定により、通知先のSlackチャンネルIDワークスペースIDが取得できます。これらはCDKコード内で使用します。
CDKでAWS Chatbot連携が完結しない理由

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コードで以下の堅牢な運用基盤を構築できました。

  1. ECS/RDSの重要なメトリクス監視
  2. CloudWatch AlarmsとChatbotによるSlackへの即時通知
  3. ECSサービスの負荷に応じた自動スケーリング(スケールイン/アウト)
  4. スケーリング操作完了時の通知

インフラをコード化することで、再現性、バージョン管理、レビューが可能になり、システムの信頼性が大きく向上します。

 

最新の記事はこちらから