web-dev-qa-db-ja.com

指定されたEBSボリュームが接続された新しいEC2インスタンスを起動します

python botoライブラリを使用してEC2インスタンスを起動し、(ルートボリュームに加えて)以前に作成したEBSボリュームをアタッチしたいと思います。

接続後、名前タグでボリュームを検索し、ボリュームを含むブロックデバイスリストを作成しようとします。あらゆる種類のエラーが発生していましたが、最終的には、少なくともインスタンスの起動に成功する次のコードを作成しました。

volumes=conn.get_all_volumes(filters={'tag:Name':'TestVolume'})
vol=volumes[0]
print repr(vol)

disks=ec2.blockdevicemapping.BlockDeviceMapping()
xvdf=ec2.blockdevicemapping.BlockDeviceType(volume_id=vol.id,
    size=vol.size,volume_type=vol.type)
disks['/dev/xvdf']=xvdf

base_image="AMI-9a562df2" #ubuntu 14.04
reservation=conn.run_instances(
    base_image,
    instance_type="t2.micro",
    block_device_map=disks)

Printステートメントは、ボリュームを検索できたことを示し、正しいボリュームIDを報告します。ただし、インスタンスが起動すると、フォーマットされていない新しい32GBボリュームが作成され、代わりにボリュームに接続されます。

これを明確にするドキュメントを見つけるのに苦労しています。特定のEBSボリュームをblock_device_mapに追加する正しい方法は何ですか?

3
confuzzled

既存のEBSボリュームが接続された状態で新しいEC2インスタンスを起動することはできません。

代わりに、新しいEC2インスタンスが起動した後に、既存のEBSボリュームをアタッチします。 2つのオプションがあります。

  1. インスタンスの初期ブートシーケンス中に既存のEBSボリュームをアタッチします。 cloud initを使用して、ボリュームを接続する最初のスクリプトを実行します。

http://docs.aws.Amazon.com/AWSEC2/latest/UserGuide/user-data.html

  1. 新しいEC2インスタンスを起動した後、起動が完了するのを待ってから、Pythonスクリプト内から既存のEBSボリュームをアタッチします。

編集:コメントに基づいて詳細を追加しました。

さまざまな言語のSDKはすべて、ベースAWSAPIを呼び出します。 RunInstancesのベースAWSAPIドキュメントを見てください。

http://docs.aws.Amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html

そのコマンドには、BlockDeviceMappingparameterがあり、そのデータ構造に従うと、ボリュームIDプロパティが含まれません。

Python SDKに精通していませんが、SDKがBlockDeviceMappingクラスをオーバーロードして、起動の両方の仕様(ボリュームIDを許可しない)を表す可能性があります。実行中のインスタンスのマッピング(ボリュームIDを含めることができます)。

私は通常、AWS SDK for .NETを使用していますが、それに固有のドキュメントを参照することはめったにありません。私は通常、基本APIドキュメント(上記で参照したように)を参照してから、.NETSDKで使用する適切なメソッドを「見つけ」ます。ただし、不一致がある場合は、基本APIドキュメントを正しいものと見なします。

5
Matt Houser

Mattが言うのとは異なり、既存のEBSボリュームをAMIの作成中にアタッチすることは完全に可能です。

まず、ボリュームのスナップショットを用意する必要があります。これは、コンソールとaws-cliの両方で実行できます。

次に、このEBSスナップショットに基づいてAMIを作成します。

#!/bin/bash

aws --region=sa-east-1 ec2 \
register-image \
--name "image" \
--description "new_image" \
--architecture x86_64 \
--kernel-id aki-912fbcfd \
--root-device-name "/dev/xvda" \
--block-device-mappings "[
{
 \"DeviceName\": \"/dev/xvda\",
 \"Ebs\": {
 \"SnapshotId\": \"snap-0dfgkhdfjkhg77\",
 \"DeleteOnTermination\": false
  }
}
]"

次に、上記のAMIに基づいてインスタンスを起動します。ここでは、スポットインスタンスの作成のサンプルをドロップしますが、オンデマンドインスタンスの作成はさらに簡単です。

#!/bin/bash
AWS_DEFAULT_OUTPUT="text"
AMI="AMI-xxxxxxx"
price="0.0022"
region="sa-east-1"
sgroup="sg-54654765"
zone="sa-east-1b"
key="key"

aws ec2 request-spot-instances  \
    --region $region \
    --spot-price $price  \
    --type "persistent" \
    --instance-interruption-behavior "stop" \
    --launch-specification \
    "{ \"KeyName\": \"$key\", 
       \"ImageId\": \"$AMI\" , 
       \"InstanceType\": \"t1.micro\"
     }"

これはすべて、簡単にスクリプト化およびプログラム可能です。

1
Suncatcher