Building a Docker Amazon Machine Image with Packer
Amazon Machine Images (AMI) are the underpinnings of any deployment to Amazon Web Services (AWS). The AWS Marketplace contains thousands of great images to get started. However, for most deployments, these images are just a starting place for the application’s configuration. Often we need to install our monitoring tool, logging tool, security tool, and our application dependencies. This process needs to be consistent and reliable. It also needs to support building new images when updates and security patches become available.
Why Amazon Machine Images?
Amazon Machine Images provide a few distinct advantages over installing and configuring the machine on boot. Scalability, the ability for the application to quickly scale up to provide additional resources to the application. Installing dependencies on-boot increases the time until the new resources are available to support the scale. Reliability, by building and configuring the machine image ahead of time it can be tested before being rolled out to the cluster. Also, it assures that all resources are available during installation time. You may be familiar with the famous left-pad package removal from NPM, but what if one of our dependencies is down during our installation? Our application will be unable to boot and perform as expected. Finally is consistency, by deploying the same image we ensure that all images are the same. We don’t run the risk of having different states of servers within the cluster.
Building a Docker Machine Image
Packer is a powerful tool for building machine images that target multiple platforms. Infrastructure-as-Code is a popular approach to managing infrastructure within the community. We use Packer to treat our AMIs as pieces of the application code that can be directly integrated with a CI/CD pipeline. This pipeline can build, test, and deploy new images into your environment.
First, we need to configure Packer to describe how we want to build our image. We are going to provision a base Ubuntu 16.04 LTS image with two disks, the boot disk and the Docker disk that is used for /var/lib/docker and the DeviceMapper Thinpool.
Next, we need to provide a script that will install and configure our dependencies.
Finally, we need to run the build against an AWS account and store the image within our private AWS AMI store.
This machine image is now available within our AWS Account and can be launched as part of an Auto-Scaling Group or as a single instance.
Conclusion
We now have an AMI that is ready to be used to deploy a Docker cluster within AWS. The above script can be easily modified to target VMWare, VirtualBox, and Azure.