Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

AWS Instance Schedulerで勤務時間外にJenkinsサーバーを停止させる

この記事はモバイルファクトリー Advent Calendar 2020 6日目の記事です。


はじめましての方ははじめまして、エンジニアの id:Nanamachi です。今回の記事ではテストに用いているJenkinsサーバーを勤務時間外に停止させる設定を行ったときに用いた AWS Instance Scheduler について解説します。

TL; DR

# 課題
AWS上で稼働しているJenkinsサーバーが勤務時間外も動作しており、必要のない費用がかかっていた

# 手法
AWS Instance Schedulerを用いてインスタンスの起動停止設定をスケジュールした

# 結果
勤務時間外はインスタンスが停止するようになった
- 突発対応などで設定を変更することも簡単にできる
- 停止させたいサーバーが増えたときもそのインスタンスにタグを付けるだけでよい

背景

現在所属しているチームではテスト基盤としてJenkinsを用いています。ここではテスト時間の高速化のためマシンスペックの高いインスタンスを使っており、勤務時間外も動きっぱなしにしてしまうとそこそこの費用が発生してしまいます。そのため、夜間・休日にインスタンスを停止させて費用削減することとなりました。

手法調査

調査開始当初は、すでに時間帯ごとのスケールアウト用途として使用実績のあったEC2 AutoScalingを使う想定でした。しかし、AutoScalingではインスタンスの停止ではなく終了処理がなされてインスタンスの状態が保存されないためNGと判断しました。

そこで代わりとなる手法を調査したところ AWSが公式で情報提供しているInstance Schedulerを発見しました。これはCloudFormationのテンプレートとして提供されている機能で、数分程度で設定が完了するほか複数のインスタンスを柔軟に設定できる点が特徴です。他の手法としてはCloudWatchやLambdaを検討したのですが、最も手間がかからず適用できる方法としてこちらを採用します。

Instance Scheduler の解説

Instance Schedulerのテンプレートでは多くの要素が定義されており初めて見ると面食らってしまいますが、実際に行われていることは単純です。

  1. Amazon EventBridge (旧: CloudWatch Event) が定期的にトリガーする
  2. トリガーされたAWS LambdaをDynamoDBの設定を元に実行する
  3. LambdaがEC2インスタンスやRDSにつけられたタグを見て起動・停止する

f:id:Nanamachi:20201204175725p:plain
Instance Scheduler の構成 (画像出典: https://aws.amazon.com/jp/solutions/implementations/instance-scheduler/ )

これらの設定と必要な権限をまとめてCloud Formationで作成することが可能です。

Instance Schedulerの設定手順

AWSソリューションドキュメントを見ながら設定していきます。ドキュメントが詳細に書かれているためこの記事ではかいつまんで必要そうな点を解説します。

1. テンプレートから作成する

上記「AWSソリューション」のページにある「AWSコンソールで起動する」をクリックするとテンプレートを選択した状態となります。非常に便利なのですが、このとき リージョンがバージニア北部 に変更されているので画面の右上から対象のリージョンに忘れずに変更しましょう。

2. スタックの詳細を指定

「スタックの名前」は任意の名前を指定します。一度デプロイしてしまえば複数のリージョン・アカウントのインスタンス全てに対して設定を行うことが可能になるので、対象となるサービス名をつけずに「InstanceScheduler」とするのがおすすめです。

その下にはテンプレートのパラメータが定義されています。よく使いそうなオプションを抽出すると下記のとおりです。

パラメータ名 デフォルト 解説
Instance Scheduler tag name Schedule InstanceScheduler がインスタンスのスケジュールを区別する際に見るタグ
Service(s) to schedule EC2 EC2だけでなくRDS、またその両方のスケジュールを管理することが可能です
Regions (空白) Instance Scheduler をデプロイしたリージョン以外を管理したい場合はこちら
Default time zone UTC タイムゾーンです。日本時間ならば Asia/Tokyo
Cross-account roles (空白) 複数のAWSアカウントについて管理する場合はこちら
Frequency 5 InstanceSchedulerのイベントが実行される間隔です(単位: 分)

3. スタックオプションの設定 / レビュー

「スタックオプションの設定」は作成されるFormation自体の設定です。デフォルトのまま次へ進み、内容が良ければ作成します。

4. スケジュールの設定

CloudFormationによってスケジュールなどを定義するための ConfigTable がDynamoDBに作成されます。 ConfigTableには次の3種類のtypeが定義されています。 - config - Instance Scheduler全体の設定 - 必要がある場合はCloudFormationから設定し、このレコードは直接編集しない - period - 曜日や日付、起動時間、停止時間といったインスタンスが起動する時間を定義するレコード - schedule - periodやTZ、起動設定などを束ねたレコード - 複数のperiodをまとめることやインスタンス種別ごとに異なるperiodを指定することもできる - 管理対象インスタンスのタグ値にはこの名前を指定する

新しくperiodやscheduleを作成する場合、各項目の型を間違えないようにするためデフォルトで用意されているレコードをコピーして作成するのがおすすめです。

5. インスタンスにタグを付ける

上記で作成したscheduleを対象となるインスタンスに設定します。EC2コンソールに移動し、 Schedule: (スケジュール名) のタグを設定するだけでそのインスタンスがSchedulerの管理下に入ります。

結果

テンプレートやドキュメントが詳細に整備されているため、1時間もかからずに設定することが可能です。また、設定もDynamoDBコンソールから管理できるため、手軽に変更することができます。さらに、Instance Schedulerを1回デプロイしてしまえば他のサーバーもタグを付けるだけで同様のスケジュール設定を適用することができます。


明日の記事は id:odan3240 さんです!