Baking AMI’s is a great way to have preconfigured machine images ready to deploy EC2 instances. It saves a lot of time when launching EC2 instances when most of the software is already available and is essential for scaling your infrastructure. Today we will look at 2 tools, Packer and EC2 Image Builder, for baking AMI’s in an automated, devops way.
Let’s look at our old friend Packer. For a long time, Packer was the first and, for most of us, the only choice to make AMI in AWS. And it’s still a great tool what most people will choose to make AMI’s with. It’s free and open source and easy to use. You just need to create a JSON file and write the commands you want to run in some shell scripts and kick off the Packer command line tool to start building AMI’s. It is a nice and simple solution that can be run from anywhere on your local machine to a Codebuild process.
EC2 Image Builder
EC2 Image Builder has been introduced since the end of 2019 and has a somewhat different approach to AMI baking. Compared to Packer, EC2 Image Builder takes a more pipeline approach to building AMI’s and is meant to be more of a full continuous, complete solution for building AMI’s. It is however not a full replacement for a full Codepipeline solution and can be seen as a more lightweight pipeline to specifically build AMI’s and can be started on a schedule or manually.
AWS has some great documentation about how to use EC2 Image Builder, but to understand how EC2 Image Builder is different from Packer, I will quickly summarize how it works.
In EC2 Image Builder you’ll start off by creating an Image Pipeline. This Pipeline can be set to trigger by a schedule or manually. A basic Image Pipeline also contains an Image Recipe, which is a configuration of what base image to use, what scripts need to be run to create and test the image and maybe some extra volumes that need to be created.
The steps for the Image Recipes are defined in pieces that are called Components and contain the commands that need to be run on the EC2 Instance that will be started. Components are self contained and don’t have any dependencies on one another. As part of the component, it not only includes build steps, but test and validation steps as well. Components also cannot be configured with external arguments, which makes their reuse case extremely limited.
Another important part of an Image Recipe is the Infrastructure Configuration. This allows configuration of important parts of the recipe such as, subnet ID and the IAM role to use.
Since Packer is not only limited to baking AMI images in AWS alone, it is a highly flexible tool to create images for a multitude of cloud providers. Flexibility can be very useful if you want to use the same set of scripts for machine images across different cloud providers. For example, you might want to have a VMWare machine image for a local development environment, but an AMI for in AWS. Packer will allow you to reuse the same scripts for both situations.
Since EC2 Image builder is built by AWS specifically to create AMI’s, it’s no surprise that reuse for other cloud provider is not supported. EC2 Image Builder is very limited to in this respect, in that you can only use it for creating AMI’s that are not usable by other cloud providers. On the other hand it is the most integrated solution, which works the best with the rest of the AWS services.
EC2 Image Builder has a nice way of integrating testing in the build process. After an image is created by the pipeline, another step in the process will start up a new EC2 instance with the newly created image to run extra test steps to make sure the AMI is done for prime time. And the commands for testing the image can be provided by you as the developer as part of the Components.
In Packer testing is not as nicely integrated. You would need to setup an extra step in your Codepipeline to accomplish the same thing. The same goes for validation.
Winner: EC2 Image Builder
Both methods support building images for Windows and Linux. The EC2 image builder is however a bit more limited when it comes to the base image that you can select. The default selection includes the major Linux distro’s, such as Amazon Linux, CentOS, Ubuntu, RedHat and SuSE, and of course Windows. You can use other ones as well by specifying a custom AMI id, but it is important that this base AMI has the SSM agent installed, since EC2 Image Builder uses SSM to execute all commands.
Packer does not have this requirement and can use all the major Linux base AMI’s and uses SSH/WinRM to communicate with the running instance.
If things go wrong, both have ways to debug the process. In both methods it’s possible to let the instance running after an error to figure what is going wrong. Though, in EC2 Image Builder it’s required to set this on the configuration explicitly.
When it comes to logging, Packer outputs all the log in the console. A
-debug flag can be given to
packer build to enable more logging. It’s nice and simple.
EC2 Image Builder will output all the logging of the pipeline process in Cloudwatch Logs. This is nice, because you can see logs for multiple runs and it also allows you automate things, such as using Cloudwatch filtering to trigger Lambda’s.
Winner: EC2 Image Builder
What should you choose?
This question depends mostly on what the use case is. If you’re creating machine images specifically for use in AWS, EC2 Image Builder is a no brainer. It has all the nice integrations with the rest of the AWS services and is generally quite easy to understand. Sure, there are some things that I would like to see improved, such as better Cloudformation support. To elaborate, Image Recipes and Components are versioned. Redeploying the same Cloudformation template can give you some issues regarding versions that are already deployed. One solution is to use a custom resource to provide a version number based on an existing resource and autobump it. And better reusable Components by providing a way to set parameters. But in overall I expect AWS will support for the next coming years and make it better.
However, if you need more flexibility and need to support more than just AWS, do consider using Packer. It is by far the most flexible of the 2 and is easy to startup. For its shortcomings, most can be resolved using Codepipeline and Codebuild.
Update (15-7-2021): Components support parameters now. (https://aws.amazon.com/about-aws/whats-new/2021/07/ec2-image-builder-supports-parameters-components-creating-custom-images/)