0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS】CDKで作ってみた!(EC2の自動起動/停止)

0
Posted at

はじめに

EC2の自動起動/停止は、基本的な設定ですがEC2インスタンスを利用する上で

  • 日々の起動作業の省略、待ち時間の削減
  • 停止忘れによる利用料増加の防止

などメリットは大きいと思います。
今回はそんな設定をCDKで実行してみたのでご紹介させていただきます。
コードでは運用しやすい工夫も行っていますので是非ご覧ください。

ソースコードはこちらのGitHubで公開しております。

事前準備

  • AWSアカウントが作成されていること
  • CDK開発環境の構築が完了していること
    (詳しくはこちらをご参照ください。)

AWS 構成図

EC2自動起動停止.drawio.png
EC2の自動起動/停止のアーキテクチャはいくつかあると思いますが、今回はEventBridgeが指定した時間にトリガーを発行し、SSM Automationドキュメントを実行することでEC2の制御を行います。

コードの解説

StackファイルとConfigファイル(パラメータファイル)について抜粋して解説します。
コードの全容はこちらのGitHubからご確認ください。

Stackファイル

lib/ec2-startstop-stack.ts
/**
 * 事前定義
 */
// パラメータファイル読み込み(用途に応じて変更する可能性のあるパラメータは外部ファイルに記述)
const config = require("../config/" + props.nodeEnv);

ここでは、環境ごとのパラメータファイルを読み込んでいます。このCDKコードをデプロイするアカウント、リージョンごとにパラメータファイルを作成し、その設定ごとにスケジュールや対象EC2を簡単に書き換えられるような工夫となっています。

lib/ec2-startstop-stack.ts
// EC2の起動・停止に関する定義
type Ec2Schedule = {
  cron: string;
  action: 'start' | 'stop';
  instanceIds: string[];
};
// 外部ファイルから読み込み
const schedules: readonly Ec2Schedule[] = config.EC2_SCHEDULES;

ここではEC2の制御内容を型として定義しています。
設定ファイルに記述した複数のスケジュールを配列として取得しています。
これにより、複数のEC2インスタンスを個別スケジュールで制御できます。

lib/ec2-startstop-stack.ts
/**
 * EventBridge用IAMロール
 */
const eventsRole = new iam.Role(this, 'EventsRole', {
  roleName: `${config.common.project}-${config.common.env}-events-role`,
  assumedBy: new iam.ServicePrincipal('events.amazonaws.com'),
});
// ポリシー追加
eventsRole.addToPolicy(
  new iam.PolicyStatement({
    actions: [
      'ssm:StartAutomationExecution',
      'ec2:StartInstances',
      'ec2:StopInstances',
    ],
    resources: ['*'],
  })
);

このロールは、EventBridgeがSSM Automationを実行するために使用されます。
assumedBy に events.amazonaws.com を指定することで、EventBridgeがこのロールを利用できるようになります。SSM Automationを実行するための権限としてssm:StartAutomationExecutionを、EC2の起動停止をするための権限としてec2:StartInstances, ec2:StopInstances付与しています。

lib/ec2-startstop-stack.ts
/**
 * スケジュール定義をループしてルール生成
 */
schedules.forEach((schedule, index) => {
  // 起動 / 停止で使う AWS 管理 Automation を切り替え
  const documentName =
    schedule.action === 'start'
      ? 'AWS-StartEC2Instance'
      : 'AWS-StopEC2Instance';

  const ec2StartStopRule = new events.CfnRule(this, `EC2${schedule.action}Rule${index}`, {
    name: `${config.common.project}-${config.common.env}-ec2${schedule.action}${index}-rule`,
    scheduleExpression: schedule.cron,
    state: 'ENABLED',
    targets: [{
      id: 'StartSSMAutomation',
      arn: `arn:aws:ssm:${this.region}::automation-definition/${documentName}:$DEFAULT`,
      roleArn: eventsRole.roleArn,
      input: JSON.stringify({
        InstanceId: schedule.instanceIds,
      })
    }],
  });
});

パラメータファイルで定義したスケジュールをループし、それぞれに対応するEventBridgeルールを生成します。
actionの値に応じて使用するSSM Automationドキュメントを切り替えています。ドキュメントはAWSが提供している以下を利用しています。

  • AWS-StartEC2Instance
  • AWS-StopEC2Instance

cron形式のスケジュールをパラメータファイルから取得し、scheduleExpression に引き渡しています。
input では、Automationドキュメントに対象となるEC2インスタンスIDを渡しています。AWS-StartEC2Instance およびAWS-StopEC2Instance は、InstanceId を配列形式で受け取ります。

Configファイル

本コードを利用する場合は、基本的にこのファイルを修正するのみで大丈夫です。

config/Dev.ts
// 共通パラメータセット
export const common = {
  project: "ec2startstop",
  env: "dev",
  accountId: "12345678912",
  regionId: "ap-northeast-1",
}

環境ごとにtsファイルを作成します。ファイル名のほか、common内で指定する各種パラメータを環境ごとに書き換えて、Stack作成時にこのパラメータを読み込むことで、それぞれの設定でEC2の自動起動/停止を簡単に設定することができます。

config/Dev.ts
/**
 * EC2 の起動・停止スケジュール定義
 *
 * - cron: EventBridge の cron 式
 * - action: start | stop
 * - instanceIds: 対象 EC2 の InstanceId 配列
 */
export const EC2_SCHEDULES = [
  {
    // 平日 朝9時に起動
    cron: 'cron(0 0 ? * MON-FRI *)',
    action: 'start',
    instanceIds: [
      'i-xxxxxxxxxx',
      'i-yyyyyyyyyy',
    ],
  },
  {
    // 平日 夜18時に停止
    cron: 'cron(0 9 ? * MON-FRI *)',
    action: 'stop',
    instanceIds: [
      'i-xxxxxxxxxx',
      'i-yyyyyyyyyy',
    ],
  },
] as const;

例として平日9時と平日18時のcorn形式を示しています。ここをご自身の定義したいスケジュールに書き換えてください。

CfnRuleで指定できる時間はUTCのみとなっているため、日本時間-9時間でcron式を作成する必要があります。

対象となるEC2インスタンスのIDを instanceIds で配列として定義していますので、ここをご自身の起動/停止したいEC2インスタンスのIDに書き換えてください。

本Stackをデプロイ後に、対象となるEC2インスタンスを追加、削除したい場合は、この配列に記載したIDを修正しStackの変更セットをデプロイすることで簡単にメンテナンス可能です。

まとめ

EC2の自動起動/停止のためのCDKコードをご紹介しました。
パラメータファイルを書き換えることで起動/停止のスケジュール、対象のEC2インスタンスをカスタマイズできるような書き方をしてみました。マネジメントコンソールで設定を入れるより運用しやすいのではないでしょうか。
ぜひご活用いただければと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?