Let’s take a closer look at the build plan. It has four stages, and the names are self explanatory.
Checkout – Check out the source code from one or more repositories.
Package – Build the code or create a package of the binaries then share them as artifacts.
Bake – Create new AMI.
Share – Share the AMI to other AWS account if needed.
Nothing special here for stages Checkout and Package.
Bake stage is the cool one. We use Packer to bake, and it only takes about 5 minutes. Really really awesome!! There 3 types of AMI builder that Packer supports: amazon-ebs, amazon-instance and amazon-chroot. I highly recommend to use amazon-chroot, as it is the most efficient one.
How it works? We install Packer in the Bamboo agent. Packer creates a new EBS volume from an existing source AMI and attach it to the Bamboo agent (EC2 instance as well). Once attached, a chroot is used to provision the system (like installing binaries) within that volume. After provisioning, the volume is detached, snapshotted, and an AMI is made. One gotcha here – stop any running services before detaching the volume, otherwise the unmount will fail.
All Packer configuration is included in a json file. You can copy files to the volume or run scripts in the chroot system. Here is a sample: packer_bake.json
{ "builders": [{ "type": "amazon-chroot", "source_ami": "ami-aws12345", "ami_virtualization_type": "hvm", "ami_name": "packer-base-ami-{{timestamp}}" }], "provisioners" : [ { "type" : "shell", "inline" : [ "sleep 10", "mkdir -p /opt/stackdriver/collectd/etc/collectd.d", "/etc/init.d/cloud-init start" ] }, { "type" : "file", "source" : "files/stackdriver/stackdriver", "destination" : "/etc/sysconfig/stackdriver" } }
Now just tell packer to bake a new AMI for you. Also remember to share the AMI ID as a artifact, as the deployment plan need that to create stacks.
/usr/local/packer/packer build -machine-readable packer_bake.json
And if you have multiple AWS accounts, and want to share the AMI across. Just simply modify the AMI attribute:
aws ec2 modify-image-attribute --image-id $image_id --launch-permission "{\"Add\": [{\"UserId\":\"$aws_id\"}]}"
By now, you have got all receipts for the build plan. In the next post, I will show you how the deployment plan works.