Cloud AutomatorでEC2インスタンスを冗長化ぽくしたい

AWS運用自動化サービス「Cloud Automator」

たとえば。。。

たとえばこんな構成があるとします。

AWSでバッチ処理を実行するとなるとLambdaやECS、AWS Batchがあると思いますが、要件が合わずこの構成では1台のEC2インスタンスでバッチ処理を定期的に実行しています。

しかし、EC2に障害があった場合どうしましょうか。

SNSで通知を飛ばして再起動なりAMIから復旧なりや、あらかじめHAクラスター製品を導入しておくなどいろいろ考えられますよね。

Cloud Automatorで??

ワタシは思いつきました。

「うちのサービスのCloud Automatorなら冗長化してるぽできるんじゃね??」と。

実際にやってみた

実際にやってみました。

今回は検証としてCloud Automatorのジョブを含めるとこんな感じの構成。

線がががががががが。。。

1つずつ見ていきましょう。

AWS環境

EC2

EC2を2台用意しました。検証用途なのでAmazonLinux2のt3.microです。今回は間違えて同じAZに構築してしまいましたが、異なるAZに配置するのがよいです。

後述しますが、Cloud Automatorの「EC2: インスタンスでコマンドを実行」はSSMのRunCommandを利用するため、インスタンスにSSMエージェントをインストール・適切なIAMロールを付与し、またインターネットもしくはVPCエンドポイント経由でSSMと通信できる必要があります。

SQS

こちらも後述しますが、Cloud AutomatorでSQSを使用します。あらかじめ2つのSQSキューを作成しておきます。

Cloud Automator

Cloud Automatorのジョブは3つ作成しました。

ジョブ1: バッチ用1でコマンド実行

1つ目のジョブはバッチ用1でコマンドを実行するジョブです。

設定項目 補足
トリガー HTTPトリガー 検証のためHTTPトリガーとしてます。本番環境の場合はタイマートリガーとなるでしょう、
アクション EC2: インスタンスでコマンドを実行 SSMのRunCommand経由でインスタンスにて指定のコマンドを実行します。
参考: EC2: インスタンスでコマンドを実行
コマンド echo kore ha test desu 検証なのでテキトー。本番環境ではバッチ処理を実行するコマンドとなります。
実行コマンドの終了ステータスチェック する 「する」の場合、インスタンス内で実行されたコマンドの終了ステータスによってジョブの成功/失敗を判断できます。今回はインスタンスの障害を想定してるので「しない」
参考: 【Cloud Automator】「EC2: インスタンスでコマンドを実行」アクションに終了ステータスチェックオプションを追加しました
インスタンス接続のタイムアウト秒数 - インスタンスへ接続出来ずに失敗とみなすまでのタイムアウト秒数。デフォルトは900秒なので指定しません。
後処理(成功時) - 検証環境なのでなし。本番環境ではせめてEメール後処理くらいあってもよいかも。
後処理(失敗時) SQS後処理
Eメール後処理
SQS後処理で指定のSQSキューにメッセージを送信します。あらかじめ作成しておいたうちの1つを指定します。
参考: SQS後処理

ジョブ2: バッチ用2の起動

バッチ用1でのRunCommand失敗時にバッチ用2を起動するジョブです。

設定項目 補足
トリガー SQSトリガー 指定したSQSキュー内にメッセージがあるとそれをトリガーとします。ここではジョブ1のSQS後処理で指定したキューをトリガーとします。
アクション EC2: インスタンスを起動 指定のインスタンスを起動します。
参考: EC2: インスタンスを起動
リソースの終了ステータスチェック する これを「する」にしておくと、インスタンスの状態が「running」になった場合にジョブが成功したと判断されます
後処理(成功時) SQS後処理 SQS後処理で指定のSQSキューにメッセージを送信します。ジョブ1で指定したものとは別の残りの1つを指定します。
後処理(失敗時) Eメール後処理 バッチ用2の起動の失敗時にメール通知します。その後は手動で何とかするしかないですね。

ジョブ2: バッチ用2でコマンド実行

バッチ用2でのRunCommand失敗時にバッチ用2を起動するジョブです。トリガー以外はだいたいジョブ1と同じです。

設定項目 補足
トリガー SQSトリガー 指定したSQSキュー内にメッセージがあるとそれをトリガーとします。ここではジョブ1のSQS後処理で指定したキューをトリガーとします。
アクション EC2: インスタンスでコマンドを実行 SSMのRunCommand経由でインスタンスにて指定のコマンドを実行します。
参考: EC2: インスタンスでコマンドを実行
コマンド echo kore ha test desu 検証なのでテキトー。本番環境ではバッチ処理を実行するコマンドとなります。
実行コマンドの終了ステータスチェック しない 「する」の場合、インスタンス内で実行されたコマンドの終了ステータスによってジョブの成功/失敗を判断できます。今回はインスタンスの障害を想定してるので「しない」
インスタンス接続のタイムアウト秒数 - インスタンスへ接続出来ずに失敗とみなすまでのタイムアウト秒数。デフォルトは900秒なので指定しません。
後処理(成功時) Eメール後処理 成功のメール通知。
後処理(失敗時) Eメール後処理 失敗のメール通知。その後は手動で何とかするしかないですね。

試してみた

正常なとき

バッチ用1を起動した状態にします。

ジョブ1をHTTPトリガーで実行しました。成功したぽいです。

障害のとき

バッチ用1を削除してみました。

ジョブ1をHTTPトリガーで実行しましたが、失敗しました。

ジョブ2でバッチ用2の起動が成功しました。

ジョブ3のを確認すると、、、成功しています。

念のためRunCommandを確認、、、成功してるぽいです。

まとめ

いかがでしたでしょうか?思いつきで検証してみましたが、実際使うとなるとこの方法はどうなんでしょうか??タイムアウト時間とかは調整しないといけないかもしれませんね。

AWS運用自動化サービス「Cloud Automator」