要点: Auto Scaling Group(ASG)はメンバーインスタンスを常時監視し、異常と判定したインスタンスを自動で置き換えます。インスタンスの停止や AMI 作成(停止・再起動を伴う)を行うと、この置き換えロジックが操作完了前に発動します。メンテナンスを安全に行うには、インスタンスをデタッチするか、Standby 状態にするか、ASG のプロセスを一時停止する必要があります。

核心の問題: ASG はステータス変化を障害と見なす

Auto Scaling Group は希望キャパシティを維持し続ける仕組みです。ASG のヘルスチェックは一定間隔で実行され、デフォルトでは EC2 ステータスチェック、オプションで ELB ヘルスチェックも使用します。インスタンスが running 以外の状態に遷移すると、ASG はそのインスタンスを異常と判定し、終了して代替インスタンスを起動します。

通常運用ではこれが正しい動作ですが、意図的にメンテナンスのためインスタンスの状態を変更する場合に問題となります。

シナリオ 1: インスタンスの停止

ASG 配下の EC2 インスタンスを停止すると、以下の順序でイベントが発生します。

  1. インスタンスが stoppingstopped 状態に遷移する。
  2. ASG のヘルスチェックがインスタンスの running 状態喪失を検知する。
  3. ASG がインスタンスを Unhealthy とマークする。
  4. ASG が停止済みインスタンスを終了し、新しいインスタンスを起動する。

結果として、停止したインスタンスは終了されます。後から再起動するつもりで停止しても、ASG はインスタンスを停止状態のまま維持しません。

なぜ問題になるか

  • コスト管理: 営業時間外にインスタンスを停止してコスト削減を図りたい場合でも、ASG が即座に代替を起動するため意味がありません。
  • トラブルシューティング: EBS ボリュームの調査やインスタンスの状態保全のために停止したくても、ASG 配下では不可能です。

シナリオ 2: AMI の作成

EC2 インスタンスから AMI を作成する方法は主に以下の通りです。

  • 再起動なし(--no-reboot: インスタンスを再起動せずに AMI を作成します。ASG 内でも安全ですが、書き込み中のデータがフラッシュされないためファイルシステムの整合性リスクがあります。
  • デフォルト(再起動あり): クリーンなスナップショットを取るためにインスタンスを再起動します。通常は再起動が短時間で完了するため ASG のヘルスチェックに引っかかりませんが、ヘルスチェック猶予期間やタイミングに依存します。
  • 停止ベースの AMI 作成: 完全に整合性のあるスナップショットを取るためにインスタンスを先に停止するワークフローです。シナリオ 1 と同じ終了シーケンスが発動します。

再起動がヘルスチェック間隔より長くかかった場合、または ELB ヘルスチェックが有効で再起動中にインスタンスが応答しなかった場合、ASG は AMI 作成中にインスタンスを終了する可能性があります。結果として、不完全な AMI 終了されたインスタンスが残ります。

回避策 1: インスタンスのデタッチ

インスタンスを終了せずに ASG から取り外すことができます。

aws autoscaling detach-instances \
  --instance-ids i-0123456789abcdef0 \
  --auto-scaling-group-name my-asg \
  --should-decrement-desired-capacity

動作

  • インスタンスが ASG から除外され、ヘルスチェックの対象外になります。
  • --should-decrement-desired-capacity を指定すると、ASG の希望キャパシティが 1 減ります。省略すると即座に代替インスタンスが起動されます。
  • デタッチされたインスタンスはスタンドアロンの EC2 インスタンスとして稼働し続けます。

メンテナンス完了後

停止/起動、AMI 作成などが済んだら、インスタンスを終了するか再アタッチします。

aws autoscaling attach-instances \
  --instance-ids i-0123456789abcdef0 \
  --auto-scaling-group-name my-asg

トレードオフ

  • インスタンスは ASG の保護対象外となります(自動復旧やスケーリングアクションの対象外)。
  • 再アタッチまたは終了を忘れると、孤立したインスタンスのコストが蓄積します。
  • 希望キャパシティを減らさなかった場合、一時的に余分なインスタンスが稼働します。

回避策 2: Standby 状態にする

インスタンスをサービスに戻す予定がある場合、Standby が推奨される方法です。

aws autoscaling enter-standby \
  --instance-ids i-0123456789abcdef0 \
  --auto-scaling-group-name my-asg \
  --should-decrement-desired-capacity

動作

  • インスタンスが ASG 内で Standby 状態に移行します。
  • 当該インスタンスに対する ASG のヘルスチェックが一時停止されます。
  • ロードバランサー配下の場合、ターゲットグループから自動的に登録解除されます。
  • インスタンスは ASG のメンバーのままです(グループから離脱していません)。

これで安全にインスタンスの停止、AMI 作成、パッチ適用などのメンテナンスが可能です。完了後:

aws autoscaling exit-standby \
  --instance-ids i-0123456789abcdef0 \
  --auto-scaling-group-name my-asg

インスタンスが InService に復帰し、ロードバランサーに再登録され、ヘルスチェックが再開します。

Standby とデタッチの比較

観点 Standby デタッチ
インスタンスが ASG に残るか はい いいえ
ヘルスチェックの一時停止 はい 対象外(グループ外)
サービス復帰の容易さ exit-standby attach-instances
ロードバランサー登録解除 自動 手動
孤立インスタンスのリスク 低い 高い
ユースケース 一時的なメンテナンス 恒久的な除外や長期作業

回避策 3: ASG プロセスの一時停止

複数のインスタンスに同時にメンテナンスを行う場合、個別に Standby にするよりも ASG プロセスの一時停止が効率的です。

aws autoscaling suspend-processes \
  --auto-scaling-group-name my-asg \
  --scaling-processes HealthCheck ReplaceUnhealthy Launch Terminate

停止すべき主要プロセス

  • HealthCheck: ASG によるインスタンスの異常判定を停止します。
  • ReplaceUnhealthy: 異常インスタンスの終了と代替起動を停止します。
  • Launch / Terminate: メンテナンスウィンドウ中のスケーリングアクションを防止します。

完了後に再開:

aws autoscaling resume-processes \
  --auto-scaling-group-name my-asg \
  --scaling-processes HealthCheck ReplaceUnhealthy Launch Terminate

リスク

プロセスの一時停止はグループ内の全インスタンスの自己修復を無効化します。作業対象以外のインスタンスがこの間に障害を起こしても代替されません。停止期間はできる限り短く保ちましょう。

回避策 4: --no-reboot で AMI 作成(注意付き)

AMI の作成だけが目的で、ファイルシステムの不整合を許容できる場合:

aws ec2 create-image \
  --instance-id i-0123456789abcdef0 \
  --name "my-ami-$(date +%Y%m%d)" \
  --no-reboot

状態変化が発生しないため、ASG は何も検知しません。ただし、ディスク書き込み中のアプリケーション(データベース、キューなど)では破損したスナップショットが生成される可能性があります。OS とアプリケーションコードのみを含むステートレスなインスタンスには適しています。

判断フローチャート

ASG インスタンスのメンテナンスが必要?
│
├─ AMI 作成のみ?
│  ├─ ステートレスなインスタンス → --no-reboot を使用
│  └─ ステートフル / 整合性のあるスナップショットが必要
│     └─ Standby → AMI 作成 → Exit Standby
│
├─ インスタンスを停止して調査?
│  └─ Standby → 停止 → 調査 → 起動 → Exit Standby
│
├─ 複数インスタンスへのパッチ適用?
│  └─ HealthCheck + ReplaceUnhealthy を一時停止 → パッチ → 再開
│
└─ インスタンスの恒久的な除外?
   └─ --should-decrement-desired-capacity でデタッチ

注意すべきポイント

  1. ELB ヘルスチェックはリスクを増幅する。 ASG が ELB ヘルスチェック(EC2 ステータスチェックだけでなく)を使用している場合、短時間の再起動でもヘルスチェックプローブへの応答が途切れて異常と判定される可能性があります。

  2. ライフサイクルフックとの相互作用。 ASG にライフサイクルフックが設定されている場合、デタッチや Standby 移行がフックアクションをトリガーすることがあります。本番環境以外で事前にテストしましょう。

  3. スケーリングポリシーは引き続き発火する。 インスタンスを Standby にするとキャパシティが減少し、スケールアウトポリシーが発動して代替インスタンスが起動されることがあります。--should-decrement-desired-capacity の設定を意図的に判断してください。

  4. インスタンス保護と Standby は別物。 スケールイン保護(SetInstanceProtection)はスケールイン時の終了対象選定を防ぎますが、ASG が異常と判定したインスタンスの終了は防ぎません。ヘルスチェック起因の終了を防ぐには Standby またはプロセスの一時停止が必要です。

  5. クールダウン期間。 プロセス再開後、ASG がスケーリングイベントに応答するまでクールダウン期間に入ることがあります。メンテナンスウィンドウの計画に織り込みましょう。

まとめ

Auto Scaling Group は健全なフリートを自動的に維持するよう設計されています。その同じ自動化が、インスタンスの停止や AMI 作成といったルーティンメンテナンスでは障害になります。重要なポイントは、インスタンスの状態を変更する前に ASG の管理を一時的に外す必要があるということです。Standby・デタッチ・プロセス一時停止のいずれかを、メンテナンスの範囲と期間に応じて選択してください。