コストを最優先し、手動での介入を許容する範囲での障害復旧手順をいろいろ考えてみました。
前提
・AMIは7世代分くらいを毎日取得している
・起動テンプレは作成済み
・シングルAZ構成でパブリックサブネットにALB + EC2構成
手動でやっていく
「障害インスタンス発生 → メール通知 → 手動で、起動テンプレートのAMIを最新のものに設定 → Auto Scalingの希望容量と最小容量を1に設定」
という手順は、Auto Scaling Group (ASG) の本来の自動復旧能力を最大限に活用できておらず、手動作業が多く、迅速な復旧という観点からは最適ではありません。
コストを抑えつつ、EC2インスタンス単体障害からの自動復旧を目指すのであれば、
「常に最新のAMIを使用するように起動テンプレートを設定し、ASGの最小容量/希望容量を1にしておく」
ことが、追加コストを発生させずに自動復旧を実現する、最も良い方法です。
なぜこの方法が最適ではないのか
ASGの基本的な機能として、ヘルスチェックに失敗したインスタンスを自動的に置き換える機能があります。この機能は、追加料金なしで利用できます。
この手順だと、以下の点が課題となります。
「手動で、起動テンプレートのAMIを最新のものに設定」:
-
- ASGは、起動テンプレートで指定されたAMIを使ってインスタンスを起動します。
- もし、起動テンプレートのAMIが常に最新になっていないと、障害時に古いAMIからインスタンスが起動されてしまい、最新のデータや設定が反映されません。
- 毎日AMIを取得しているのに、それを手動で起動テンプレートに反映させる作業は、手間がかかるだけでなく、緊急時にAMIの指定ミスをするリスクもあります。
- ASGの「インスタンスの置き換え」機能自体は、現在の起動テンプレートの設定に基づいて自動で行われます。障害時に手動で起動テンプレートを更新してからASGの設定を変更するのは、手間も時間もかかり、復旧が遅れます。
「Auto Scalingの希望容量と最小容量を1に設定」:
-
- これはASGの基本的な設定として、常に「1」にしておくべきです。
- ASGがインスタンスの障害を検知すると、自動的にそのインスタンスを終了し、新しいインスタンスを「希望容量 (Desired Capacity)」を満たすように起動しようとします。 もし希望容量が1であれば、障害インスタンスを終了後、新しいインスタンスを1台起動します。
- この挙動は、希望容量や最小容量を「0」から「1」に変更するような手動操作を必要としません。
コストを抑えつつ自動復旧を目指す最も良い方法(修正案)
ASGが提供する無料の自動復旧機能を最大限に活用し、かつコストを抑えるためには、以下の手順が最も良いです。
-
DLM (Data Lifecycle Manager) でAMIの自動取得と世代管理を設定する:
- これにより、毎日自動でAMIが取得され、古いAMIは自動で削除されます。ここには手動介入は不要です。
-
Auto Scaling Group (ASG) を適切に設定する:
- 起動テンプレート (Launch Template) を作成し、常に最新のAMI IDを参照するようにする(ここが少し工夫が必要な部分です。後述します)。
- ASGの最小容量 (Min capacity) を
1
に設定します。 - ASGの希望容量 (Desired capacity) を
1
に設定します。 - ASGの最大容量 (Max capacity) を
1
以上(例えば1
または2
)に設定します。(1
にすると、常に1台しか存在しません。スケールアウトはしません。) - ALBのターゲットグループと連携させ、ALBのヘルスチェックを使用するようにASGを設定します。
- これにより、インスタンスが障害を起こしたり、ALBのヘルスチェックに失敗したりした場合、ASGが自動的にそのインスタンスを終了し、起動テンプレートに指定されたAMIから新しいインスタンスを「自動で」起動し直します。
ASGが常に最新のAMIを参照するようにする工夫(推奨)
これが「手間なく自動復旧」を実現する上で最も重要な点です。
方法1: 定期的な手動更新(初期の労力は少ないが運用負荷)
-
- DLMで新しいAMIが作成されるたびに、手動で起動テンプレートの新しいバージョンを作成し、そこに最新のAMI IDを指定します。
- ASGは、デフォルトで起動テンプレートの最新バージョンを使用するように設定できます(または特定のバージョンを指定することも可能)。
- コストはかかりませんが、毎日手動で更新する手間が発生します。
方法2: AWS CLI/Lambdaを使った起動テンプレートの自動更新(推奨)
-
- DLMが新しいAMIを作成したイベントをトリガーに、AWS Lambda関数が起動するようにEventBridge(旧CloudWatch Events)を設定します。
- このLambda関数内で、AWS CLI(またはAWS SDK)を使って以下の処理を実行します。
- DLMで作成された最新のAMIのIDを取得する。
- 既存の起動テンプレートの新しいバージョンを作成し、その中に最新のAMI IDをセットする。
- (オプション)ASGに、その新しい起動テンプレートバージョンを使用するように指示する(ASGが「最新バージョンを使用」設定なら不要)。
- この方法であれば、AMIが作成されると自動的にASGが最新のAMIを参照するようになり、障害時には常に最新の状態から自動復旧が行われます。
- LambdaとEventBridgeの実行コストは非常に低く、ほとんど無料枠に収まることが多いため、これがコストを抑えつつ最も自動化された良い方法です。
まとめ
コストを抑えつつ単一インスタンスの障害復旧を自動化するならば、
- DLMでAMIの自動作成・世代管理。
- ASGの最小・希望容量を1に設定し、ALBヘルスチェックと連携させる。
- ASGの起動テンプレートが常に最新のAMIを参照するように、手動またはLambdaで自動更新する。
これが、追加のインフラコストなしに、EC2インスタンスの単体障害からの自動復旧を実現するベストなアプローチです。手動でのAMI更新は手間とリスクを伴うため、可能であればLambdaによる自動更新を検討するのが良いです。