Proxmox VEからAWS EC2へVMを移行する方法|VM Import/ExportでAMI化

VM Import/Export は、オンプレミスの仮想化基盤上の仮想マシン (VM)を、Amazon EC2 にインポートする AWS の機能です。Amazon Machine Image (AMI) としてインポートすると、AMI から EC2 インスタンスとしていつでも起動することができます。今回、Proxmox VE 上の仮想マシンを VM Import サービスを使用してインポートしてみます。
なお、インポート後の構成には、AMI としてインポート、インスタンスとしてインポートの二種類があります。特殊な理由(※)がなければ、AMI としてインポートすることを選択すべきです。
※移行対象の OS がレガシーであり、Nitro 世代(NVMe や ENAドライバー)に対応できない、またはカーネルが未対応などの理由により、 Xen 旧世代インスタンスで起動する場合など。
検証環境
オンプレミス環境を以下示します。
・Proxmox VE 8.4.18(仮想化ホスト)
・Rocky Linux 9(移行元VM)
・Windows 11 PRO / AWS CLI(作業端末)
下図は本記事における環境と作業フローを示します。

AWSと作業端末との接続確認
作業はなるべく CLI で完結したいので、作業端末(Windows 11)に AWS CLI をセットアップしてから進めます。作業端末上の PowerShell から、以下の AWS CLI コマンドを実行し、作業用 IAM ユーザーで正常に応答がある状態が前提となります。
1.認証の確認
> aws sts get-caller-identity
{
"UserId": "*********************",
"Account": "[Account ID]",
"Arn": "arn:aws:iam::[Account ID]:user/[User NAME]"
}
>2.S3との接続確認
※バケットが0個の場合は何も出力がなくプロンプトが返ります。
> aws s3 ls
2026-10-10 15:34:35 vm-import-[Account ID]-ap-northeast-1-an
>3.EC2との接続確認
> aws ec2 describe-instances
{
"Reservations": []
}
>VM Importサービスとアカウントとの信頼関係の作成
AWS の VM Import のサービスが動作するために、AWS に「vmimport」という名前の専用 IAM ロール作成と、S3 への接続設定が必要なため作成します。
1.VM Import サービスとアカウントとの信頼関係作成
“trust-policy.json” という名前の json ファイルを任意の場所で作成して AWS に送り込みます。これにより “vmimport” というロールとポリシーが作成され、VM Import サービスが作業を代行できるようになります。
PowerShell からノートパッドを起動する。
> notepad
以下の記述を trust-policy.json として保存する。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "vmie.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
作成ファイルを確認
> ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2026/10/10 16:42 337 trust-policy.json
ロールを AWS IAM に作成する。
> aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json
~jsonの応答が出力~
>2.VM Import サービスと S3 バケットとの連携
VM Import サービスが任意の S3 バケット(vm-import-[Account ID]-ap-northeast-1-an)からディスクを読み込み、EC2 側にスナップショットを作成できるようにするポリシーを作成・追加します。
ノートパッドを起動する。
> notepad
以下の記述を trust-policy.json として保存する。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::vm-import-[Account ID]-ap-northeast-1-an",
"arn:aws:s3:::vm-import-[Account ID]-ap-northeast-1-an/*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:ModifySnapshotAttribute",
"ec2:CopySnapshot",
"ec2:RegisterImage",
"ec2:Describe*"
],
"Resource": "*"
}
]
}
作成ファイルを確認する。
> ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2026/10/10 17:51 662 role-policy.json
-a---- 2026/10/10 16:42 337 trust-policy.json
ポリシーをロール "vmimport" に追加する。
> aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.jsonProxmox VEで移行対象VMのディスクを変換
大前提として、Proxmox VE の VM の仮想ディスク形式「QCOW2」は、VM Import が対応していません。一旦、VM の仮想ディスクを VMDK 形式に変換します。整合性の観点から対象 VM は停止した状態で実行します。
1.ディスクの実体パスの確認
VM の設定ファイルからストレージ名とファイル名を確認する。
# qm config [VM-ID] | grep -E "(scsi|virtio|sata|ide)[0-9]:"
ide2: none,media=cdrom
scsi0: ssd-1:vm-103-disk-1,discard=on,iothread=1,size=50G
実体パスを確認する。
# pvesm path ssd-1:vm-103-disk-1
/dev/ssd-1/vm-103-disk-12.VMDK ファイルへの変換
VMDK ファイルのサブフォーマットは、VM Import が対応している VMware OVF/OVA 形式とする必要があります。Proxmox VE の qemu コマンドによる変換の際、streamOptimized オプションを使用して変換します。
streamOptimized オプションを使用すると、内部が 2MB 単位のブロックに分割され、Deflate 圧縮されたストリーム構造を持ちます(未使用領域のゼロブロックが圧縮されます)。拡張子は .vmdk のままであり、フォーマット分類上も「VMDK」として扱われます。
ただし、実体のファイルサイズもより小さくなりますすが、変換中は Proxmox VE ホストの CPU の1コアを占有します。
# qemu-img convert -p -O vmdk -o subformat=streamOptimized /dev/ssd-1/vm-103-disk-1 /mnt/pve/MS150-BAK/vm-103-disk-1-streamOptimized.vmdk
(100.00/100%)
※"/dev/ssd-1/vm-103-disk-1" が変換元の VM ディスクの実体パス
※"/mnt/pve/MS150-BAK/vm-103-disk-1-streamOptimized.vmdk" が変換後の VMDK の実体パス
※オプションの解説
-p: 進捗状況(%)を表示
-O vmdk: 出力フォーマットを VMDK に指定
-o subformat=streamOptimized: 未使用領域の圧縮を指定
変換後のサイズ確認
# du -sh /mnt/pve/MS150-BAK/vm-103-disk-1-streamOptimized.vmdk
6.8G /mnt/pve/MS150-BAK/vm-103-disk-1-streamOptimized.vmdkS3へのVMDKのアップロード
1.S3 へのアップロード
PowerShell から VMDK ファイルを配置したフォルダから S3 バケットへ転送します。今回、転送総量 6.8 GiB の HDD 上のファイルを 1Gbps ネットワークの作業端末から転送し、平均実効スループットは 58 MiB/s 程度でした。商用環境(10Gbps、全てがSSD)であれば、5倍~8倍程度の速度で転送が完了できるものと予想します。
> aws s3 cp "U:\vm-103-disk-1-streamOptimized.vmdk" s3://vm-import-[Account ID]-ap-northeast-1-an/vm-103-disk-1.vmdk
Completed 242.0 MiB/6.8 GiB (61.3 MiB/s) with 1 file(s) remaining
↓
upload: U:\vm-103-disk-1-streamOptimized.vmdk to s3://vm-import-772638622264-ap-northeast-1-an/vm-103-disk-1.vmdk
>2.アップロード後の確認
正常に S3 バケットに配置されたか確認します。
> aws s3 ls s3://vm-import-772638622264-ap-northeast-1-an/
2026-10-11 17:49:04 7277967872 vm-103-disk-1.vmdkAMI への変換
1.インポート対象の S3 情報を記述した json ファイルを作成
ノートパッドを起動する。
> notepad
以下の記述を containers.json として保存する。
[
{
"Description": "Proxmox VM 103 Disk 1",
"Format": "vmdk",
"UserBucket": {
"S3Bucket": "vm-import-[Account ID]-ap-northeast-1-an",
"S3Key": "vm-103-disk-1.vmdk"
}
}
]
作成ファイルを確認する。
> ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2026/10/11 17:15 210 containers.json
-a---- 2026/10/10 17:51 662 role-policy.json
-a---- 2026/10/10 16:42 337 trust-policy.json2.インポートタスクの開始
> aws ec2 import-image --description "Proxmox-VM-103" --disk-containers file://containers.json
{
"Description": "Proxmox-VM-103",
"ImportTaskId": "import-ami-480f7ac24e512184t",
"Progress": "1",
"SnapshotDetails": [
{
"Description": "Proxmox VM 103 Disk 1",
"DiskImageSize": 0.0,
"Format": "vmdk",
"UserBucket": {
"S3Bucket": "vm-import-[Account ID]-ap-northeast-1-an",
"S3Key": "vm-103-disk-1.vmdk"
}
}
],
"Status": "active",
"StatusMessage": "pending"
}
>3.進捗状況を確認
“ImportTaskId” の値を代入して、以下のコマンドで進捗が確認できます。”Status” が “completed” になれば AMI の作成が完了です。以下では、AMI “ami-0084d4a74a1bca523” が発行されています。
タスク実行直後。
> aws ec2 describe-import-image-tasks --import-task-ids "import-ami-480f7ac24e512184t"
{
"ImportImageTasks": [
{
"Description": "Proxmox-VM-103",
"ImageId": "",
"ImportTaskId": "import-ami-480f7ac24e512184t",
"Progress": "9",
"SnapshotDetails": [
{
"DiskImageSize": 7277967872.0,
"Format": "VMDK",
"Status": "active",
"UserBucket": {
"S3Bucket": "vm-import-[Account ID]-ap-northeast-1-an",
"S3Key": "vm-103-disk-1.vmdk"
}
}
],
"Status": "active",
"StatusMessage": "converting",
"Tags": []
}
]
}
タスク完了後。
> aws ec2 describe-import-image-tasks --import-task-ids "import-ami-480f7ac24e512184t"
{
"ImportImageTasks": [
{
"Architecture": "x86_64",
"Description": "Proxmox-VM-103",
"ImageId": "ami-0084d4a74a1bca523",
"ImportTaskId": "import-ami-480f7ac24e512184t",
"LicenseType": "BYOL",
"Platform": "Linux",
"SnapshotDetails": [
{
"DeviceName": "/dev/sda1",
"DiskImageSize": 7277967872.0,
"Format": "VMDK",
"SnapshotId": "snap-00f6e4a09eea24a3b",
"Status": "completed",
"UserBucket": {
"S3Bucket": "vm-import-[Account ID]-ap-northeast-1-an",
"S3Key": "vm-103-disk-1.vmdk"
}
}
],
"Status": "completed",
"Tags": []
}
]
}
AMI 作成時の変更点と確認箇所
VM Import サービスが Rocky Linux(RHEL 系ディストリビューション)の仮想ディスクを読み込み、EC2 上でブート可能な AMI(Amazon マシンイメージ)へ変換する際、内部のファイルシステムをマウントして自動的に修正する変更点は以下のとおりです。
①ENA(Elastic Network Adapter)ドライバーの構成
Nitro 世代の高速ネットワークに必須となる ENA モジュールを、initramfs(初期 RAM ディスク)、及びカーネルモジュール設定に追加します。
※NVMe / ENA ドライバーが OS 内に元々インストールされている場合。
②NVMe ストレージドライバーの構成
Nitro 世代で EBS ボリュームが NVMe デバイスとしてアタッチされるため、ブート時にルートボリュームをマウントできるよう nvme / nvme-core ドライバーを initramfs に組み込みます。
※NVMe / ENA ドライバーが OS 内に元々インストールされている場合。
③initramfs の再生成
新しいドライバーなどを既存の初期 RAM ディスク(initramfs)に含めて起動用イメージを再ビルドします。
④カーネルパラメータの調整(/etc/default/grub 等)
シリアルコンソールや AWS の「システムログ取得」へブートログを出力するため、コンソールリダイレクト(console=ttyS0,115200n8 console=tty0 など)を追加します。
⑤UDEV 永続的ネットワークルールの無効化・削除
Proxmox VE 環境の MAC アドレスにより、新しいインターフェース(eth0 等)が認識されなくなる現象を防ぐため、以下のファイルが存在する場合は削除または空に置換されます。
/etc/udev/rules.d/70-persistent-net.rules
⑥ネットワーク設定の DHCP 化準備
既存のネットワークスクリプト(NetworkManager や /etc/sysconfig/network-scripts/ifcfg-*)内の静的 IP や MAC アドレスの記述を無効化し、AWS の DHCP から IP を自動取得できるようにします。
⑦既存のオンプレミス仮想化ツールの無効化
Proxmox VE 向けに入っていた qemu-guest-agent や、または VMware 起因でインストールされていた open-vm-tools などのサービスが停止・無効化されます。
⑧ライセンス・プラットフォームメタデータの設定
OS の変更ではありませんが、AWS で Platform: Linux、Architecture: x86_64、LicenseType: BYOL(既存ライセンス持ち込み)として属性が付与されます。
EC2 インスタンスの設定
ここからは AWS コンソールを使用して、インスタンスを起動してみます。
1.AMI の起動(選択)
EC2 ダッシュボードを開き、作成された ami-0084d4a74a1bca523 を選択し、右上の 「AMI からインスタンスを起動」 をクリックします。
2.起動設定
・インスタンスタイプ
AMI 変換時に ENA/NVMe ドライバーが導入済みのはずなので t3 などの Nitro 世代を選択します。なお、Xen 旧世代で起動すべきレガシーな OS を、Nitro 世代のマシンで起動すると、ENA/NVMe ドライバーが未導入のため、ブート時にカーネルパニック等が発生します。
・キーペア
今回、インポート元 VM(RockyLinux)の既存ユーザー・パスワードで SSH ログインするため、EC2 のキーペア指定はしません。
・ネットワーク設定
接続対象の VPC、パブリックサブネットを選択し、インターネット越しに SSH 接続の確認をしたければ「パブリックIPの自動割り当て」を “有効化” にします。また、「セキュリティグループ」では、作業端末(接続元)のグローバル IP を SSH で許可するルールを追加しておきます。

3.インスタンスを起動


早速、SSH でログインしてみます。接続は旧 SSH の鍵情報で問題なくできました。ただし、Last login の IP が移行前のオンプレミス環境ものであり、念のため、who コマンドで現在の接続元 IP も確認します。
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Sun Oct 4 19:03:02 2026 from 192.168.1.250
#
# who am i
root pts/0 2026-10-11 20:36 (222.227.***.***)
#万が一、SSH 接続ができない場合は、EC2 シリアルコンソールから接続をして原因を確認しましょう。
AMI 変換前後の補足
①fstab への影響について
今回、移行元 VM の OS では LVM(Logical Volume Manager)構成だったため、AMI 変換時に、物理ディスクのデバイス名がオンプレミスの「VirtIO/SCSI」から EC2「NVMe」へ変化しても、LVM のボリュームグループ・論理ボリューム名は変わらないため、書き換える必要がありませんでした(VM Import サービスが)。
また、元々から /boot 領域はファイルシステムの固有識別子(UUID=b55c81e3-…)で指定されていたことから、ディスクイメージをそのままブロック単位で複製・インポートしたことから、ファイルシステムの UUID は移行前後で維持されており、書き換えが不要でした。
以下、移行後の fstab です(移行元と変化なし)。
# cat /etc/fstab
# /etc/fstab
# Created by anaconda on Sat Nov 1 02:21:49 2025
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
/dev/mapper/rl-root / xfs defaults 0 0
UUID=b55c81e3-af71-4fc5-9aeb-924ecdd915be /boot xfs defaults 0 0
/dev/mapper/rl-swap none swap defaults 0 0②物理デバイスの認識の変化について
/etc/fstab に変化はなくても、OS が認識しているディスクデバイス名が変化しています。
■移行元 VM の OS
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 49G 0 part
├─rl-root 253:0 0 44G 0 lvm /
└─rl-swap 253:1 0 5G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom■移行先 AMI 変換後
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 50G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
└─nvme0n1p2 259:2 0 49G 0 part
├─rl-root 253:0 0 44G 0 lvm /
└─rl-swap 253:1 0 5G 0 lvm [SWAP]③IP 変更に伴う設定
移行した VM がウェブサーバーが実装されていて、固定のパブリック IPv4 アドレスが必要であれば Elastic IP を取得してインスタンスに関連付ける構成が必要です。そのほか、AWS SG(セキュリティグループの開放)設定、OS 内で firewalld が動作しているのであれば管理設定の見直しが必要となります。
④VMDK ファイルのフォーマット
VMDK ファイルのフォーマットが VM Import サービスが未対応で、インポート時にエラーとなった時の出力を残しておきます。”[Unsupported VMDK File Format]” の出力がそれです。この例では VMDK ファイルのフォーマットが “VMware OVF/OVA 形式” でなかったため発生しています。
> aws ec2 describe-import-image-tasks --import-task-ids "import-ami-f3eb3827f2823b13t"
{
"ImportImageTasks": [
{
"Description": "Proxmox-VM-103",
"ImageId": "",
"ImportTaskId": "import-ami-f3eb3827f2823b13t",
"Status": "deleted",
"StatusMessage": "CLIENT_ERROR : errorType: CLIENT_ERROR message: ClientError: Disk validation failed [Unsupported VMDK File Format]",
"Tags": []
}
]
}以上となります。総じて、Proxmox VE 上の VM の EC2 への VM Import を使用した移行は、レガシーな OS でなければ問題ないと言えます。
まとめ
今回は、オンプレミスの Proxmox VE 環境で稼働していた Rocky Linux 9 の仮想マシンを、AWS VM Import/Export サービスを用いて AMI 化し、EC2 として起動する一連の流れを検証しました。
実際に移行作業を行ってみて分かった重要なポイントは以下の通りです。
- ディスク変換時は streamOptimized サブフォーマットの指定が必要だったこと
Proxmox から qemu-img で VMDK を切り出す際、単に -O vmdk を指定するだけでは AWS 側の検証で Unsupported VMDK File Format エラーとなります。-o subformat=streamOptimized を明示することで、未使用領域の圧縮とともに VM Import に適合した形式で出力できます。 - ドライバーとブート環境の自動修復
VM Import 処理の過程で、Nitro 世代に必要な NVMe / ENA ドライバーが、OS 内にドライバモジュールが元々インストールされていることを前提として、ブート構成(initramfs)やモジュール読み込み設定への自動反映が行われます。 - LVM と UUID による構成維持
ディスク名がオンプレミス環境の /dev/sda から EC2 の /dev/nvme0n1 に変化しても、LVM(論理ボリューム名)や UUID でマウント管理されていれば、/etc/fstab を手動修正することなくそのまま起動可能です。
cloud-init をあえて導入せず、オンプレミス時代のアカウントや SSH 鍵設定をそのまま引き継いで稼働させたいケースにおいても、VM Import は非常に手軽で有力な移行手段となります。オンプレミスの Proxmox 環境から AWS へのリホスト(リフト&シフト)を検討されている方の参考になれば幸いです。
追記:
AWS の VM Import/Export については公式ドキュメント(日本語)が提供されています。全体的な把握はこちらを参照することをお勧めします。

