はじめに
EC2とRDS(Aurora)を、グループ単位かつ指定した順番に起動/停止する仕組みを AWS Step FunctionsとLambda(Python 3.9)で作りました。
もう少し詳しく
作成した StepFunctions ステートマシン の詳細を説明します。
以下のように複数のEC2,RDS(Aurora)がある場合に、タグを使いをグループ化と起動順序を設定します。
タグに必要な情報を設定し、起動したいグループと命令(起動命令 or 停止命令)を指定すると、順番に従いリソースを起動or 停止します。
具体的な設定例も含め説明します。以下図のような構成でEC2,RDS(Aurora)を作成します。
※図にはリソースごとのタグ情報を記載しています
各リソースにはこのようにタグを設定します。
| リソース | Nameタグ/DB識別子 | Groupタグ | BootOrderタグ | Group2タグ | BootOrder2タグ |
|---|---|---|---|---|---|
| EC2 | tmp1 | test1 | 2 | ec2only | 1 |
| EC2 | tmp2 | test2 | 2 | ec2only | 2 |
| RDS(Aurora) | database-a | test1 | 1 | - | - |
| RDS(Aurora) | database-b | test2 | 1 | test2A | 1 |
タグ名 Group,Group2はグループの区分け用のタグです。
タグ名 BootOrder,BootOrder2は起動順番を設定するタグです。
作成した StepFunctions ステートマシンは、実行する際にグループ分けのタグと起動順番のタグを指定することができます。これにより、1つのリソースに、グループ分けと起動順番のタグを複数することが可能にしました。
グループ test1 をすぐに起動する場合
グループ test1 に所属するEC2とRDS(Aurora)を起動します。
StepFunctions実行時の 実行入力 は ↓ です。
{
"EXEC": "start",
"DATE": "now",
"GroupTag": "Group",
"GroupValue": "test1",
"BootOrderTag": "BootOrder"
}
※参考※ 実行入力とは以下図のように、作成したStep Functions ステートマシンを実行するときに設定する引数のようなもので、JSON形式で記載します。

実行入力 の各要素の意味はこちら ↓
| 要素 | 説明 |
|---|---|
| EXEC | 実行命令 start or stop
|
| DATE | 実行日時 YYYY-MM-DDThh:mm:ss+09:00例 2021-10-09T21:40:00+09:00now ←即時実行の場合 |
| GroupTag | グループ分けのタグ |
| GroupValue | グループ名 |
| BootOrderTag | 起動順番のタグ |
起動処理は、BootOrderタグの値を昇順で処理します。RDS(Aurora)から起動を開始し、すべてのDBインスタンスが起動完了した後に、EC2が起動開始します。EC2が起動を完了するとStepFunctionsの処理が完了します。
グループ test2 を指定した時刻に停止する場合
グループ test2 に所属するEC2とRDS(Aurora)を停止します。
StepFunctions実行時の 実行入力 は ↓ です。
{
"EXEC": "stop",
"DATE": "2021-10-09T21:40:00+09:00",
"GroupTag": "Group",
"GroupValue": "test2",
"BootOrderTag": "BootOrder"
}
DATEに指定した日時(2021年10月9日21時40分)に命令(今回は停止命令)を実行します。
停止処理は、BootOrderタグの値を降順で処理します。EC2から停止を開始し、停止が完了した後に、RDS(Aurora)が停止を開始します。RDS(Aurora)が停止を完了するとStepFunctionsの処理が完了します。
グループ ec2only をすぐに起動する場合
グループ ec2only に所属するEC2を停止します。
StepFunctions実行時の 実行入力 は ↓ です。これまでの例ではグループ分け用のタグは Group でしたが今回は Group2 を使用します。
{
"EXEC": "start",
"DATE": "now",
"GroupTag": "Group2",
"GroupValue": "ec2only",
"BootOrderTag": "BootOrder2"
}
グループ test2A をすぐに起動する場合
グループ test2A に所属するRDS(Aurora)を起動します。
StepFunctions実行時の 実行入力 は ↓ です。
{
"EXEC": "start",
"DATE": "now",
"GroupTag": "Group2",
"GroupValue": "test2A",
"BootOrderTag": "BootOrder2"
}
以上で使い方の説明はおわりです。
StepFunctions ステートマシン の紹介
概要
ソースはgithubに置きました。
StepFunctionsのフローです。
3種類のLambda(Python 3.9)スクリプトを使用します。
- Lambda (GetTargetResources)
- 対象のリソース(EC2,RDS)の情報を取得し、起動(or停止)の順番に並べる
- 起動の場合:起動順場を示すタグ(BootOrderタグ)昇順に並べ替えます
- 停止の場合:起動順場を示すタグ(BootOrderタグ)降順に並べ替えます
- Lambda (ExecResource)
- 実行命令(start or stop)を実行する
- 実行結果をJSON要素 Response に登録する
- Lambda (StatusCheck)
- 対象のリソースの状態(起動中,停止中,初期化中など)を取得する
- 取得した状態をJSON要素 NextAction に登録する
EC2のステータス別の判定
EC2のステータス判定は、インスタンスの状態(InstanceStatuses)(図赤枠)とステータスチェック(InstanceStatus,SystemStatus)(図青枠)で判定します。
EC2の状態判定について
EC2の状態判定について、running以外はインスタンスの状態(InstanceStatuses)で判定することにしました。
|InstanceStatuses|判定|
|--------|----------------|----|
|NONE|起動命令(start)→WAIT
停止命令(stop)→NEXT|
|pending|WAIT|
|terminated|SKIP|
|stopping|WAIT|
|stopped|起動命令→WAIT
停止命令→NEXT|
|shutting-down|WAIT|
|running|InstanceStatus, SystemStatusで判定|
インスタンスの状態(InstanceStatuses)がrunningの場合は、ステータスチェック(InstanceStatus,SystemStatus)で判定します。
InstanceStatus--SystemStatus--命令 |
判定 | 備考 |
|---|---|---|
ok--ok--stop の場合 |
WAIT | 起動かつ停止命令(stop) |
ok--ok--start の場合 |
NEXT | 停止かつ起動命令(start) |
NONE--NONE--stop |
NEXT | 停止かつ停止命令 |
NONE--NONE--start |
WAIT | 停止かつ起動命令 |
impaired含む |
ERROR | 障害発生 |
insufficient-data含む |
WAIT | データ不足 |
not-applicable含む |
WAIT | 未適用 |
initializing含む |
WAIT | 初期化中 |
| その他 | WAIT |
RDS(Aurora)の状態判定について
RDS(Aurora)には、DBクラスターとDBインスタンスがあります。DBクラスターを起動すると、DBクラスター配下のDBインスタンスも起動を開始します。指定したRDS(Aurora)の起動が完了したかの判定は、そのDBクラスター配下の全DBインスタンスの状態で判定します。
1つのDBクラスターに複数のDBインスタンスが存在する場合があるので、状態判定はそれら全てのDBインスタンスが起動した場合に起動完了と判定するようにします。
DBインスタンスごとに状態の判定は以下表のようにしました。
| DB instance status | 判定 |
|---|---|
| available | 停止命令(stop)→WAIT 起動命令(start)→NEXT |
| backing-up | NEXT |
| configuring-enhanced-monitoring | WAIT |
| configuring-iam-database-auth | WAIT |
| configuring-log-exports | WAIT |
| converting-to-vpc | WAIT |
| creating | WAIT |
| deleting | WAIT |
| failed | ERROR |
| inaccessible-encryption-credentials | ERROR |
| incompatible-network | ERROR |
| incompatible-option-group | ERROR |
| incompatible-parameters | ERROR |
| incompatible-restore | ERROR |
| insufficient-capacity | ERROR |
| maintenance | WAIT |
| modifying | WAIT |
| moving-to-vpc | WAIT |
| rebooting | WAIT |
| resetting-master-credentials | WAIT |
| renaming | WAIT |
| restore-error | ERROR |
| starting | WAIT |
| stopped | 停止命令→NEXT 起動命令→WAIT |
| stopping | WAIT |
| storage-full | ERROR |
| storage-optimization | WAIT |
| upgrading | WAIT |
全DBインスタンスの状態を1つの変数(allRtnVal)に連結して格納し、以下表の判定条件で状態を判定します。
変数allRtnVal
|
判定 |
|---|---|
| ERROR 含む | ERROR |
| WAIT 含む | WAIT |
| その他 | NEXT |
参考
- DBインスタンスのステータス
- SDK(boto3) EC2
- SDK(boto3) RDS
さいごに
モタモタしてたらStep Functionがアップデートしてました。新機能を使って、今回作ったステートマシンをアップデートできたらまたQiitaで紹介しようと思います。

