AWS の EC2 インスタンスをローカルの Proxmox でそのまま実行できないか試行錯誤したときのメモ
大きく分けて以下のステップを踏む
- EC2 コンテナの AMI 作成
- AMI から S3 にエクスポート
- ローカル PC にダウンロード
- Proxmox が起動できるように変換
- 起動
移行した直後は SSH できない場合があるので、ID/Pass を設定しておくと安全
AWS Cloudshell (admin ユーザー)での作業
S3 Bucket の作成
# バケット名を定義
BUCKET_NAME="ami-export-$(date +%Y%m%d%H%M%S)"
REGION=ap-northeast-1
# バケットを作成
aws s3 mb s3://$BUCKET_NAME --region $REGION
vmimport ロールの作成
# vmimport ロールを作成
cat > trust-policy.json <<'JSON'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "vmie.amazonaws.com" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "sts:Externalid": "vmimport" } }
}]
}
JSON
aws iam create-role --role-name vmimport \
--assume-role-policy-document file://trust-policy.json
# vmimport ロールに必要権限を付与
cat > vmimport-inline.json <<'JSON'
{
"Version":"2012-10-17",
"Statement":[
{ "Effect":"Allow",
"Action":[ "s3:GetBucketLocation","s3:GetObject","s3:ListBucket","s3:PutObject","s3:GetBucketAcl" ],
"Resource":["*"]
},
{ "Effect":"Allow",
"Action":[ "ec2:ModifySnapshotAttribute","ec2:CopySnapshot","ec2:RegisterImage","ec2:Describe*" ],
"Resource":"*"
}
]
}
JSON
aws iam put-role-policy \
--role-name vmimport \
--policy-name AllowS3AndEC2ForExport \
--policy-document file://vmimport-inline.json
EC2 から AMI を作成
INSTANCE_ID の部分を自分ものに置き換える
INSTANCE_ID=i-xxxxxxxxxxxxxxxxx
AMI_ID=$(aws ec2 create-image \
--instance-id "$INSTANCE_ID" \
--name "ami-from-$INSTANCE_ID" \
--description "AMI created from $INSTANCE_ID" \
--no-reboot \
--query 'ImageId' --output text)
echo "AMI_ID=$AMI_ID"
AMI を S3 にエクスポート
PREFIX="exports"
EXPORT_TASK_ID=$(aws ec2 export-image \
--image-id "$AMI_ID" \
--disk-image-format VMDK \
--s3-export-location S3Bucket=$BUCKET_NAME,S3Prefix=${PREFIX}/ \
--role-name vmimport \
--query 'ExportImageTaskId' --output text)
echo "EXPORT_TASK_ID=$EXPORT_TASK_ID"
進捗確認(すこし時間がかかる)
aws ec2 describe-export-image-tasks
ダウンロード用 IAM ユーザー作成
S3 に転送したイメージをダウンロードするために IAM ユーザーを作成し、ローカル PC に AWS CLI をセットアップする
すでにセットアップ済みであれば「イメージをダウンロード」までスキップ
# ユーザー作成
USER_NAME=export-user
aws iam create-user --user-name $USER_NAME
# アクセスキー発行 (AccessKeyIdとSecret をメモする)
aws iam create-access-key --user-name $USER_NAME
# S3へのRead権限を付与
cat > s3-readonly.json <<JSON
{
"Version": "2012-10-17",
"Statement": [
{ "Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
},
{ "Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::$BUCKET_NAME"
},
{ "Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::$BUCKET_NAME/*"
}
]
}
JSON
aws iam put-user-policy \
--user-name $USER_NAME \
--policy-name S3ReadOnlySpecificBucket \
--policy-document file://s3-readonly.json
# もしフルアクセスを与える場合は以下のコマンド(非推奨)
# aws iam attach-user-policy --user-name $USER_NAME --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
ローカル PC での作業
AWS CLI 設定
AWS CLI のインストール方法については こちらを参照
USER_NAME=export-user
REGION=ap-northeast-1
export AWS_PAGER=""
aws configure --profile $USER_NAME # ここでさっきメモしたAccesskeyIdとSecretを入力
export AWS_PROFILE=$USER_NAME
aws configure set region $REGION --profile $USER_NAME
イメージをダウンロード
# すべてのバケットを表示
aws s3 ls
# バケット選んで中身を表示
aws s3 ls s3://ami-export-xxxxxxxxxxxxxx/
# バケット内のコンテンツをすべてダウンロード
aws s3 cp --recursive s3://ami-export-xxxxxxxxxxxxxx/ ./
VMDK から QCOW2/RAW に変換
qemu-utils をインストール
sudo apt update
sudo apt install qemu-utils
# 変換
qemu-img convert -f vmdk -O qcow2 export-ami-xxxxxxxxxxxxxxxxx.vmdk disk.qcow2
# 確認
qemu-img info disk.qcow2
Proxmox での作業
空の VM を作成
GUI からだと
- “Create VM”
- OS: “Do not use any media”
- System - BIOS: SeaBIOS
- Disks: すべての Disk を削除
Proxmox のホストに SSH してディスクをアタッチ
VM を作成後、VMID を GUI から確認して、変数を定義しておく
VMID=111
qm importdisk $VMID ./disk.qcow2 local --format qcow2
# ディスクを VM に接続:
qm set $VMID --scsihw virtio-scsi-pci --scsi0 local:$VMID/vm-$VMID-disk-0.qcow2
qm set $VMID --boot order=scsi0
# ネットワーク設定で、最初は互換性の高い e1000 を指定する
qm set $VMID --net0 e1000,bridge=vmbr0
# シリアル出力を有効化。
qm set $VMID --serial0 socket --vga serial0
VM 起動
qm start $VMID
# ターミナルに接続
qm terminal $VMID
起動できると、cloud-init のタイムアウトが発生した後、login を求められる (タイムアウトを待っているので多分 2 分くらいかかる)
[ 63.982952] cloud-init[1308]: 2025-09-20 14:42:15,253 - url_helper.py[WARNING]: Calling 'http://169.254.169.254/2009-04-04/meta-data/instance-id' failed [49/120s]: request error [HTTPConnectionPool(host='169.254.169.254', port=80): Read timed out. (read timeout=50.0)]
...
...
...
[ OK ] Started Execute cloud user/final scripts.
[ OK ] Reached target Cloud-init target.
Ubuntu 16.04.7 LTS ip-172-31-35-185 ttyS0
ip-172-31-35-185 login:
(余談) ID/Pass がわからない場合
ID/Pass がわからないかつ IP がその VM に割り振られていない場合はパスワードを変更してシリアルコンソールからログインできるようにする必要がある。
AWS のインスタンスは grub が無効化されている場合が多いので、以下の手順を踏んでパスワードをリセットする
- VM を一度シャットダウン or STOP
- 以下のコマンドで一度 VGA に戻す
qm set $VMID --delete serial0 && qm set $VMID --vga std
- Ubuntu Server の iso イメージを Hardware -> “CD/DVD Drive” -> “Use CD/DVD disk image file (iso)” に接続
- Options -> Boot Order から Disk を一番先頭に持ってくる
- 起動して GUI から Console を開く
- (Ubuntu Server の場合)Help -> Enter Shell
fdisk -l
で対象のデバイスを確認後、mount /dev/sda1 /mnt
で/mnt にマウントchroot /mnt
passwd root
でパスワード変更- SELinux が有効になっている場合はラベルを修復
getenforce # 結果が"Enforcing"の場合は続けて以下のコマンドを実行 restorecon -Rv /etc
- VM STOP 後、GUI から Hardware -> “CD/DVD Drive” -> “Do not use any media"を選択しディスクを外す
- VM を起動
起動後の調節
Cloud Init の無効化 (EC2 で設定されている Cloud Init が EC2 コンテナ管理用のエンドポイントにアクセスを試みて起動が遅くなるため)
sudo apt purge cloud-init
sudo rm -rf /etc/cloud/ /var/lib/cloud/
hosts に hostname を追加 (sudo コマンドの実行が極端に遅くなるため)
echo "127.0.1.1 $(hostname)" | sudo tee -a /etc/hosts