オンプレ ESXi から AWS へ Linux VM をインポートする

オンプレ ESXi から AWS へ Linux VM をインポートする

今回はオンプレ ESXi で作成した Linux VM を AWS へ移行する手順を試したのでメモとして記録します。

AWS への Linux VM 持ち込みについて

オンプレで作成した VM でも各種クラウドへ持ち込むことが可能です。AWS の場合は 2 種類のインポート方法が提供されています。今回はイメージインポートの方法で試してみます。

  • イメージインポート
  • インスタンスインポート

イメージインポート

イメージインポートは VM をイメージディスクとしてインポートし、そのイメージから VM を作成します。

インスタンスインポート

インスタンスインポートの場合、インポートが完了したときに VM が停止した状態で作成されます。

インポート手順

インポートの大まかな流れは次のとおりです。

  1. S3 バケットの作成
  2. VM インポート用ユーザーの作成
  3. VM インポートに対するサービスロールとポリシー作成
  4. Linux VM の事前準備
  5. VM ディスクのアップロード
  6. イメージインポート
  7. イメージからの VM インスタンス作成

VM Import/Export とは何ですか? – VM Import/Export (amazon.com)

S3 バケットの作成

AWS でイメージディスクを格納するための S3 バケットを作成します。

VM インポート用ユーザーの作成

VM インポートを実行するために必要な権限を持ったユーザーを作成します。インポート操作時にはこのユーザーをプロファイルで指定します。ここは AWS CLI でもコンソールからでもどちらでも良いです。パブリックアクセスは許可する必要はありません。

次の権限を持つ IAM ユーザーを作成します。<your-s3-backuet> の部分は前の手順で作成したイメージディスクを格納するための S3 バケットを指定します。ここでは VMImportUser という名前で作成すると想定します。

{
  "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:::<your-s3-bucket>","arn:aws:s3:::<your-s3-bucket>/*"]
    }, 
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CancelConversionTask",
        "ec2:CancelExportTask",
        "ec2:CreateImage",
        "ec2:CreateInstanceExportTask",
        "ec2:CreateTags",
        "ec2:DeleteTags",
        "ec2:DescribeConversionTasks",
        "ec2:DescribeExportTasks",
        "ec2:DescribeExportImageTasks",
        "ec2:DescribeImages",
        "ec2:DescribeInstanceAttribute",
        "ec2:DescribeInstanceStatus",
        "ec2:DescribeInstances",
        "ec2:DescribeSnapshots",
        "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 ユーザーを使えるようにプロファイルに登録しておきます。リージョンは東京を想定しているので <ap-northeast-1> を指定します。

$ aws configure --profile VMImportUser
AWS Access Key ID [None]: <IAM ユーザーのアクセスキー ID>
AWS Secret Access Key [None]: <IAM ユーザーのシークレットアクセス>
Default region name [None]: ap-northeast-1
Default output format [None]: json

VM インポートに対するサービスロールとポリシー作成

VM インポートサービスが S3 バケットのデータを扱えるようにサービス用のロールとポリシーを作成します。まず、trust-policy.json というファイル名で次の内容のファイルを作成します。

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": { "Service": "vmie.amazonaws.com" },
         "Action": "sts:AssumeRole",
         "Condition": {
            "StringEquals":{
               "sts:ExternalId": "vmimport"
            }
         }
      }
   ]
}

aws iam create-role コマンドで --assume-role-policy-document オプションでは作成したファイルのパスを指定します。

aws iam create-role --role-name VM-Import --assume-role-policy-document "file://~/trust-policy.json"

次に、S3 バケットに対するポリシーを定義するファイルを role-policy.json という名前で作成します。S3 バケットの名前は作成済みのバケットの名前に置き換えます。

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "s3:ListBucket",
            "s3:GetBucketLocation"
         ],
         "Resource": [
            "arn:aws:s3:::<your-s3-bucket>"
         ]
      },
      {
         "Effect": "Allow",
         "Action": [
            "s3:GetObject"
         ],
         "Resource": [
            "arn:aws:s3:::<your-s3-bucket>*"
         ]
      },
      {
         "Effect": "Allow",
         "Action":[
            "ec2:ModifySnapshotAttribute",
            "ec2:CopySnapshot",
            "ec2:RegisterImage",
            "ec2:Describe*"
         ],
         "Resource": "*"
      }
   ]
}

aws iam put-role-policy コマンドでローカルファイルからロールにアクセスポリシーを付与します。

aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document "file://~/trust-policy.json"

Linux VM の事前準備

移行対象の VM は Red Hat Enterprise Linux 8 を利用します。Linux VM に必要となる主な準備は次の通りです。

  • AWS CLI のインストール
  • ウイルス対策ソフトの無効化
  • VMware Tools のアンインストール
  • CD ドライブの切断
  • DHCP クライアントサービスの有効化
  • SSH アクセスの有効化
  • SSH ポートのアクセス許可
  • 非ルートユーザーでの公開鍵認証を有効化
  • シャットダウン

AWS に持ち込める OS とイメージデータ形式の詳細なサポートと事前準備要件はこちらの公開情報に記載されています。

VM Import/Export の要件 – VM Import/Export (amazon.com)

AWS CLI のインストール

次のコマンドで AWS CLI をインストールします。

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

インストール完了後は次のコマンドでバージョンを確認できます。

aws --version

Installing, updating, and uninstalling the AWS CLI version 2 on Linux – AWS Command Line Interface (amazon.com)

最後は VM をシャットダウンしておきます。

VM ディスクデータのエクスポート

ESXi の VM 画面から [アクション]>[エクスポート] をクリックし、ディスクデータをローカルに保存します。

VM ディスクのアップロード

S3 バケットにエクスポートしたディスクデータをアップロードします。AWS CLI かコンソールでデータをアップロードしておきます。

イメージインポート

インポートするディスクデータを指定するファイルを次の内容で container.json という名前で作成します。OVF 形式などその他の形式の場合は公開情報を参考として記述します。

[
  {
    "Description": "My Image Disk Data",
    "Format": "vmdk",
    "Url": "s3://<your-s3-bucket>/<your-vm-disk.vmdk>"
  }
]

aws ec2 import-image コマンドでインポートするディスクデータを指定したファイルとともにインポートを実行します。

aws ec2 import-image --profile vmimportuser --description "AWS RHEL 8 Disk" --disk-containers file://~/container.json

VM Import/Export を使用してイメージとして VM をインポートする – VM Import/Export (amazon.com)

インポートの進捗は aws ec2 import-image コマンドの結果で得られる ImportTaskId を使って次のコマンドで取得できます。Progress は進捗率を表し、StatusComplete となっていれば完了です。

aws ec2 describe-import-image-tasks --import-task-ids <import-task-id>

イメージからの VM インスタンス作成

インポートが完了したら AMI として利用できるので、EC2 インスタンスとして作成できます。