はじめに
EC2 AMIを取得するスクリプトを検証してみました。
AMIの取得時にEC2を再起動しない且つディスクは削除終了にチェックを入れることです。
chatGPTにAMI取得スクリプトを教えていただき動作検証した結果を記事にまとめています。
前提条件
2つのEC2のAMIを取得する
※EC2は作成後、削除するためEC2のインスタンスIDは隠しておりません。
EC2の起動時刻がAMI取得後に変わらないことを確認する
AMI取得スクリプト
#!/bin/bash
# jqがインストールされているか確認
if ! command -v jq &> /dev/null; then
echo "jqがインストールされていません。インストールしてください。"
exit 1
fi
# 複数のインスタンスIDを指定
INSTANCE_IDS=("i-092d7b81160094de7" "i-00507569a3930cef8")
# 現在の日付を取得 (例: 20241110)
DATE=$(date +"%Y%m%d")
for INSTANCE_ID in "${INSTANCE_IDS[@]}"; do
# インスタンスのNameタグを取得
INSTANCE_NAME=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query "Reservations[0].Instances[0].Tags[?Key=='Name'].Value" \
--output text)
# インスタンス名が取得できなければエラー
if [ -z "$INSTANCE_NAME" ]; then
echo "インスタンス $INSTANCE_ID のNameタグが見つかりません。スキップします。"
continue
fi
# AMI名を作成 (例: インスタンス名-YYYYMMDD-test)
AMI_NAME="${INSTANCE_NAME}-${DATE}-test"
# インスタンスに紐づくブロックデバイスマッピングを取得し、DeleteOnTerminationを設定
BLOCK_DEVICE_MAPPINGS=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query "Reservations[0].Instances[0].BlockDeviceMappings" \
--output json)
# ブロックデバイスマッピングにDeleteOnTerminationを設定
BLOCK_DEVICE_MAPPINGS_JSON=$(echo "$BLOCK_DEVICE_MAPPINGS" | jq -c '[.[] | {DeviceName: .DeviceName, Ebs: {DeleteOnTermination: true}}]')
# AMIを作成 (再起動なし) + Nameタグを付与
AMI_ID=$(aws ec2 create-image \
--instance-id "$INSTANCE_ID" \
--name "$AMI_NAME" \
--no-reboot \
--block-device-mappings "$BLOCK_DEVICE_MAPPINGS_JSON" \
--tag-specifications "ResourceType=image,Tags=[{Key=Name,Value=$AMI_NAME}]" \
--query "ImageId" \
--output text)
if [ -z "$AMI_ID" ]; then
echo "AMIの作成に失敗しました。インスタンスID: $INSTANCE_ID"
continue
else
echo "Created AMI for instance $INSTANCE_ID with AMI ID: $AMI_ID and name: $AMI_NAME"
fi
# AMIに関連するスナップショットを取得し、Nameタグを付与
SNAPSHOT_IDS=$(aws ec2 describe-images \
--image-ids "$AMI_ID" \
--query "Images[0].BlockDeviceMappings[*].Ebs.SnapshotId" \
--output text)
for SNAPSHOT_ID in $SNAPSHOT_IDS; do
aws ec2 create-tags \
--resources "$SNAPSHOT_ID" \
--tags Key=Name,Value="$AMI_NAME"
if [ $? -eq 0 ]; then
echo "Added Name tag to snapshot $SNAPSHOT_ID with Name: $AMI_NAME"
else
echo "Failed to add Name tag to snapshot $SNAPSHOT_ID"
fi
done
done
対応手順
sakuraエディタを開き、本記事に記載した上記のスクリプト貼り付けました。
UTF8を文字コードセットを指定して、改行コードLF(UNIX)を指定しました。
※上記の設定をしないとcloudshellでスクリプトを実行しようとしたら文字コードのエラーで怒られます。
cloudshellを起動しました。
[cloudshell-user@ip-10-130-46-88 ~]$ sh AMIget.sh
Created AMI for instance i-092d7b81160094de7 with AMI ID: ami-0a06d31f7f12dc21d and name: test-20241110-test
Added Name tag to snapshot snap-0e0aaeb59ee2485fa with Name: test-20241110-test
Added Name tag to snapshot snap-0ba6f95053ecc7845 with Name: test-20241110-test
Created AMI for instance i-00507569a3930cef8 with AMI ID: ami-07433c3736e775319 and name: test2-20241110-test
Added Name tag to snapshot snap-0fa3d5c0f38a92cc5 with Name: test2-20241110-test
AMI取得した際にEC2は再起動されていないことを確認した。
本記事のスクリプトで取得したAMIからEC2が問題なく起動できるか確認した
取得したAMIからEC2を問題なく起動できてSSH接続までできました。
取得したAMIから復元したEC2からAMIが問題なく取得できました。
[cloudshell-user@ip-10-130-46-88 ~]$ sh AMIget.sh
Created AMI for instance i-0d2fdc2e6a87e20ca with AMI ID: ami-0fe8859f8e5922229 and name: test3-20241110-test
Added Name tag to snapshot snap-031bc35b07d4addaf with Name: test3-20241110-test
Added Name tag to snapshot snap-0f546428647631583 with Name: test3-20241110-test
元のEC2とスクリプトで取得したAMIから起動したEC2とディスク領域も同じのため、問題なし
まとめ
AMI取得はスクリプトで取得した方が自動化出来て効率が良いです。
本記事のスクリプトで指定したEC2インスタンスIDからAMIを取得できるため、ぜひ参考にしてください