jadeallenx / net-amazon-ec2

Perl interface to the Amazon Elastic Compute Cloud (EC2) environment.

Home Page:http://metacpan.org/release/Net-Amazon-EC2

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mixing EBS and ephemeral drives in BlockDeviceMapping is not documented; guidance requested

jimbrowne opened this issue · comments

If one wants to change the size of the EBS root volume from what is in the AMI and if one needs to specify ephemeral mappings (e.g. for m3 instances[1]), one needs to mix EBS with ephemeral in the BlockDeviceMapping. With how EC2.pm is passed parameters this means passing three arrays and using undef in some positions. I wanted to document this in the POD but I couldn't find a good place for it. Since parameters to run_instances are listed individually that didn't seem like a good place, and there's no place for advanced examples; placing this in the summary seems to violate the brevity implied by the title summary. I'm opening this issues to fish for suggestions.

Here's some example code that could go in the documentation:

my @BDMDeviceName;
my @BDMEBSVolumeSize;
my @BDMVirtualName;

if ($ebsSize) {
    push @BDMDeviceName,    '/dev/sda1';
    push @BDMEBSVolumeSize, $ebsSize;
    push @BDMVirtualName,   undef;
}

for my $ephemeral ( 0 .. 1 ) {
    push @BDMDeviceName,    '/dev/xvd' . chr( ord("b") + $ephemeral );
    push @BDMEBSVolumeSize, undef;
    push @BDMVirtualName,   'ephemeral' . $ephemeral;
}

$run_options{'BlockDeviceMapping.DeviceName'}     = \@BDMDeviceName;
$run_options{'BlockDeviceMapping.VirtualName'}    = \@BDMVirtualName;
$run_options{'BlockDeviceMapping.Ebs.VolumeSize'} = \@BDMEBSVolumeSize;

[1] "For M3 instances, you must specify instance store volumes in the block device mapping for the instance. When you launch an M3 instance, we ignore any instance store volumes specified in the block device mapping for the AMI." -- [AWS Docs](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-RunI
nstances.html)

Thanks for the issue - this is an important question. I guess my response would be: how can we make this interface not suck so much for this example? Can you give me a Perlish data structure that expresses exactly what you need?

I struggle with this because my use-cases for this library tend to be on the very simple side of things, so I almost never encounter them on a day-to-day type of basis.

Prior to the M3 tier I don't think most people were manipulating the BlockDeviceMapping for ephemeral devices, so I can see it being a rare use case in the past. I considered patching to allow BlockDeviceMapping.%d type-parameters for advanced use, but I didn't find a way to codify a regexp for the argument in Moose. At that point I looked more closely at the code, saw the undef case and used the above approach. I don't think that approach is bad per se if we could just provide an example for future users.

I was thinking more like this:

[{
   'DeviceName' => '/dev/xvd0',
   'DeviceType' => 'ephemeral', # or some other signifier to treat this appropriately
  },
  {
   'DeviceName' => '/dev/foo',
   'VolumeSize' => 10,
   'VirtualName' => 'bar',
  },
]

And this could get unpacked into the proper XML elements - I hate using an arrayref for this stuff. The natural mapping is into a hash and we ought to expose it that way IMO.

Could certainly use a hash, though your example is wrong :) (VirtualName is only set for ephemeral devices and AFAICT always takes the format of ephemeral(\d){1,2}.)

Another option would be to accept the format already accepted by the create_image method.

Not surprised it's wrong - I just guessed hehe. As far as what to do - do you have a choice? I don't use features like this so... this is your chance to pick your poison, right? :)

Can this ticket be closed now? I can't remember if there was a PR to address it.

I'm going to close this issue for now. Please open another one if needed. Thanks.