aws ec2 import-imageを使ってVMwareイメージをAMIにインポートしてみた
VMwareイメージをAWS移行するって話があるかなと思い検証しました!
参考にしたドキュメント aws.amazon.com
VMwareイメージのインポートについて
AWS環境のEC2でVM を使用する際、AMIにインポートや
直接インスタンスとしてEC2 にインポートすることができます。
今回は個人的に使い勝手がいいなと思う、AMIにインポートする手順をまとめました。 AMIへのインポートの場合、AMIからインスタンスの作成時に セキュリティグループやEBSサイズの指定などができます。
また、CloudFormationでのテンプレートに組み込みが簡単なのはうれしいです!
インスタンスのインポートについては
AWSの公式サイトに記載されていますので、
気になる方はご確認いただければと思います。
手順の大まかな概要
- 作業用PCにAWS CLIのインストール
- VM Import/Exportの事前準備
- VMwareから必要イメージファイルをエクスポート
- VMイメージファイル格納用のS3バケット作成・アップロード
- VM Import/Export用のIAM ロール (vmimport) の作成
- VMのインポート
作業用PCにAWS CLIのインストール
インポートコマンドを実行するために使用する作業用PCに AWS CLIをインストールしていない場合は、 AWS CLI のインストールを参照してインストールします。
VM Import/Exportの事前準備
※今回はCentOS 7を対象とします。
※実行前にVM Import/Export の要件を確認しておきましょう。
全般
IAM ユーザーに必要なアクセス許可
IAMユーザーとしてログインしている場合は
VM Import/Export を使用するには、IAM ポリシーに以下アクセス許可が必要です。
IAM ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:DeleteObject",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": ["arn:aws:s3:::mys3bucket","arn:aws:s3:::mys3bucket/*"]
},
{
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:PutRolePolicy"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CancelConversionTask",
"ec2:CancelExportTask",
"ec2:CreateImage",
"ec2:CreateInstanceExportTask",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DescribeConversionTasks",
"ec2:DescribeExportTasks",
"ec2:DescribeExportImageTasks",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstances",
"ec2:DescribeTags",
"ec2:ExportImage",
"ec2:ImportInstance",
"ec2:ImportVolume",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:ImportImage",
"ec2:ImportSnapshot",
"ec2:DescribeImportImageTasks",
"ec2:DescribeImportSnapshotTasks",
"ec2:CancelImportTask"
],
"Resource": "*"
}
]
}
権限がなければ、専用のIAMユーザを作成するのもありかと思います。
新規作成をした場合は、AWS CLIにこのユーザ情報を記載を忘れずに。。。
AWS CLIのインストール
作業用PCと同様にAWS CLI のインストールを参照してインストールします。
VMware Toolsをアンインストール
VMware Toolsをインストールしている場合は
以下の手順を参考にアンインストールしてください。
docs.vmware.com
静的IPアドレスを設定している場合はDHCPに設定に変更する
DHCPに設定していなければ以下の手順を参考に設定変更をしてください。
access.redhat.com
その他
- CD-ROM ドライブを利用している場合は切断する必要があります。
- VM のウイルス対策ソフトウェアまたは侵入検出ソフトウェアを利用している場合、無効にする必要があります。
- インポートプロセスが完了したら、これらのサービスを再度有効にすることができます。
Linux
リモートアクセスの設定
リモートアクセスの有効化をおこなっていない場合は
以下の手順を参考に必要な設定をしてください。
access.redhat.com
ホストのファイアウォールでリモートアクセスが許可されていなければ
以下の手順を参考に必要な設定をしてください。
access.redhat.com
公開鍵ベースのリモートアクセスが許可されていなければ
以下の手順を参考に必要な設定をしてください。
access.redhat.com
ブートローダーの確認
対象のブートローダーは以下の通りです。
以下のコマンドで対象のブートローダーを使用している確認します。
$ sudo dd if=/dev/sda count=1 | strings
ルートファイルシステムの確認
対象のルートファイルシステムは以下の通りです。
以下のコマンドで利用しているルートファイルシステムを確認します。
$ cat /etc/fstab
VMwareから必要イメージファイルをエクスポート
以下のVMwareサイトで利用しているVMwareの「OVAファイルをエクスポート」手順を検索し、その手順に従って作業をおこなえばエクスポートが可能です。 docs.vmware.com
VMイメージファイル格納用のS3バケット作成・アップロード
先ほど、エクスポートしたOVAファイルやVMDKファイルを格納するS3を
AWSコンソールまたは以下のAWS CLIコマンドで作成します。
$ aws s3 mb s3://bucket-name make_bucket: bucket-name $ aws s3 cp test.ovf s3://bucket-name/ upload: ./test.ovf to s3://bucket-name/test.ovf $ aws s3 ls s3://bucket-name 2020-01-07 03:35:00 317 file.txt
VM Import/Export用のIAM ロール (vmimport) の作成
trust-policy.json
という名前のファイルを作成しポリシーをファイルに追加します。
$ vim trust-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "vmie.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals":{ "sts:Externalid": "vmimport" } } } ] }
create-role
コマンドを使用して、vmimport
ロールを作成し、
ロールへのアクセス権を前の手順で作成したtrust-policy.json
をもとに付与します。
$ aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-poolicy.json { "Role": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Condition": { "StringEquals": { "sts:Externalid": "vmimport" } }, "Principal": { "Service": "vmie.amazonaws.com" } } ] }, "RoleId": "AROA2PLMIQDORKZYZRYOO", "CreateDate": "2020-01-07T01:14:37Z", "RoleName": "vmimport", "Path": "/", "Arn": "arn:aws:iam::xxxxxxxxxxxx:role/vmimport" } }
role-policy.json
という名前のファイルを作成します。
disk-image-file-bucket
はバケットは先ほど作成したバケット名を指定します。
$ vim role-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::disk-image-file-bucket" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::disk-image-file-bucket/*" ] }, { "Effect": "Allow", "Action":[ "ec2:ModifySnapshotAttribute", "ec2:CopySnapshot", "ec2:RegisterImage", "ec2:Describe*" ], "Resource": "*" } ] }
put-role-policy
コマンドを使用して上記で作成したvmimport
ロールにポリシーをアタッチします。
$ aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json
VMのインポート
インポートする各種パラメータを定義したcontainers.json
というファイルを作成します。disk-image-file-bucket
の箇所は作成したバケット名を指定してください。
単一ディスク(VMDKファイルが1つ)の場合
[ { "Description": "First disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" } } ]
複数ディスク(VMDKファイルが複数)の場合
[ { "Description": "First disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" } }, { "Description": "Second disk", "Format": "vmdk", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" } } ]
import-image
を使用してインポートタスクを作成します。
$ aws ec2 import-image --description "My server disks"--disk-containers file://containers..json { "Status": "active", "Description": "My server disks", "SnapshotDetails": [ { "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" }, "DiskImageSize": 0.0, "Format": "VMDK" }, { "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" }, "DiskImageSize": 0.0, "Format": "VMDK" } ], "Progress": "2", "StatusMessage": "pending", "ImportTaskId": "import-ami-xxxxxxxxxxxxx" }
Progress
が100になれば完了となります。
体感ですが結構待ちましたので気長に待ってください。
途中の進捗状況を確認はdescribe-import-image-tasks
コマンドで可能です。
$ aws ec2 describe-import-image-tasks --import-task-ids import-ami-xxxxxxxxxxxxx "ImportImageTasks": [ { "Status": "active", "Description": "testcslabo48", "SnapshotDetails": [ { "Status": "completed", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" }, "DiskImageSize": 1932634112.0, "Description": "First disk", "Format": "VMDK" }, { "Status": "completed", "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" }, "DiskImageSize": 76800.0, "Description": "Second disk", "Format": "VMDK" } ], "Progress": "20", "StatusMessage": "updating", "ImportTaskId": "import-ami-xxxxxxxxxxxxx" } ] }
途中でキャンセルする場合はcancel-import-task
コマンドを実行します。
$ aws ec2 cancel-import-task --import-task-id import-ami-xxxxxxxxxxxxx
Status
がcompleted
になればAMIが使用可能になります。
$ aws ec2 describe-import-image-tasks --import-task-ids import-ami-xxxxxxxxxxxxx { "ImportImageTasks": [ { "Status": "completed", "LicenseType": "BYOL", "Description": "My server disks", "ImageId": "ami-xxxxxxxxxxxx", "Platform": "Linux", "Architecture": "x86_64", "SnapshotDetails": [ { "Status": "completed", "DeviceName": "/dev/sda1", "Description": "First disk", "Format": "VMDK", "DiskImageSize": 1932634112.0, "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk1.vmdk" }, "SnapshotId": "snap-xxxxxxxxxxxx" }, { "Status": "completed", "DeviceName": "/dev/sdf", "Description": "Second disk", "Format": "VMDK", "DiskImageSize": 76800.0, "UserBucket": { "S3Bucket": "my-import-bucket", "S3Key": "my-server-vm-disk2.vmdk" }, "SnapshotId": "snap-xxxxxxxxxxxxx" } ], "ImportTaskId": "import-ami-xxxxxxxxxxxxx" } ] }
これでAMIが使えますのでAMIをもとにEC2を作成してみてください。
最後に
やってみた結果一番詰まるのは「VM Import/Exportの事前準備」かなと思います。
僕も実際にやったときはSSHユーザをつくり忘れてしまい
ログインも何もできないただの箱が出来上がりました。
「VM Import/Exportの事前準備」は各環境で実行手順がまちまちですので、
サービスの環境などでおこなう際はしっかりと確認していただけたら幸いです。