はじめに
企業で運用しているシステムではユーザにサービスを提供している本番環境とは別に開発用の環境など複数の環境を用意して本番環境に影響を与えずに開発を行えるようにしているシステムが多いのではないかと思います。
当然ながら開発環境を利用する方は限られており、開発者がいない時間は無駄に費用がかかってしまうことから、費用削減のため開発者が退勤する際にサーバを停止するようなことを行っている会社も多いかと思います。
今回、AWSのStep Functionsを使用してEC2、ECS、RDSをまとめて停止・起動する処理を作成したため、JSONata形式のStep Functionsの書き方を紹介しつつ、何回かに分けてEC2、ECS、RDSをまとめて停止起動するStep Functionsを作成しようと思います。
今回のStep Functionsのフロー概要
もともと同様の処理は導入しておりましたが、最近Step FunctionsがJSONataの書式に対応したことで、ワークフローが格段に書きやすくなったため、書式の変更を行うついでにロジックの変更も行い、結果として以下のようなフローを作成しました。
停止時はアカウントに存在するリソースすべてをまとめて停止し、起動時はRDSを先に立ち上げてからEC2、ECSを起動するようにしており、DBアクセスができないと起動に失敗するような問題が発生しないようにしました。
また、祝日や特別休暇などにも対応できるよう、Change Calendarを使用し、EventBridge等のcron式だけでは対応しきれない場合にも対応しております。
多くのシステムで使えるフローとなっているかと思いますが、システムごとに微調整する必要はあると思うので、使用する場合はシステムの特性に応じてチューニングするようにしてください。
Change Calendarの作成
リソースの停止起動自体はStep Functionsで実行しますが、Step Functionsを実行するためにChange CalendarとEventBridgeを使って定期的に実行する仕組みを作成していきます。
祝日カレンダーのエクスポート
後述のChange Calendarで祝日カレンダーを使用するため、iCal形式のカレンダーをエクスポートしておきます。
以前はGoogleカレンダーの祝日カレンダーを使用することができましたが、最近フォーマットが変わったようで、GoogleカレンダーからエクスポートしたカレンダーではChange Calendarにインポートできなくなってしまったため、今回はMacOSのデフォルトカレンダーからエクスポートする方法を紹介します。
Googleカレンダー以外のiCal形式カレンダーであればおそらく使用できるかと思うので、MacOS以外の方は他のiCal形式のカレンダーをご使用ください。
MacOSの「カレンダー」を起動し、左ウィンドウに表示されている「日本の祝日」を選択、上バーの「ファイル」→「書き出す」→「書き出す」よりiCal形式のカレンダーとしてエクスポートします。
Change Calendarの作成
定期的にStep Functionsを実行するだけであればEventBridgeだけでも可能ですが、cron形式の場合、祝日に対応することが難しいため、祝日や特別休暇のようなcron形式だけでは対応が難しいパターンにも対応させるため、Change Calendarを使用します。
Systems Managerダッシュボードより「変更管理ツール」の「カレンダーの変更」から「カレンダーを作成」で以下のようなカレンダーを作成します。
| 項目 | 設定 | 備考 |
|---|---|---|
| カレンダー名 | stop-start-calendar | 任意のカレンダー名を設定 |
| 説明 | 空欄 | 今回は未設定 |
| Import calendar | 祝日カレンダー | 先ほどエクスポートした祝日カレンダーを指定 |
| カレンダータイプ | デフォルトで開く | 今回は停止する時間帯を登録するようにしたいためデフォルトで開くを選択 |
| Add change management events to the calendar | チェックしない | チェックするとState Managerのイベントが表示されてしまうため、チェックしない |
Change Calendarイベントの作成
先ほど作成したカレンダーを選択し、「イベントを作成」から停止する日時を設定していきます。
今回は例として、土曜日、日曜日は終日停止、平日は00:00〜08:00まで停止するイベントを作成してみようと思います。
| 項目 | 土曜日(終日) | 日曜日(終日) | 平日(00:00-08:00) |
|---|---|---|---|
| スケジュールされたイベントの名前 | ※任意の名前を指定 | ※任意の名前を指定 | ※任意の名前を指定 |
| 説明 | ※任意で設定 | ※任意で設定 | ※任意で設定 |
| Advisory | チェックなし | チェックなし | チェックなし |
| イベント開始日 | ※次の土曜日を指定 | ※次の日曜日を指定 | ※次の月曜日を指定 |
| Event start time | 00:00:00 | 00:00:00 | 00:00:00 |
| イベント終了日 | ※次の日曜日を指定 | ※次の月曜日を指定 | ※次の月曜日を指定 |
| Event end time | 00:00:00 | 00:00:00 | 08:00:00 |
| タイムゾーンをスケジュール | (GMT+09:00)Asia/Tokyo | (GMT+09:00)Asia/Tokyo | (GMT+09:00)Asia/Tokyo |
| 繰り返し | 有効化 | 有効化 | 有効化 |
| 繰り返し単位 | Weekly | Weekly | Weekly |
| 繰り返し期間 | Every week | Every week | Every week |
| 繰り返し曜日 | Saturday | Sunday | Monday〜Friday |
| 繰り返し回数 | Repeat forever | Repeat forever | Repeat forever |
Change CalendarのARN確認
後ほど使用するため、事前にARNを確認しておきます。
カレンダーの画面より、「Details」を選択し、「Calendar use」に記載されているARNを控えておいてください。
IAMポリシー&ロールの作成
後ほど作成するEventBridgeとStep Functionsで使用するIAMポリシーとIAMロールをあらかじめ作成しておきます。
EventBridge、Step Functions作成時に自動で作成されるIAMロールを使用しても良いですが、今回は作成するポリシー・ロールを明示するために手動で作成します。
EventBridge用IAMポリシーの作成
EventBridge用のポリシーは、Step Functionsを実行するだけの権限があればよいので、IAMダッシュボードの「ポリシー」→「ポリシーの作成」より以下のように作成していきます。
途中の「Resource state machine name」で後ほど作成するStep Functionsの名前を指定する部分があるので、Step Functionsに指定する名前は事前に決めておいてください。
| 項目 | 設定 | 備考 |
|---|---|---|
| ポリシーエディタ | ビジュアル | ビジュアルモードで作成 |
| サービス | Step Functions | EventBridge経由でStep Functionsを実行するため設定 |
| アクション許可 | StartExecution | Step Functions実行を許可 |
| 次のリソース | このアカウント | 自分の環境に合わせて設定 |
| リソース | 特定 | 「ARNを追加」より以下設定を追加 |
| リソースのリージョン | ap-northeast-1 | 対象のリージョンを指定 |
| Resource state machine name | stop-start-sfn | 後ほど作成するStep Functionsの名前を指定(今回はstop-start-sfn) |
| リソース ARN | arn:aws:states:ap-northeast-1:012345678901:stateMachine:stop-start-sfn | 上記指定すると自動で記載されるため、そのままでOK |
| ポリシー名 | stop-start-eb-policy | 任意の名前を指定 |
| タグ | 空欄 | 今回は未設定 |
EventBridge用IAMロールの作成
先ほど作成したIAMポリシーを指定したIAMロールを作成します。
IAMダッシュボードの「ポリシー」→「ロールを作成」より以下のように作成していきます。
| 項目 | 設定 | 備考 |
|---|---|---|
| 信頼されたエンティティタイプ | カスタム信頼ポリシー | 「AWSのサービス」では任意のポリシーを指定できないためカスタムで作成 |
| STSのアクションを追加 | AssumeRole | ー |
| プリンシパルを追加 | ※選択 | 追加ボタンを選択して以下設定を追加 |
| プリンシパルタイプ | AWS services | ー |
| ARN | events.amazonaws.com | EventBridge用のARNを指定 |
| 条件を追加 | ※未設定 | 今回は条件は不要 |
| 許可ポリシー | stop-start-eb-policy | 先ほど作成したIAMポリシーを指定 |
| ロール名 | stop-start-eb-role | 任意の名前を指定 |
| 説明 | 空欄 | 今回は未設定 |
| タグ | 空欄 | 今回は未設定 |
Step Functions用IAMポリシーの作成
先ほどと同じようにIAMダッシュボードの「ポリシー」→「ポリシーの作成」より以下のように作成していきます。
Step Functionsの場合は、ワークフロー実行のために付与しなければいけない権限が多いので、下記に作成する権限を記載したJSONを用意しました。
下記を参考にIAMポリシーを作成してください。
| 項目 | 設定 | 備考 |
|---|---|---|
| ポリシーエディタ | JSON | 以下のJSONを参考に権限を付与 |
| ポリシー名 | stop-start-sfn-policy | 任意の名前を指定 |
| タグ | 空欄 | 今回は未設定 |
{
"Statement": [
{
"Action": [
"ssm:GetCalendarState",
"ssm:GetCalendar"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "ChangeCalendarPolicy"
},
{
"Action": [
"logs:UpdateLogDelivery",
"logs:PutResourcePolicy",
"logs:ListLogDeliveries",
"logs:GetLogDelivery",
"logs:DescribeResourcePolicies",
"logs:DescribeLogGroups",
"logs:DeleteLogDelivery",
"logs:CreateLogDelivery"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "StepFunctionsPolicy"
},
{
"Action": [
"ec2:StopInstances",
"ec2:StartInstances",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "EC2Policy"
},
{
"Action": [
"rds:StopDBInstance",
"rds:StopDBCluster",
"rds:StartDBInstance",
"rds:StartDBCluster",
"rds:ListTagsForResource",
"rds:DescribeDBClusters"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "RDSPolicy"
},
{
"Action": [
"ecs:UpdateService",
"ecs:StopTask",
"ecs:StartTask",
"ecs:RunTask",
"ecs:ListTasks",
"ecs:ListTagsForResource",
"ecs:ListServices",
"ecs:ListClusters",
"ecs:DescribeServices"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "ECSPolicy"
}
],
"Version": "2012-10-17"
}
Step Functions用IAMロールの作成
先ほど作成したIAMポリシーを指定したIAMロールを作成します。
IAMダッシュボードの「ポリシー」→「ロールを作成」より以下のように作成していきます。
| 項目 | 設定 | 備考 |
|---|---|---|
| 信頼されたエンティティタイプ | カスタム信頼ポリシー | 「AWSのサービス」では任意のポリシーを指定できないためカスタムで作成 |
| STSのアクションを追加 | AssumeRole | ー |
| プリンシパルを追加 | ※選択 | 追加ボタンを選択して以下設定を追加 |
| プリンシパルタイプ | AWS Service | ー |
| ARN | states.amazonaws.com | Step Functions用のARNを指定 |
| 条件を追加 | ※未設定 | 今回は条件は不要 |
| 許可ポリシー | stop-start-sfn-policy | 先ほど作成したIAMポリシーを指定 |
| ロール名 | stop-start-sfn-role | 任意の名前を指定 |
| 説明 | 空欄 | 今回は未設定 |
| タグ | 空欄 | 今回は未設定 |
Step Functionsステートマシン雛形の作成
EventBridgeの設定を行う際、Step Functionsステートマシンを指定する箇所があるため、先にStep Functionsステートマシンを作成しておきます。
ただし、実際のワークフローは次回以降で説明していくため、今回はワークフローを無視してステートマシンの雛形のみ作成していきます。
Step Functionsダッシュボードより「ステートマシン」→「ステートマシンの作成」より以下のように作成していきます。
| 項目 | 設定 | 備考 |
|---|---|---|
| ステートマシンの作成 | 空白から作成 | ー |
| ステートマシン名 | stop-start-sfn | EventBridge用IAMポリシーで指定したStep Functionsの名前を指定 |
| ステートマシンのタイプ | 標準 | ー |
上記入力後、「続行」ボタンを選択するとワークフロー作成画面が表示されます。
ワークフローを適当に設定しないと作成時にエラーとなってしまうため、左ウィンドウの「フロー」から「成功」などあまり影響が無いものを選択し、右のワークフローの画面にドラッグ&ドロップして配置してください。
フロー配置後、画面上部の「設定」より実行ロールのみ指定しておきます。
| 項目 | 設定 | 備考 |
|---|---|---|
| 実行ロール | stop-start-sfn-role | 先ほど作成したStep Functions用IAMロールを指定 |
| ログ記録 | ALL | 実際の運用に合わせて設定 |
| 実行データを含める | チェック | デフォルトのまま |
| CloudWatchロググループ | 新しいロググループを作成 | 実際の運用に合わせて設定 |
| ロググループ名 | /aws/vendedlogs/states/stop-start-sfn-Logs | 実際の運用に合わせて設定 |
| カスタマーマネージドキーでロググループを暗号化 | チェックしない | 実際の運用に合わせて設定 |
| 追加の設定 | 未設定 | 実際の運用に合わせて設定 |
設定後、画面右上の「作成」ボタンを選択し、Step Functionsステートマシンを作成してください。
EventBridgeの作成
先程作成したカレンダーからの通知を受けてStep Functionsを実行するためのEventBridgeルールを作成します。
EventBridgeダッシュボードより、「バス」→「ルール」から「ルールを作成」を選択し、以下のように設定を行います。
| 項目 | 設定 | 備考 |
|---|---|---|
| 名前 | stop-start-eb | 任意の名前を指定 |
| 説明 | 空欄 | 任意で設定 |
| イベントバス | default | ー |
| 選択したイベントバスでルールを有効にする | 有効化 | ー |
| ルールタイプ | イベントパターンを持つルール | ー |
| イベントソース | AWS イベントまたは EventBridge パートナーイベント | ー |
| 作成のメソッド | パターンフォームを使用する | ー |
| イベントソース | AWSのサービス | ー |
| AWSのサービス | Systems Manager | ー |
| イベントタイプ | Calendar State Change | ー |
| イベントタイプの仕様 1 | 特定リソース (ARN 別) | ー |
| 特定リソース (ARN 別) | ※先ほど作成したカレンダーのARN | 先ほど控えたARNを入力 |
| イベントタイプの仕様 2 | 特定の状態 | ー |
| 特定の状態 | OPEN, CLOSE | OPEN、CLOSEDどちらの通知も受け取るため両方指定 |
| イベントタイプの仕様 3 | 任意のイベント | ー |
| ターゲットタイプ | AWS のサービス | ー |
| ターゲットを選択 | Step Functions ステートマシン | ー |
| ステートマシン | stop-start-sfn | 先ほど作成したStep Functionsステートマシンを指定 |
| 実行ロール | 既存のロールを使用 | ー |
| ロール名 | stop-start-eb-role | 先ほど作成したEventBridge用IAMロールを指定 |
| 追加設定 | 未設定 | 実際の運用に合わせて設定 |
| タグ | 未設定 | 実際の運用に合わせて設定 |
おわりに
今回はStep Functionsワークフローを作成する前の前準備としてChange Calendar、EventBridge、Step Functionsの雛形作成まで行いました。
次回から、本題となるStep FunctionsのJSONataを使ったワークフローの基礎から説明していこうと思います。


