2026年10月1日
2026年10月1日
AWS EC2でカスタムAMIを作成する方法|作成前の片付け・CLIでの作成・起動確認と世代管理
カスタム AMI は、設定済みの EC2 インスタンスを「ひな形」として保存し、同じ構成のサーバーを何台でも起動できるようにする仕組みです。作成自体はコマンド1つで終わりますが、作成前に何を片付けるか、作成後にどう確認し、古い AMI をどう整理するかで使い勝手が大きく変わります。この記事では、EBS ボリュームを使う一般的なインスタンスを前提に、その一連の手順を説明します。
カスタム AMI が向いている場面
AMI を作っておくと、次のような場面で手間と時間を減らせます。
- Auto Scaling で台数を増やすとき、起動直後から必要なソフトウェアが揃っている状態にしたい
- OS やミドルウェアの設定を固めた「基準イメージ」を作り、検証環境と本番環境で同じものを使いたい
- 大きな変更の前に、サーバー全体を戻せる状態を残しておきたい
一方で、WordPress の投稿データやアップロードファイルのように日々変わるデータは、AMI に入れても作成した時点で古くなります。データベースは RDS などの別サービス、メディアは S3 や EFS に分けておき、AMI には「アプリケーションを動かすための環境」だけを入れる構成にすると、AMI を作り直す頻度を抑えられます。
作成前にインスタンスを整える
AMI には、作成時点のディスクの中身がそのまま入ります。そこから起動したすべてのインスタンスに引き継がれるため、次の点を先に片付けます。
秘密情報を入れない。 データベースのパスワードや API キーをファイルに書いたまま AMI にすると、AMI を共有した相手や、AMI から起動できる人すべてが読めるようになります。wp-config.php の接続情報などは、起動時にユーザーデータや AWS Systems Manager Parameter Store、Secrets Manager から取得する形にしておくと安全です。
個人の鍵と履歴を消す。 作業者が追加した SSH の公開鍵(~/.ssh/authorized_keys の追記分)、シェルの履歴、作業中に置いた一時ファイルを削除します。起動時に指定するキーペアは cloud-init などが設定するため、作業者個人の鍵を残す必要はありません。
ログと一時データを空にする。 古いログが残っていると、新しいインスタンスで障害調査をするときに紛らわしくなります。cloud-init を使う OS では、次のコマンドで実行記録を消しておくと、新しいインスタンスで初回起動の処理が改めて行われます。
sudo cloud-init clean --logs
history -c
cloud-init clean の挙動やオプションは版によって異なることがあるため、使う OS のドキュメントで確認してください。Windows の場合は EC2Launch などの仕組みで同様の準備を行います。
インストールするパッケージは、OS の版に合わせます。Amazon Linux 2023 であれば dnf を使い、次のような形になります(パッケージ名は版によって変わるため、dnf search で確認してから入れてください)。
sudo dnf install -y httpd php php-fpm php-mysqlnd
sudo systemctl enable httpd php-fpm
systemctl enable で自動起動を有効にしておかないと、AMI から起動したインスタンスでサービスが止まったままになります。作成前に一度再起動し、サービスが自動で立ち上がることを確かめておくと安心です。
AMI を作成する
コンソールでは、インスタンスを選んで操作メニューの「イメージとテンプレート」から「イメージを作成」を選びます(メニューの表記は画面の更新で変わることがあります。2026年10月現在)。CLI では次のように作成します。
aws ec2 create-image \
--instance-id i-0123456789abcdef0 \
--name "wp-base-2026-10-28" \
--description "Amazon Linux 2023 + httpd + php-fpm" \
--tag-specifications \
'ResourceType=image,Tags=[{Key=Role,Value=wp-base}]' \
'ResourceType=snapshot,Tags=[{Key=Role,Value=wp-base}]'
名前には日付や版を入れておくと、後で世代を見分けやすくなります。タグを AMI とスナップショットの両方に付けておくのは、後述の削除作業でスナップショットを探しやすくするためです。
既定ではインスタンスが一度再起動されます。これはディスクへの書き込みを止めて、整合性の取れた状態で保存するためです。--no-reboot を付けると再起動せずに作成できますが、書き込み中のデータが中途半端な状態で保存されるおそれがあります。本番サーバーを止められない場合は、メンテナンス時間を取るか、同じ構成の作業用インスタンスから作成する方法を検討してください。
作成には数分から数十分かかります。完了を待つには次のコマンドが便利です。
aws ec2 wait image-available --image-ids ami-0123456789abcdef0
aws ec2 describe-images --image-ids ami-0123456789abcdef0 \
--query 'Images[0].{State:State,Name:Name,Created:CreationDate}'
wait には待ち時間の上限があり、大きなボリュームでは完了前にエラーで終わることがあります。その場合は作成が失敗したわけではないので、もう一度実行するか describe-images で状態を確認します。State が available になれば利用できます。failed の場合は、describe-images の結果に含まれる理由を確認します。
AMI から起動して確認する
作った AMI は、実際に起動して確かめるまで「使えるか分からないもの」です。検証用のサブネットで1台起動し、次の点を見ます。
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type t3.micro \
--key-name my-keypair \
--subnet-id subnet-0123456789abcdef0 \
--security-group-ids sg-0123456789abcdef0 \
--metadata-options HttpTokens=required
- SSH または Session Manager で接続できるか
- Web サーバーや PHP-FPM が自動で起動しているか
- 起動時に取得するはずの設定(データベース接続先など)が正しく入っているか
- 古いホスト名や IP アドレスが設定ファイルに残っていないか
HttpTokens=required は、インスタンスメタデータへのアクセスに IMDSv2 を必須にする指定です。AMI 側で既定値を設定することもできますが、起動時に明示しておくと設定漏れを防げます。
問題がなければ、Auto Scaling で使っている起動テンプレートに新しい AMI を設定した版を追加します。
aws ec2 create-launch-template-version \
--launch-template-id lt-0123456789abcdef0 \
--source-version 1 \
--launch-template-data '{"ImageId":"ami-0123456789abcdef0"}'
別リージョンへのコピーと共有
災害対策で別リージョンでも起動できるようにするには、AMI をコピーします。
aws ec2 copy-image \
--source-region ap-northeast-1 \
--source-image-id ami-0123456789abcdef0 \
--region ap-northeast-3 \
--name "wp-base-2026-10-28"
別の AWS アカウントと共有するには、起動許可にアカウント ID を追加します。暗号化された AMI を共有する場合、AWS 管理のデフォルトキーで暗号化したものは共有できず、カスタマー管理の KMS キーと、そのキーの利用許可が必要です。AMI を誤って一般公開しないよう、パブリック共有をブロックするアカウント設定も確認しておきます。
古い AMI を整理する
AMI を作るたびに EBS スナップショットが増え、その保存容量に応じて料金がかかります。使わなくなった AMI は登録を解除しますが、解除しただけではスナップショットが残る点に注意してください。
aws ec2 describe-images --image-ids ami-0aaaaaaaaaaaaaaaa \
--query 'Images[0].BlockDeviceMappings[].Ebs.SnapshotId'
aws ec2 deregister-image --image-id ami-0aaaaaaaaaaaaaaaa
aws ec2 delete-snapshot --snapshot-id snap-0aaaaaaaaaaaaaaaa
スナップショット ID は、登録解除の前に控えておきます。起動テンプレートや Auto Scaling グループがまだその AMI を参照していないかも、削除前に確認します。直近の数世代は残しておき、問題があったときに前の AMI へ戻せるようにしておくと安心です。
手作業での作成に慣れたら、EC2 Image Builder や Packer でビルド手順をコード化したり、Amazon Data Lifecycle Manager で定期作成と世代管理を自動化したりする方法もあります。
まとめ
- AMI には「アプリケーションを動かす環境」だけを入れ、データベースやメディアは別サービスに分ける
- 作成前に秘密情報・個人の SSH 鍵・履歴・ログを片付け、サービスの自動起動を確かめる
create-imageは既定で再起動して整合性を保つ。--no-rebootは整合性のリスクを理解して使う- 作った AMI は検証環境で起動して確認してから、起動テンプレートに反映する
- 登録解除だけではスナップショットが残る。ID を控えてから削除し、直近の世代は残す