特定のEBSボリュームをgp2からgp3へ一括変換するスクリプトを作ってみた

特定のEBSボリュームをgp2からgp3へ一括変換するスクリプトを作ってみた

EBSボリュームのgp2からgp3への変換は、コスト最適化の重要な施策の一つです。今回は、変換前のスナップショット取得やロールバック対応も考慮した、安全な一括変換スクリプトをご紹介します。
Clock Icon2025.02.26

こんにちは!クラウド事業本部のおつまみです。

今回あるアカウントにて、大量のEBSボリュームに対して、gp2からgp3への変更する必要がありました。
大量のボリュームを手動で変換するのは手間がかかります。
そこで一括変換できるスクリプトを作成しました。

今回はそのスクリプトをご紹介したいと思います!

前提条件

スクリプトを実行する前に、gp2からgp3への変換が適切かどうか検討する必要があります。

基本的にgp3はgp2の上位後継タイプとして位置づけられており、同等の性能を確保する場合、コスト面でgp3の方が有利です。また、変換時に再起動は不要です。
一方変換時には、以下の点に注意が必要です。

  • 旧世代のインスタンスタイプを使用している場合は、変換を避けることを推奨
  • レイテンシーについては、gp2の方が低い傾向にあるため、シングルスレッドの処理が重要な場合はgp2の方が適している可能性あり

変換を検討される際は、以下の記事も参考にしてください。

実装したスクリプト

作成したスクリプトはこちらです。トグルを開くと内容を確認できます。

convert_ebs.sh
#!/bin/bash

# 入力ファイルの確認
if [ -z "$1" ]; then
    echo "エラー: ボリュームIDを含む入力ファイルを指定してください"
    echo "使用方法: $0 <入力ファイル>"
    exit 1
fi

INPUT_FILE=$1
LOG_DIR="gp3_conversion_logs_$(date +%Y%m%d_%H%M%S)"
CONVERSION_STATUS_FILE="${LOG_DIR}/conversion_status.txt"
SNAPSHOT_STATUS_FILE="${LOG_DIR}/snapshot_status.txt"
SUMMARY_FILE="${LOG_DIR}/summary.txt"

# ログディレクトリの作成
mkdir -p "$LOG_DIR"
echo "ログディレクトリを作成しました: $LOG_DIR"

# ファイルの存在確認
if [ ! -f "$INPUT_FILE" ]; then
    echo "エラー: 入力ファイル $INPUT_FILE が存在しません"
    exit 1
fi

# スナップショット作成の選択
read -p "変換前にスナップショットを作成しますか? (y/n): " create_snapshot
case $create_snapshot in
    [Yy]* )
        snapshot_enabled=true
        echo "スナップショットを作成します"
        ;;
    [Nn]* )
        snapshot_enabled=false
        echo "スナップショットを作成せずに処理を続行します"
        ;;
    * )
        echo "エラー: y または n を入力してください"
        exit 1
        ;;
esac

# スナップショット作成開始関数
start_snapshot_creation() {
    local volume_id=$1

    # ボリュームの名前を取得(存在する場合)
    volume_name=$(aws ec2 describe-volumes \
        --volume-ids "$volume_id" \
        --query 'Volumes[0].Tags[?Key==`Name`].Value' \
        --output text)

    # 日本時間の日時を取得
    jst_date=$(TZ=Asia/Tokyo date '+%Y%m%d-%H%M%S')
    jst_datetime=$(TZ=Asia/Tokyo date '+%Y-%m-%d %H:%M:%S')

    # スナップショットの名前を設定
    if [ -n "$volume_name" ] && [ "$volume_name" != "None" ]; then
        snapshot_name="Backup-${volume_name}-gp2-to-gp3-${jst_date}"
    else
        snapshot_name="Backup-${volume_id}-gp2-to-gp3-${jst_date}"
    fi

    echo "ボリューム $volume_id のスナップショットを作成開始..."
    snapshot_id=$(aws ec2 create-snapshot \
        --volume-id "$volume_id" \
        --description "gp2 to gp3 conversion backup - ${jst_datetime} JST" \
        --tag-specifications "ResourceType=snapshot,Tags=[{Key=Name,Value=\"$snapshot_name\"},{Key=Purpose,Value=gp2-gp3-conversion-backup}]" \
        --query 'SnapshotId' \
        --output text)

    if [ $? -ne 0 ]; then
        echo "スナップショットの作成開始に失敗しました: $volume_id"
        echo "$volume_id,ERROR,スナップショット作成開始失敗,-" >> "$SNAPSHOT_STATUS_FILE"
        return 1
    fi

    echo "スナップショット $snapshot_id を作成中... (Name: $snapshot_name)"
    echo "$volume_id,$snapshot_id,PENDING,$snapshot_name" >> "$SNAPSHOT_STATUS_FILE"

    return 0
}

# スナップショット状態確認関数
check_snapshot_status() {
    local pending_snapshots=0

    # 一時ファイルを作成
    local temp_file="${LOG_DIR}/snapshot_temp.txt"
    cp "$SNAPSHOT_STATUS_FILE" "$temp_file"

    while IFS=, read -r volume_id snapshot_id status snapshot_name || [ -n "$volume_id" ]; do
        # ヘッダー行またはエラー行はスキップ
        [[ "$status" == "STATUS" || "$status" == "ERROR" || "$volume_id" == "VolumeID" ]] && continue

        if [ "$status" == "PENDING" ]; then
            ((pending_snapshots++))

            snapshot_status=$(aws ec2 describe-snapshots \
                --snapshot-ids "$snapshot_id" \
                --query 'Snapshots[0].State' \
                --output text 2>/dev/null)

            if [ "$snapshot_status" == "completed" ]; then
                echo "スナップショット $snapshot_id ($volume_id): 完了"
                # ステータスファイルを更新
                sed -i "s/^$volume_id,$snapshot_id,PENDING,/$volume_id,$snapshot_id,COMPLETED,/" "$temp_file"

                # 変換を開始
                start_volume_conversion "$volume_id"
            elif [ "$snapshot_status" == "error" ]; then
                echo "スナップショット $snapshot_id ($volume_id): 作成失敗"
                sed -i "s/^$volume_id,$snapshot_id,PENDING,/$volume_id,$snapshot_id,FAILED,/" "$temp_file"
                echo "$volume_id,ERROR,スナップショット作成失敗" >> "$CONVERSION_STATUS_FILE"
            else
                echo "スナップショット $snapshot_id ($volume_id): 作成中... 状態: $snapshot_status"
                # ステータスは変更しない
            fi
        fi
    done < "$SNAPSHOT_STATUS_FILE"

    # 更新されたファイルを元のファイルに戻す
    mv "$temp_file" "$SNAPSHOT_STATUS_FILE"

    return $pending_snapshots
}

# ボリュームの変換開始関数
start_volume_conversion() {
    local volume_id=$1

    # 既に変換が開始されているか確認
    if grep -q "^$volume_id," "$CONVERSION_STATUS_FILE"; then
        # 既に記録がある場合はスキップ
        return 0
    fi

    # ボリュームの現在の状態を確認
    echo "ボリューム $volume_id を gp2 から gp3 に変換開始..."
    aws ec2 modify-volume \
        --volume-id "$volume_id" \
        --volume-type gp3 > /dev/null

    if [ $? -eq 0 ]; then
        echo "ボリューム $volume_id の変換を開始しました"
        echo "$volume_id,STARTED,$(date '+%Y-%m-%d %H:%M:%S')" >> "$CONVERSION_STATUS_FILE"
        return 0
    else
        echo "ボリューム $volume_id の変換開始に失敗しました"
        echo "$volume_id,ERROR,変換開始失敗" >> "$CONVERSION_STATUS_FILE"
        return 1
    fi
}

# ボリュームの確認関数
check_volume() {
    local volume_id=$1

    # ボリュームの存在確認とタイプチェック
    volume_info=$(aws ec2 describe-volumes \
        --volume-ids "$volume_id" \
        --query 'Volumes[0].[VolumeType,State]' \
        --output json 2>/dev/null)

    if [ $? -ne 0 ]; then
        echo "ボリューム $volume_id が存在しないかアクセスできません"
        echo "$volume_id,ERROR,存在しないかアクセスできません" >> "$CONVERSION_STATUS_FILE"
        return 1
    fi

    volume_type=$(echo "$volume_info" | jq -r '.[0]')
    volume_state=$(echo "$volume_info" | jq -r '.[1]')

    if [ "$volume_state" != "available" ] && [ "$volume_state" != "in-use" ]; then
        echo "ボリューム $volume_id は利用可能な状態ではありません(現在の状態: $volume_state)。スキップします..."
        echo "$volume_id,SKIPPED,状態が $volume_state です" >> "$CONVERSION_STATUS_FILE"
        return 2
    fi

    if [ "$volume_type" != "gp2" ]; then
        echo "ボリューム $volume_id は gp2 ではありません(現在のタイプ: $volume_type)。スキップします..."
        echo "$volume_id,SKIPPED,既に $volume_type タイプです" >> "$CONVERSION_STATUS_FILE"
        return 2
    fi

    return 0
}

# 変換状態の確認関数
check_conversion_status() {
    local volumes_to_check=()

    # 変換開始したボリュームのリストを作成
    while IFS=, read -r volume_id status timestamp || [ -n "$volume_id" ]; do
        # ヘッダー行はスキップ
        [[ "$status" == "Status" || "$volume_id" == "VolumeID" ]] && continue

        if [ "$status" = "STARTED" ]; then
            volumes_to_check+=("$volume_id")
        fi
    done < "$CONVERSION_STATUS_FILE"

    if [ ${#volumes_to_check[@]} -eq 0 ]; then
        return 0
    fi

    echo "変換状態を確認中... (${#volumes_to_check[@]} ボリューム)"

    # 一時ファイルを作成
    local temp_file="${LOG_DIR}/conversion_temp.txt"
    cp "$CONVERSION_STATUS_FILE" "$temp_file"

    for volume_id in "${volumes_to_check[@]}"; do
        status=$(aws ec2 describe-volumes-modifications \
            --volume-ids "$volume_id" \
            --query 'VolumesModifications[0].ModificationState' \
            --output text 2>/dev/null)

        if [ "$status" = "completed" ]; then
            # 実際のボリュームタイプを確認
            current_type=$(aws ec2 describe-volumes \
                --volume-ids "$volume_id" \
                --query 'Volumes[0].VolumeType' \
                --output text)

            if [ "$current_type" = "gp3" ]; then
                echo "ボリューム $volume_id: gp3への変換が完了しました"
                # ステータスファイルを更新
                sed -i "s/^$volume_id,STARTED,.*/$volume_id,COMPLETED,$(date '+%Y-%m-%d %H:%M:%S')/" "$temp_file"
            else
                echo "ボリューム $volume_id: 変換に失敗しました(タイプが $current_type のまま)"
                sed -i "s/^$volume_id,STARTED,.*/$volume_id,FAILED,タイプが $current_type のまま/" "$temp_file"
            fi
        elif [ "$status" = "failed" ]; then
            echo "ボリューム $volume_id: 変換に失敗しました"
            sed -i "s/^$volume_id,STARTED,.*/$volume_id,FAILED,変換失敗/" "$temp_file"
        else
            echo "ボリューム $volume_id: 変換中... 状態: $status"
            # ステータスは変更しない
        fi
    done

    # 更新されたファイルを元のファイルに戻す
    mv "$temp_file" "$CONVERSION_STATUS_FILE"
}

# 結果サマリーの生成関数
generate_summary() {
    local success_count=0
    local fail_count=0
    local skip_count=0
    local pending_count=0
    local snapshot_pending=0
    local snapshot_completed=0
    local snapshot_failed=0

    # 変換状態のカウント
    while IFS=, read -r volume_id status reason || [ -n "$volume_id" ]; do
        # ヘッダー行はスキップ
        [[ "$status" == "Status" || "$volume_id" == "VolumeID" ]] && continue

        case $status in
            COMPLETED)
                ((success_count++))
                ;;
            FAILED|ERROR)
                ((fail_count++))
                ;;
            SKIPPED)
                ((skip_count++))
                ;;
            STARTED)
                ((pending_count++))
                ;;
        esac
    done < "$CONVERSION_STATUS_FILE"

    # スナップショット状態のカウント
    if [ "$snapshot_enabled" = true ]; then
        while IFS=, read -r volume_id snapshot_id status name || [ -n "$volume_id" ]; do
            # ヘッダー行はスキップ
            [[ "$status" == "STATUS" || "$volume_id" == "VolumeID" ]] && continue

            case $status in
                COMPLETED)
                    ((snapshot_completed++))
                    ;;
                FAILED|ERROR)
                    ((snapshot_failed++))
                    ;;
                PENDING)
                    ((snapshot_pending++))
                    ;;
            esac
        done < "$SNAPSHOT_STATUS_FILE"
    fi

    echo "変換結果サマリー:" > "$SUMMARY_FILE"
    echo "変換成功: $success_count" >> "$SUMMARY_FILE"
    echo "変換失敗: $fail_count" >> "$SUMMARY_FILE"
    echo "スキップ: $skip_count" >> "$SUMMARY_FILE"
    echo "処理中: $pending_count" >> "$SUMMARY_FILE"

    if [ "$snapshot_enabled" = true ]; then
        echo "" >> "$SUMMARY_FILE"
        echo "スナップショット状態:" >> "$SUMMARY_FILE"
        echo "完了: $snapshot_completed" >> "$SUMMARY_FILE"
        echo "作成中: $snapshot_pending" >> "$SUMMARY_FILE"
        echo "失敗: $snapshot_failed" >> "$SUMMARY_FILE"
    fi

    echo
    cat "$SUMMARY_FILE"
}

# メイン処理
echo "EBSボリューム変換プロセスを開始します..."
echo "入力ファイル $INPUT_FILE からボリュームIDを読み込みます"

# 初期化
echo "VolumeID,Status,Details" > "$CONVERSION_STATUS_FILE"
if [ "$snapshot_enabled" = true ]; then
    echo "VolumeID,SnapshotID,STATUS,SnapshotName" > "$SNAPSHOT_STATUS_FILE"
fi

# ファイルの各行を処理して変換を開始
while IFS= read -r volume_id || [ -n "$volume_id" ]; do
    # 空行とコメントをスキップ
    [[ -z "$volume_id" || "$volume_id" =~ ^[[:space:]]*# ]] && continue

    # 先頭と末尾の空白を削除
    volume_id=$(echo "$volume_id" | tr -d '[:space:]')

    # ボリュームの確認
    check_volume "$volume_id"
    check_result=$?

    if [ $check_result -eq 0 ]; then
        if [ "$snapshot_enabled" = true ]; then
            # スナップショット作成を開始
            start_snapshot_creation "$volume_id"
        else
            # 直接変換を開始
            start_volume_conversion "$volume_id"
        fi
    fi
done < "$INPUT_FILE"

echo
echo "すべてのボリュームの処理を開始しました。変換状態を監視します..."

# 変換状態の確認を定期的に実行
while true; do
    # スナップショットの状態確認(有効な場合)
    pending_snapshots=0
    if [ "$snapshot_enabled" = true ]; then
        check_snapshot_status
        pending_snapshots=$?
    fi

    # 変換状態の確認
    check_conversion_status

    # サマリーの生成
    generate_summary

    # 処理中のボリュームとスナップショットがあるか確認
    pending_count=$(grep -c "STARTED" "$CONVERSION_STATUS_FILE")

    if [ "$pending_count" -eq 0 ] && [ "$pending_snapshots" -eq 0 ]; then
        echo "すべての処理が完了しました"
        break
    fi

    echo
    echo "次の確認まで30秒待機します... (Ctrl+C で中断可能、処理は継続されます)"
    sleep 30
done

echo
echo "変換プロセスが完了しました。詳細なログは $LOG_DIR ディレクトリにあります。"
echo "- 変換状態: $CONVERSION_STATUS_FILE"
if [ "$snapshot_enabled" = true ]; then
    echo "- スナップショット情報: $SNAPSHOT_STATUS_FILE"
fi
echo "- サマリー: $SUMMARY_FILE"

スクリプトの説明

外部ファイルで指定したEBSボリュームをgp2からgp3に一括変換するスクリプトです。
主な機能は以下の通りです。

主な機能

  1. 選択的な変換
    • 指定したボリュームのみを並列処理で変換
    • 外部ファイルでボリュームIDを管理
  2. スナップショット管理
    • 変換前のスナップショット並列処理で取得(オプション)
    • ボリューム名もしくはボリュームIDでのスナップショット名付け
  3. 変換状態の監視
    • リアルタイムでの進捗表示(30秒ごと)
    • 変換完了の確実な検知
    • エラー時の適切な通知
  4. 結果管理
    • 変換成功/失敗/スキップの集計
    • 処理結果のサマリー表示

スクリプトの使用手順

1. CloudShellの起動

AWSマネジメントコンソールの右上にあるCloudShellアイコンをクリックして起動します。

コンソールのホーム___コンソールのホーム___ap-northeast-1

2. スクリプトの準備

CloudShellで以下のコマンドを実行し、スクリプトファイルを作成します。作成後、実行権限を付与します。

# スクリプトファイルの作成
cat << 'EOF' > convert_ebs.sh
[スクリプト本体をここにペースト]
EOF

# 実行権限の付与
chmod +x convert_ebs.sh

3. 変換対象ボリュームの準備

変換したいボリュームのIDを記載したテキストファイルを作成します。

# volume_ids.txtの作成
cat << EOF > volume_ids.txt
vol-xxxxxxxxxxxxxxxxx
vol-yyyyyyyyyyyyyyyyy
vol-zzzzzzzzzzzzzzzzz
EOF

# 作成したファイルの確認
cat volume_ids.txt

4. スクリプトの実行

以下のコマンドを実行し、スクリプトを実行します。

./convert_ebs.sh volume_ids.txt

5. 実行時の流れ

まず、変換前にスナップショットを作成するかどうか聞かれます。スナップショットが必要な場合はy、不要な場合はnを入力します。本番環境の場合は念の為、スナップショットを取得していくことを推奨します。(6時間経過後にgp3 → gp2への変更が可能となります。)

変換前にスナップショットを作成しますか? (y/n):

変換処理状況が自動で表示されます。

ログディレクトリを作成しました: gp3_conversion_logs_yyyymmdd_hhmmss
変換前にスナップショットを作成しますか? (y/n): y
スナップショットを作成します
EBSボリューム変換プロセスを開始します...
入力ファイル volume_ids.txt からボリュームIDを読み込みます
ボリューム vol-xxxxxxxxxxxxxxxxx のスナップショットを作成開始...
スナップショット snap-yyyyyyyyyyyyyyy を作成中... (Name: Backup-test-vol-xxxxxxxxxxxxxxxxx-gp2-to-gp3-yyyymmdd-hhmmss)

すべてのボリュームの処理を開始しました。変換状態を監視します...
スナップショット snap-yyyyyyyyyyyyyyy (vol-xxxxxxxxxxxxxxxxx): 完了
ボリューム vol-xxxxxxxxxxxxxxxxx を gp2 から gp3 に変換開始...
ボリューム vol-xxxxxxxxxxxxxxxxx の変換を開始しました
変換状態を確認中... (1 ボリューム)
ボリューム vol-xxxxxxxxxxxxxxxxx: 変換中... 状態: optimizing

変換結果サマリー:
変換成功: 0
変換失敗: 0
スキップ: 0
処理中: 1

スナップショット状態:
完了: 1
作成中: 0
失敗: 0

次の確認まで30秒待機します... (Ctrl+C で中断可能、処理は継続は継続されます)

全ボリュームの変換処理が完了すると、結果サマリーが表示されます。

変換結果サマリー:
変換成功: X
変換失敗: Y
スキップ: Z
処理中: 0

スナップショット状態:
完了:  X
作成中: Y
失敗: Z
すべての処理が完了しました

変換プロセスが完了しました。詳細なログは gp3_conversion_logs_yyyymmdd_hhmmss ディレクトリにあります。
- 変換状態: gp3_conversion_logs_yyyymmdd_hhmmss/conversion_status.txt
- スナップショット情報: gp3_conversion_logs_yyyymmdd_hhmmss/snapshot_status.txt
- サマリー: gp3_conversion_logs_yyyymmdd_hhmmss/summary.txt

「変換成功」は指定したgp2ボリュームがgp3への変換を完了し、ボリュームタイプの確認でgp3となっているケースがカウントされます。
「変換失敗」はボリュームが存在しない場合、APIアクセスエラー、スナップショット作成失敗、変換プロセスの失敗など、正常に完了しなかったケースがカウントされます。
「スキップ」は指定したボリュームがgp2以外の場合(例:gp3、io1、io2など)にカウントされます。

6. 実行結果の確認

変換後、以下のコマンドで結果を確認できます

# 変換したボリュームの状態確認
aws ec2 describe-volumes --volume-ids $(cat volume_ids.txt) --query 'Volumes[*].[VolumeId,VolumeType,State]' --output table

# 作成されたスナップショットの確認(スナップショットを作成した場合)
aws ec2 describe-snapshots --filters "Name=tag:Purpose,Values=gp2-gp3-conversion-backup" --query 'Snapshots[*].[SnapshotId,VolumeId,Tags[?Key==`Name`].Value|[0]]' --output table

スナップショット名は以下どちらかの命名規則で保存されます。

  • ボリュームに有効なNameタグがある場合:Backup-{ボリューム名}-gp2-to-gp3-{日時(JST)}
  • ボリュームにNameタグがない場合:Backup-{ボリュームID}-gp2-to-gp3-{日時(JST)}

7. スナップショットの削除

一定期間経過し、gp3に変換したことによる不具合が出ていなければ、オプションで取得したスナップショットは削除します。

# スナップショットの削除
for snapshot_id in $(aws ec2 describe-snapshots --filters "Name=tag:Purpose,Values=gp2-gp3-conversion-backup" --query 'Snapshots[*].SnapshotId' --output text); do
    echo "Deleting snapshot: $snapshot_id"
    aws ec2 delete-snapshot --snapshot-id $snapshot_id
done

万一、gp3変換後に不具合が生じた場合は以下を実施してください。

やってみた

作成したスクリプトで検証します。

1.テスト用ボリュームの作成

CloudShellで以下コマンドを実行し、テスト用ボリュームを作成します。

# 変換対象のgp2ボリューム作成(Nameタグ付き)
aws ec2 create-volume \
    --volume-type gp2 \
    --size 10 \
    --availability-zone ap-northeast-1a \
    --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=test-vol-1},{Key=Convert,Value=true}]'

# 変換対象のgp2ボリューム作成(Nameタグなし)
aws ec2 create-volume \
    --volume-type gp2 \
    --size 10 \
    --availability-zone ap-northeast-1a \
    --tag-specifications 'ResourceType=volume,Tags=[{Key=Convert,Value=true}]'

# 変換しないgp2ボリューム作成(Nameタグ付き)
aws ec2 create-volume \
    --volume-type gp2 \
    --size 10 \
    --availability-zone ap-northeast-1a \
    --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=test-vol-no-convert},{Key=Convert,Value=false}]'

# スキップ確認用のgp3ボリューム作成(Nameタグ付き)
aws ec2 create-volume \
    --volume-type gp3 \
    --size 10 \
    --availability-zone ap-northeast-1a \
    --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=test-vol-gp3},{Key=Convert,Value=true}]'

4つのEBSボリュームが作成されました。test-vol-no-convert以外のボリュームを指定して、gp2→gp3変換スクリプトを実行します。

ボリューム___EC2___ap-northeast-1

2.スクリプト・変換対象ボリュームの準備

使用手順2,3に従ってスクリプトファイルおよびボリューム一覧を準備します。

3.スクリプトの実行

使用手順4,5に従ってスクリプトを実行します。
今回は3ボリューム(うち1ボリュームはスキップ)だったため、2~3分で処理が完了しました。

実行結果
[cloudshell-user@ip-xx-xx-xx-xx ~]$ ./convert_ebs.sh volume_ids.txt
ログディレクトリを作成しました: gp3_conversion_logs_yymmdd_hhmmss
変換前にスナップショットを作成しますか? (y/n): y
スナップショットを作成します
EBSボリューム変換プロセスを開始します...
入力ファイル volume_ids.txt からボリュームIDを読み込みます
ボリューム vol-004373c1f59e29646 のスナップショットを作成開始...
スナップショット snap-041788273d8cbe3b1 を作成中... (Name: Backup-vol-004373c1f59e29646-gp2-to-gp3-20250305-160726)
ボリューム vol-097ec3db03ae36526 のスナップショットを作成開始...
スナップショット snap-03cf1d0b1d5165fad を作成中... (Name: Backup-vol-097ec3db03ae36526-gp2-to-gp3-20250305-160729)
ボリューム vol-010694bdbe52f7416 は gp2 ではありません(現在のタイプ: gp3)。スキップします...

すべてのボリュームの処理を開始しました。変換状態を監視します...
スナップショット snap-041788273d8cbe3b1 (vol-004373c1f59e29646): 作成中... 状態: pending
スナップショット snap-03cf1d0b1d5165fad (vol-097ec3db03ae36526): 作成中... 状態: pending

変換結果サマリー:
変換成功: 0
変換失敗: 0
スキップ: 1
処理中: 0

スナップショット状態:
完了: 0
作成中: 2
失敗: 0

次の確認まで30秒待機します... (Ctrl+C で中断可能、処理は継続されます)
スナップショット snap-041788273d8cbe3b1 (vol-004373c1f59e29646): 完了
ボリューム vol-004373c1f59e29646 を gp2 から gp3 に変換開始...
ボリューム vol-004373c1f59e29646 の変換を開始しました
スナップショット snap-03cf1d0b1d5165fad (vol-097ec3db03ae36526): 作成中... 状態: pending
変換状態を確認中... (1 ボリューム)
ボリューム vol-004373c1f59e29646: 変換中... 状態: optimizing

変換結果サマリー:
変換成功: 0
変換失敗: 0
スキップ: 1
処理中: 1

スナップショット状態:
完了: 1
作成中: 1
失敗: 0

次の確認まで30秒待機します... (Ctrl+C で中断可能、処理は継続されます)
スナップショット snap-03cf1d0b1d5165fad (vol-097ec3db03ae36526): 完了
ボリューム vol-097ec3db03ae36526 を gp2 から gp3 に変換開始...
ボリューム vol-097ec3db03ae36526 の変換を開始しました
変換状態を確認中... (2 ボリューム)
ボリューム vol-004373c1f59e29646: gp3への変換が完了しました
ボリューム vol-097ec3db03ae36526: gp3への変換が完了しました

変換結果サマリー:
変換成功: 2
変換失敗: 0
スキップ: 1
処理中: 0

スナップショット状態:
完了: 2
作成中: 0
失敗: 0

次の確認まで30秒待機します... (Ctrl+C で中断可能、処理は継続されます)

変換結果サマリー:
変換成功: 2
変換失敗: 0
スキップ: 1
処理中: 0

スナップショット状態:
完了: 2
作成中: 0
失敗: 0
すべての処理が完了しました

変換プロセスが完了しました。詳細なログは gp3_conversion_logs_yymmdd_hhmmss ディレクトリにあります。
- 変換状態: gp3_conversion_logs_yymmdd_hhmmss/conversion_status.txt
- スナップショット情報: gp3_conversion_logs_yymmdd_hhmmss/snapshot_status.txt
- サマリー: gp3_conversion_logs_yymmdd_hhmmss/summary.txt

4.実行結果の確認

使用手順6に従って実行結果を確認します。

[cloudshell-user@ip-xx-xx-xx-xx tmp]$ # 変換したボリュームの状態確認
[cloudshell-user@ip-xx-xx-xx-xx tmp]$ aws ec2 describe-volumes --volume-ids $(cat volume_ids.txt) --query 'Volumes[*].[VolumeId,VolumeType,State]' --output table
-----------------------------------------------
|               DescribeVolumes               |
+------------------------+------+-------------+
|  vol-004373c1f59e29646 |  gp3 |  available  |
|  vol-0fa73d9b501d6eb02 |  gp3 |  available  |
|  vol-097ec3db03ae36526 |  gp3 |  available  |
+------------------------+------+-------------+
[cloudshell-user@ip-xx-xx-xx-xx tmp]$ 
[cloudshell-user@ip-xx-xx-xx-xx tmp]$ # 作成されたスナップショットの確認(スナップショットを作成した場合)
[cloudshell-user@ip-xx-xx-xx-xx tmp]$ aws ec2 describe-snapshots --filters "Name=tag:Purpose,Values=gp2-gp3-conversion-backup" --query 'Snapshots[*].[SnapshotId,VolumeId,Tags[?Key==`Name`].Value|[0]]' --output table
----------------------------------------------------------------------------------------------------------------
|                                               DescribeSnapshots                                              |
+------------------------+------------------------+------------------------------------------------------------+
|  snap-041788273d8cbe3b1|  vol-004373c1f59e29646 |  Backup-vol-004373c1f59e29646-gp2-to-gp3-20250226-115247   |
|  snap-03cf1d0b1d5165fad|  vol-097ec3db03ae36526 |  Backup-test-vol-1-gp2-to-gp3-20250226-115351              |
+------------------------+------------------------+------------------------------------------------------------+
[cloudshell-user@ip-xx-xx-xx-xx tmp]$ 

今回指定したボリュームだけgp3に変更されていることが確認できました。
またスナップショットも問題なく作成されています。

なお、結果はコンソール上でも確認できます。

  • ボリューム
    Cursor_と_ボリューム___EC2___ap-northeast-1

  • スナップショット
    Cursor_と_スナップショット___EC2___ap-northeast-1

最後に

今回は、特定のEBSボリュームをgp2からgp3へ一括変換するスクリプトをご紹介しました!

コスト最適化は重要ですが、性能への影響も考慮する必要があります。このスクリプトを使用することで、スナップショットを取得しながら安全に変換作業を進められます。みなさんのコスト最適化の一助となれば幸いです。

以上、おつまみ(@AWS11077)でした!

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.