✈️ Auto Scaling安全なOSアップデート戦略

飛行機の乗客を新しい機体に移し替えるように、ダウンタイムゼロでシステムを更新
Blue/Green + Rolling Update 完全ガイド

✈️ 飛行機の機材変更で例えると超わかりやすい!

古い飛行機から新しい飛行機への乗客移動 = OSアップデート🛫

飛行中の飛行機(稼働中のサーバー)のOSをアップデートしたい!
でも、 乗客(ユーザー)には一切気づかれたくない 😱

どうする? → 新しい飛行機を用意して、乗客を徐々に移動させる! ✈️→✈️

これが今日学ぶ 「ダウンタイムゼロのOSアップデート戦略」 です。

7つのステップ で完璧に実現できます✨

✈️ 飛行機の機材変更に例えると...

🛩️

古い飛行機(旧OS)

🎯 現在の状態:
• 20年前のモデル(古いOS)
• 100人の乗客が搭乗中(稼働中のサービス)
• セキュリティアップデートが必要
• でも飛行中に作業は不可能

❌ 悪い方法:
飛行中に空中でエンジンを交換?
墜落します!(システムダウン)

🤔 どうすれば?
乗客を降ろさずに、新しい機体に移動させたい...
🛫

新しい飛行機(新OS)

✨ 目指す状態:
• 最新モデル(新しいOS)
• 同じ100人の乗客(継続稼働)
• セキュリティ完璧
• 乗客は移動に気づかない

✅ 正しい方法:
1. 新しい飛行機を100機準備
2. 乗客を1人ずつ新しい機体へ
3. 古い機体は順次着陸
4. 最終的に全員が新機体に!

🎉 これで完璧な移行!
💡 この戦略の正式名称
Blue/Green Deployment + Rolling Update

Blue = 古い環境(古いOS)
Green = 新しい環境(新しいOS)
Rolling = 徐々に切り替え

Auto Scalingグループを 2倍に拡大 して、
古いインスタンスを 徐々に削除 していく手法です。

🎯 ダウンタイム: 完全にゼロ!

🎯 7つのステップで完璧なアップデート

🖼️

Step 1
新しいAMI作成

✈️ たとえ:
最新の飛行機を設計

📋 実際の作業:
• 最新OSでEC2起動
• セキュリティパッチ適用
• 会社標準に準拠
• アプリインストール
• AMIとして保存

重要度: ★★★★★
⚙️

Step 2
起動設定を更新

✈️ たとえ:
新機体の運航許可取得

📋 実際の作業:
• 新しいLaunch Configuration作成
• 新AMIを指定
• Auto Scalingグループに設定
• 古い設定は保持

💡 ポイント:
Launch Templateの使用推奨

重要度: ★★★★☆
📏

Step 3
終了ポリシー設定

✈️ たとえ:
「古い機体から順に着陸」ルール

📋 実際の作業:
• Termination Policy設定
OldestLaunchConfiguration
• 古い設定のインスタンスから削除
• 新しいものは保護

🎯 これが超重要!
これで新旧を区別できる

重要度: ★★★★★
📈

Step 4
グループを2倍に

✈️ たとえ:
新機体を100機追加
(合計200機に)

📋 実際の作業:
• Desired Capacity × 2
• 例: 10台 → 20台
• 新AMIで10台起動
• 古い10台はそのまま

💰 一時的にコスト2倍
でも短時間で済む

重要度: ★★★★★

Step 5
ヘルスチェック待機

✈️ たとえ:
新機体の離陸準備完了確認

📋 実際の作業:
• ELBヘルスチェック通過待ち
• InService状態確認
• アプリが正常起動
• 準備完了まで待機

⏱️ 待機時間:
通常5-10分程度

重要度: ★★★★☆
📉

Step 6
元のサイズに戻す

✈️ たとえ:
古い機体を順次着陸させる

📋 実際の作業:
• Desired Capacity を元に戻す
• 例: 20台 → 10台
• Auto Scalingが自動削除
• OldestLaunchConfigurationから削除
• = 古いインスタンスが削除される

🎉 新しいインスタンスだけ残る!

重要度: ★★★★★
🔒

Step 7
セキュリティ強化

✈️ たとえ:
コックピットへの不正侵入防止

📋 実際の作業:
• EC2インスタンスコンソールアクセス無効
• Systems Manager Session Manager使用
• SSHキー不要に
• 監査ログ完全記録

🛡️ セキュリティ最強化!
直接ログイン禁止

重要度: ★★★★☆

🔄 詳細な実行フロー

0 現在の状態確認
📊 Before: 開始前の状態

• Auto Scalingグループ: 10インスタンス
• 全て古いAMI(例: ami-old-12345)
• Launch Configuration: lc-old-v1
• ユーザー: 1000人が利用中
• ダウンタイム許容: 0秒

🎯 目標: 全インスタンスを新OSに更新
⬇️
1 新AMI作成・起動設定更新
🛠️ 準備作業

📄 AWS CLI例
# 1. 新しいAMI作成(既存インスタンスから)
aws ec2 create-image \
  --instance-id i-xxxxx \
  --name "app-v2-2025-01-01" \
  --description "Updated OS with security patches"

# 2. 新しいLaunch Configuration作成
aws autoscaling create-launch-configuration \
  --launch-configuration-name lc-new-v2 \
  --image-id ami-new-67890 \
  --instance-type t3.medium \
  --security-groups sg-xxxxx

# 3. Auto Scalingグループを更新
aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name my-asg \
  --launch-configuration-name lc-new-v2
✅ 結果: 準備完了!でもまだ新インスタンスは起動していない
⬇️
2 終了ポリシー設定
📏 削除ルールの設定

📄 終了ポリシー設定
aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name my-asg \
  --termination-policies "OldestLaunchConfiguration"

# これで古いLaunch Configurationのインスタンスから削除される
🎯 これが最重要!
• この設定がないと新インスタンスも削除される可能性
• 必ずOldestLaunchConfigurationを指定
• 他のポリシー(OldestInstance等)は不可
⬇️
3 Desired Capacityを2倍に
📈 インスタンス数を倍増

📄 キャパシティ変更
aws autoscaling set-desired-capacity \
  --auto-scaling-group-name my-asg \
  --desired-capacity 20  # 元は10台

# Auto Scalingが自動的に新しいLaunch Configで10台起動
🚀 起動プロセス:
1. Auto Scalingが不足を検出(10台足りない)
2. 新Launch Configuration(lc-new-v2)で起動
3. 新AMI(ami-new-67890)を使用
4. ELBに自動登録
5. ヘルスチェック開始

⏱️ 所要時間: 5-10分
⬇️
4 新インスタンスのヘルスチェック待機
⏳ 全ての新インスタンスがInServiceになるまで待つ

📄 ステータス確認
# Auto Scalingグループのインスタンス状態確認
aws autoscaling describe-auto-scaling-groups \
  --auto-scaling-group-names my-asg \
  --query "AutoScalingGroups[0].Instances[*].[InstanceId,HealthStatus,LifecycleState]"

# 出力例:
# i-old-001    Healthy    InService  ← 古いインスタンス
# i-old-002    Healthy    InService
# ...
# i-new-001    Healthy    InService  ← 新しいインスタンス
# i-new-002    Healthy    InService
# ...
✅ 確認事項:
• 全20台がInService
• ELBヘルスチェック通過
• アプリケーション正常応答
• エラーログなし

💡 この時点で新旧両方が稼働中!
⬇️
5 Desired Capacityを元に戻す
📉 インスタンス数を元の10台に

📄 キャパシティ削減
aws autoscaling set-desired-capacity \
  --auto-scaling-group-name my-asg \
  --desired-capacity 10  # 元に戻す

# Auto Scalingが自動処理:
# 1. 過剰な10台を削除対象に
# 2. 終了ポリシー「OldestLaunchConfiguration」に従う
# 3. 古いlc-old-v1のインスタンスを1台ずつ削除
# 4. ELBから登録解除してから削除
# 5. 新しいインスタンスはそのまま残る
🎯 削除プロセス(自動):
1. ELBから登録解除(Deregister)
2. Connection Draining(既存接続の完了待ち)
3. インスタンス終了
4. 次のインスタンスへ

⏱️ 所要時間: 10-20分(10台削除)
🎉 完了後: 新OSの10台だけが稼働!
⬇️
6 セキュリティ強化とメンテナンス設定
🔒 最終的なセキュリティ設定

1. EC2インスタンスコンソールアクセス無効化:
• Security GroupからSSH(22)削除
• KeyPairを使用しない設定
• Systems Manager経由のみ許可

2. Systems Manager設定:
📄 Session Manager設定
# IAMロールにSSM権限付与(インスタンスプロファイル)
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "ssm:UpdateInstanceInformation",
      "ssmmessages:CreateControlChannel",
      "ssmmessages:CreateDataChannel",
      "ssmmessages:OpenControlChannel",
      "ssmmessages:OpenDataChannel"
    ],
    "Resource": "*"
  }]
}

# これでAWSコンソールから安全にログイン可能
# セッションは全てCloudTrailに記録される
3. 緊急メンテナンス用Runbook設定:
• Systems Manager Automationドキュメント作成
• 定期パッチ適用の自動化
• 障害時の自動復旧スクリプト

✅ セキュリティと運用性が大幅向上!

📊 ビジュアル図解: インスタンスの遷移

🚀 Stage 1: 開始前(10台)
旧1
ami-old
旧2
ami-old
旧3
ami-old
旧4
ami-old
旧5
ami-old
旧6
ami-old
旧7
ami-old
旧8
ami-old
旧9
ami-old
旧10
ami-old

全て古いAMI(ami-old-12345)で稼働中

⬇️ Desired Capacity: 10 → 20
🎯 Stage 2: 2倍に拡張(20台)
旧1
ami-old
旧2
ami-old
旧3
ami-old
旧4
ami-old
旧5
ami-old
旧6
ami-old
旧7
ami-old
旧8
ami-old
旧9
ami-old
旧10
ami-old
新1
ami-new
新2
ami-new
新3
ami-new
新4
ami-new
新5
ami-new
新6
ami-new
新7
ami-new
新8
ami-new
新9
ami-new
新10
ami-new

新しいAMI(ami-new-67890)で10台追加起動
一時的にコスト2倍だが、全てがInServiceで稼働中

⬇️ Desired Capacity: 20 → 10
🔄 Stage 3: 削除プロセス(進行中)
旧1
削除中
旧2
削除中
旧3
削除中
旧4
ami-old
旧5
ami-old
旧6
ami-old
旧7
ami-old
旧8
ami-old
旧9
ami-old
旧10
ami-old
新1
ami-new
新2
ami-new
新3
ami-new
新4
ami-new
新5
ami-new
新6
ami-new
新7
ami-new
新8
ami-new
新9
ami-new
新10
ami-new

OldestLaunchConfigurationポリシーにより
古いインスタンスから順次削除(ELBから登録解除後)

⬇️ 全ての旧インスタンス削除完了
✅ Stage 4: 完了(10台)
新1
ami-new
新2
ami-new
新3
ami-new
新4
ami-new
新5
ami-new
新6
ami-new
新7
ami-new
新8
ami-new
新9
ami-new
新10
ami-new

🎉 全て新しいAMI(ami-new-67890)に更新完了!
ダウンタイム: 0秒 | ユーザーへの影響: なし

📊 他の更新手法との比較

手法 ダウンタイム リスク コスト 推奨度
この手法(Blue/Green + Rolling) 0秒 超低 一時的に2倍 ★★★★★
全停止→更新→再起動 30-60分 増加なし ★☆☆☆☆
Rolling Update(1台ずつ) 部分的 増加なし ★★★☆☆
インプレース更新(yum update) 一時的 超高 増加なし ★★☆☆☆
Blue/Green(完全切替) 0秒 常時2倍 ★★★★☆
🏆 なぜこの手法が最適なのか?
完璧なバランス!

✅ メリット:
• ダウンタイム完全ゼロ
• リスク最小(問題あれば即ロールバック)
• コストは一時的のみ(15-30分程度)
• ユーザーへの影響なし
• 自動化が容易

⚠️ 注意点:
• 一時的にキャパシティが2倍必要
• 15-30分程度コストが増加
• でも本番環境ではこれが最適!

💡 実務では圧倒的にこれが推奨されます
🏆 実装のベストプラクティス
1. 事前テストを必ず実施
• 開発環境で完全にテスト
• 新AMIの動作確認
• ヘルスチェック通過を確認
• タイミング(15-30分)を計測

2. メンテナンス時間帯を選ぶ
• ダウンタイムはゼロだが念のため
• 低トラフィック時間帯(深夜など)
• ビジネスアワーは避ける
• チーム全員が待機できる時間

3. モニタリングを強化
• CloudWatch Alarmsを設定
• エラー率、レスポンスタイムを監視
• 新旧両方のメトリクスを比較
• 異常があれば即座にロールバック

4. ロールバック手順を準備
• 古いLaunch Configurationを保持
• 問題発生時の切り戻し手順書
• ワンコマンドでロールバック可能に
• 5分以内に元に戻せるように

5. 段階的なロールアウト
• 最初は小規模環境で実施
• 問題なければステージング
• 最後に本番環境
• 複数リージョンある場合は1つずつ

6. 通知設定
• SNSトピック設定
• Auto Scaling イベントを通知
• Slackに自動投稿
• チーム全員が状況把握

7. コスト最適化
• 一時的な2倍期間を最小化
• Connection Draining時間を調整
• 不要な待機時間を削減
• 通常15-20分で完了するように調整

8. 自動化スクリプト化
• 全ステップをスクリプト化
• AWS CLI / Boto3 / Terraform
• 人的ミスを排除
• CI/CDパイプラインに組み込み

💻 完全な実装スクリプト例

🐚 Bash スクリプト完全版
#!/bin/bash
# Auto Scaling安全なOSアップデートスクリプト

set -e  # エラーで停止

# 設定
ASG_NAME="my-auto-scaling-group"
NEW_AMI="ami-new-67890"
NEW_LC_NAME="lc-new-v2-$(date +%Y%m%d)"

# 現在の設定を取得
echo "📊 現在の設定を取得中..."
CURRENT_CAPACITY=$(aws autoscaling describe-auto-scaling-groups \
  --auto-scaling-group-names ${ASG_NAME} \
  --query "AutoScalingGroups[0].DesiredCapacity" \
  --output text)

echo "現在のCapacity: ${CURRENT_CAPACITY}"

# Step 1: 新Launch Configuration作成
echo "🔧 Step 1: 新Launch Configuration作成..."
aws autoscaling create-launch-configuration \
  --launch-configuration-name ${NEW_LC_NAME} \
  --image-id ${NEW_AMI} \
  --instance-type t3.medium \
  --security-groups sg-xxxxx \
  --iam-instance-profile my-instance-profile \
  --user-data file://userdata.sh

# Step 2: Auto Scalingグループ更新
echo "🔄 Step 2: Auto Scalingグループ更新..."
aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name ${ASG_NAME} \
  --launch-configuration-name ${NEW_LC_NAME} \
  --termination-policies "OldestLaunchConfiguration"

# Step 3: Desired Capacityを2倍に
NEW_CAPACITY=$((${CURRENT_CAPACITY} * 2))
echo "📈 Step 3: Capacityを${CURRENT_CAPACITY}から${NEW_CAPACITY}に拡大..."
aws autoscaling set-desired-capacity \
  --auto-scaling-group-name ${ASG_NAME} \
  --desired-capacity ${NEW_CAPACITY}

# Step 4: 新インスタンスのInService待機
echo "⏳ Step 4: 新インスタンスの起動待機..."
while true; do
  IN_SERVICE_COUNT=$(aws autoscaling describe-auto-scaling-groups \
    --auto-scaling-group-names ${ASG_NAME} \
    --query "length(AutoScalingGroups[0].Instances[?LifecycleState=='InService'])" \
    --output text)
  
  echo "  現在InService: ${IN_SERVICE_COUNT}/${NEW_CAPACITY}"
  
  if [ ${IN_SERVICE_COUNT} -eq ${NEW_CAPACITY} ]; then
    break
  fi
  
  sleep 30
done

echo "✅ 全インスタンスがInServiceになりました"

# Step 5: 少し待機(安全のため)
echo "⏱️  Step 5: 安定性確認のため2分待機..."
sleep 120

# Step 6: Desired Capacityを元に戻す
echo "📉 Step 6: Capacityを${CURRENT_CAPACITY}に戻す..."
aws autoscaling set-desired-capacity \
  --auto-scaling-group-name ${ASG_NAME} \
  --desired-capacity ${CURRENT_CAPACITY}

# Step 7: 旧インスタンス削除完了待機
echo "⏳ Step 7: 旧インスタンス削除待機..."
while true; do
  CURRENT_COUNT=$(aws autoscaling describe-auto-scaling-groups \
    --auto-scaling-group-names ${ASG_NAME} \
    --query "length(AutoScalingGroups[0].Instances)" \
    --output text)
  
  echo "  現在のインスタンス数: ${CURRENT_COUNT}"
  
  if [ ${CURRENT_COUNT} -eq ${CURRENT_CAPACITY} ]; then
    break
  fi
  
  sleep 30
done

echo "🎉 完了!全インスタンスが新AMIに更新されました"

# Step 8: 最終確認
echo "📊 最終状態:"
aws autoscaling describe-auto-scaling-groups \
  --auto-scaling-group-names ${ASG_NAME} \
  --query "AutoScalingGroups[0].Instances[*].[InstanceId,LaunchConfigurationName,HealthStatus]" \
  --output table
💡 スクリプト使用方法
実行手順:

1. AWS CLIがインストール済みであること
2. 適切なIAM権限があること
3. 変数(ASG_NAME, NEW_AMI)を環境に合わせて変更
4. テスト環境で動作確認
5. 本番環境で実行

⏱️ 実行時間:
• 10インスタンスの場合: 約15-20分
• 20インスタンスの場合: 約20-30分
• 50インスタンスの場合: 約30-45分

🎯 自動化のヒント:
• Jenkins / GitHub Actions / GitLab CIで実行
• 定期的なOSパッチ適用に使用
• Slack通知を追加してチーム共有

🎓 まとめ

✈️ 飛行機の乗客移動 = OSアップデート

新しい飛行機を用意して、乗客を徐々に移動させる🛫
これが ダウンタイムゼロ の秘訣!

7つのステップ で完璧に実現できます✨

🖼️
新AMI
作成
⚙️
起動設定
更新
📏
終了
ポリシー
📈
2倍に
拡張
ヘルスチェック
待機
📉
元のサイズに
戻す
🔒
セキュリティ
強化

🎯 この手法の最大のメリット:

ダウンタイム: 完全にゼロ
リスク: 最小限 (問題あれば即ロールバック)
ユーザー影響: なし (気づかれない)
自動化: 容易 (スクリプト化可能)

⚠️ 一時的にコスト2倍(15-30分)
でも 本番環境では絶対これ!

💡 覚えておくべき最重要ポイント:

OldestLaunchConfiguration
この終了ポリシーが全てのカギ🔑

これを設定するだけで、
Auto Scalingが賢く古いインスタンスだけを削除してくれます!

安全・確実・ダウンタイムゼロ!🚀✨

Created by SSuzuki1063

AWS SAP Learning Resources