Images are built using packer. Packer takes care of booting a source image, bootstrapping it, running your configuration management and then shutting down and creating an ami. It can run multiple builds in parallel
To make image building super simple, there is a python script build_image.py
which simply takes the name of an image to build, the various images are
configured in images.yml
. The build_image.py
script will find the appropriate source ami, generate the configuration for packer, and then run packer.
- brew install packer
- brew install python
- pip install docopt
- pip install boto
- pip install PyYAML
for help using the build_image.py
script, just pass the help option build_image.py --help
The images.yml
file defines images and how they are built.
Each image is the result of running an ansible playbook,
First a collection of source images is queried from a source Available source types: ubuntu-api dependency image-search
- this looks up the latest official ubuntu source images
- the release_name parameter is required
- the filters should match fields in the api
- see https://cloud-images.ubuntu.com/query/trusty/server/released.current.txt
- this performs a search for AMIs via the api
- for available filters see http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-DescribeImages.html#cmd-DescribeImages-filters
- this searches for an AMI built by us with the name given in the depends_on parameter
- the filters follow the same format as the image-search
- where there are multiple versions of the same image, the one with the latest timestamp is returned
Then the results of the search are matched to outputs. Each combination of outputs will result in a seperate image. so if you have config like this:
output:
virtualization_type: ['hvm', 'paravirtual']
architecture: ['x86_64']
region: ['eu-west-1', 'sa-east-1', 'us-west-1', 'us-west-2']
Then you would end up with 8 images (2 x 1 x 4)
Then packer will build the images, running the given playbook. Note that packer will run ansible in local mode, in order to do this, the zoo repo will be
checked out on the remote host, so you must have committed and pushed any changes you want to take effect. To make this easier, the build script optionally
takes a branch name, so you can test out changes on a branch before pushing to master. e.g. build_image.py base test-branch
If you want to cancel the image builds, you can interrupt packer, and it will clean up the aws resources it was using for the build, if you interrupt it a second time, then it will force quit and the source aws instance / security group / ec2 key might not be removed. You should clean up if this happens.
Sometimes aws instances take ages to boot, sometimes aws instances never get out of the pending state, generally you just have to try again :(
If this is happending consistenly then you can try the --debug
flag e.g. build_image.py base --debug
, This will run packer in debug mode,
It will prompt you at each stage of the build and will give you the connection details and a ssh key you can use to get into the instance, you should ssh with the ubuntu
username.
I've found some times that builds magically work when you add the debug flag, this would indicate a race condition with packer. god knows.