amazon-web-servicesamazon-ebspacker

How to attach EBS volume with Packer during build time?


I'm not sure if this is the right way to go about it but what I'm looking to do is shorten the build time of an image by Packer. One of the steps required is to copy some 10 GB of data and make it part of the image.

Currently I'm using a shell provisioner to SFTP this in to the image. This takes a long time. Instead I would like to have this data already in an EBS volume which can be attached at build time. Since it would be mounted as a block device in Amazon's own network the transfer would be much faster than SFTP.

I tried searching around for such a method in Packer but there's not much out there. I'm going to try and see if I can use the ami_block_device_mappings optional parameter in the amazon-ebs builder to attach the EBS volume.

If there is a better method I'm not aware of please let me know.


Solution

  • So it looks like the shell provisioner is the way to go..for now. The shell provisioner seems like the catch all for things like this :). It would be good to have a parameter in the amazon-ebs builder at some point though. Something like "attach_ebs_volume" for instance. Anyway, here's how I did it:

    1. Add AWS info (ebs_volume, instance_id etc..) to the variables secion of the template. I do pull the access and secret key from ENV so it's not spelled out in the template but the rest i just define in the template for now.
    2. use "environment_vars" parameter in the provisioners block in the template to pass the variables to the build machine.
    3. add {{.Vars}} to the "execute_command" parameter so the vars are defined prior to the script run.
    4. install aws cli (part of the script being passed.)
    5. grab the instance_id of the build machine from meta_data via wget and assign to an env var.
    6. issue the aws cli command to attach the volume and use the env vars passed from the template to fill in the command options as well as the instance_id from the wget command.
    7. mount as normal (have it sleep for a few seconds before mounting, it takes a little time to attach. Otherwise it won't see it and the mount will fail.)

    Done.

    If anyone has a more elegant way... please share.

    Thanks.