Creating custom AMI Images with AWS EC2 Image Builder

If you're familiar with AWS EC2 instances, you may already know about the optional "user data" field that allows you to provide a series of commands to be executed during instance startup. This is a convenient way to automate instance configuration, but what if there's a better way?

In today's post, we'll introduce you to AWS EC2 image builder, a service that enables you to create Amazon Machine Images (AMIs) with custom configurations. As an exercise, we'll walk through customizing an Amazon Linux image to include Docker and other utilities.

Before we get started, here are some key concepts to understand:

  • Components: These are sets of instructions needed to configure a specific service. Components are reusable and can be shared between Image recipes. They can be Amazon-managed or owned by you.

  • Image recipes: These are combinations of components needed to configure a custom AMI image. You specify the base image and the components to be applied on top.

  • Image pipelines: These are used to build custom AMI images using the procedure described in the Image recipe.

Creating a Component

First, open the AWS console and navigate to the EC2 Image Builder service. From the left menu, click Components, then click Create component.

In the Component details section, make sure to:

  • Select Linux as OS.

  • Select Amazon Linux 2 from the Compatible OS Version drop menu.

  • Set Utilis as component name.

  • Specify a component version.

It should look like this:

Next, move to the Content section, where you'll define the instructions. Copy and paste the following code:

name: Install common packages
description: Install common packages
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: InstallWithYum
        action: ExecuteBash
        inputs:
          commands:
            - yum install vim htop git -y

As you can see, the component consists of one step where yum, the Red Hat package manager, installs vim, htop and git.

Click Create component to save.

Note: Although we set as Compatible OS Version only AWS Linux but the same instructions can also be executed on Red Hat-based OSes like CentOS. This is a great example of how a component can be reused and shared in different Image Recipes.

Creating an Image Recipe

From the EC2 image builder console, click Image recipes and then click Create image recipe.

In the Recipe details:

  • Set as name: DockerEnabledImage.

  • Set version: 1.0.0.

It should look like this:

In the base image section:

  • Select Amazon Linux as Image Operating System.

  • Select Amazon Linux 2 EC2 Optimized x86 as Image name.

Setting up components

Next, we'll specify which components will be executed during the image creation. In the search bar, type docker and select Amazon-managed from the drop-down menu. Then, select docker-ce-linux.

This component installs Docker Community Edition, enables the docker service at startup, and adds the "ec2-user" to the docker group to execute docker commands without typing sudo.

As the name suggests, Amazon-manged components are created and shared by AWS, so AWS is responsible for keeping them up to date. This means that the component will be updated in case of changes in the docker-ce installation.

Select Owned by me in the drop-down menu, the Utilis component you created previously will appear, tick it.

When more than one component is included in the recipe, you can set the execution order. This might be important if your roles have dependencies, for this recipe, there is no need to execute the components in a specific sequence.

Click Create recipe to save.

Image pipelines

From the image builder console, click on Image pipelines and then Create image pipeline.

Specify a name for the pipeline:

In the Build schedule section, select Manual and click Next.

Select Use existing recipe and the image you previously created, and click Next.

The last two steps are optional just click Next, Next and finally Create pipeline.

At this point, the pipeline is configured and has to be triggered manually to create an image. Select the pipeline and from the Actions drop-down menu click Run pipeline

The build process consists of spinning an EC2 instance, executing the recipe and saving the custom AMI. If you open the EC2 dashboard just after triggering the pipeline you will see the build process running:

iiiii

The process might take some time, be patient!

Launch an Instance

Go to the EC2 console and click Launch instances. In the Application and OS Images section select Owned by me and then the image created from the pipeline:

Click Launch instance.

You can check by yourself if Docker is running and the installed packages are present! ;)

Conclusions

We have learned how to use the AWS EC2 image builder to create custom AMI images. We also created a custom AMI with Docker ready to be used on EC2 instances without further configurations.

The Image builder is very convenient to automate software installations and also to trigger automatic image build whenever a component or the base image is updated.

Beware, the EC2 image builder is a regional service, if you create a recipe in an eu region will not be visible an us one.

While building the image, AWS selected the m5.large "Instance type" (as shown in the EC2 dashboard image). However, since a large amount of computing power is not required, I am curious if a smaller instance type could be used instead. Unfortunately, I have not been able to find a way to adjust the instance type during the build process.

References:

Did you find this article valuable?

Support Marco's blog by becoming a sponsor. Any amount is appreciated!