Create RHEL / CentOS 8 custom AMI for AWS using Image Builder

Ranch
You can download this article in PDF format to support us through the following link.

Download the guide as a PDF

turn off
Ranch

The
The

In this guide, we will discuss how to use Image Builder to create a custom RHEL 8 / CentOS 8 AMI for AWS. For newcomers to Image Builder, it is a tool for creating custom system images of Red Hat Enterprise Linux, including system images that are ready to be deployed on cloud platforms.

The image generator automatically processes the server setting details for each image output, so it is faster than the manual image creation method. Command line tool composer Available, as well as the graphical user interface in the Cockpit Web console.

Image generator block

  • blueprint – Define a customized system image by listing the software packages and customizations that will be included in the system. The blueprint is presented to the user in plain text format (Tom’s minimum language (TOML)).
  • write – The combination is a separate build of a system image based on a specific version of a specific blueprint.
  • customized – These are system specifications, not packaging. This includes users, groups and SSH keys.

Image Builder output format

The image generator allows you to construct images in multiple output formats. See the table below.

Description CLI name file extension
QEMU QCOW2 picture qcow2 .qcow2
Ext4 file system image ext4-filesystem .img
Raw partition disk image partitioned-disk .img
Start ISO in real time live-iso .iso
TAR file tar .tar
Amazon Machine Image Disk ami .ami
Azure Disk Image vhd .vhd
VMware virtual machine disk vmdk .vmdk
Open stack openstack .qcow2

Step 1: Install the Image Builder software package

Before using Image Builder, you need to install the following software packages.

                      
                        sudo yum -y install vim lorax-composer composer-cli cockpit-composer bash-completion
                      
                    

Enable Image Builder to start after each restart:

                      
                        sudo systemctl enable --now lorax-composer.socket
                      
                    

To access the UI through Cockpit, enable it:

                      
                        sudo systemctl enable --now cockpit.socket
sudo firewall-cmd --add-service=cockpit && sudo firewall-cmd --add-service=cockpit --permanent
                      
                    

Load the shell configuration script so that the auto-complete function of the composer-cli command can start working immediately without restarting:

                      
                        source  /etc/bash_completion.d/composer-cli
                      
                    

Step 2: Create a blueprint for Image Builder

We will use the command line interface to do this. However, the same operation can be performed from the Cockpit Web console. To use this interface, run composer Commands with appropriate options and parameters.

This is the workflow image generator:

  1. Export (save) blueprint definitions to plain text files
  2. Edit this file in a text editor
  3. Import (push) the blueprint text file into Image Builder
  4. Run compose to build the image based on the blueprint
  5. Export image files to download

Add your $ USER to the welder group.

                      
                        sudo usermod -aG weldr $USER
newgrp weldr
                      
                    

Create Image Builder blueprint:

                      
                        $ vim rhel8-base.toml
                      
                    

Mine has been modified as follows:

                      
                        name = "rhel-8-base"
description = "A RHEL 8 Base Image"
version = "0.0.1"
groups = []

[[modules]]
name = "vim"
version = "*"

[[packages]]
name = "openssh-server"
version = "*"

[[packages]]
name = "rsync"
version = "*"

[[packages]]
name = "tmux"
version = "*"

[[packages]]
name = "git"
version = "*"

[[packages]]
name = "tree"
version = "*"

[[packages]]
name = "bash-completion"
version = "*"

[[packages]]
name = "lvm2"
version = "*"

[[packages]]
name = "wget"
version = "*"

[[packages]]
name = "firewalld"
version = "*"

[[packages]]
name = "python3"
version = "*"

[[packages]]
name = "python3-pip"
version = "*"

[[packages]]
name = "telnet"
version = "*"

[customizations.kernel]
append = "net.ifnames=0"

[[customizations.user]]
name = "rheladmin"
description = " RHEL Admin User"
password = "hashed-user-password"
key = "your-ssh-pub-key"
home = "/home/rheladmin/"
shell = "/usr/bin/bash"
groups = ["users", "wheel"]
                      
                    

Replace Hash user password Hash with the actual password. To generate a hash, use the following command:

                      
                        python3 -c 'import crypt,getpass;pw=getpass.getpass();print(crypt.crypt(pw) if (pw==getpass.getpass("Confirm: ")) else exit())'
                      
                    

Check document All entries and customized pages.

Push the blueprint back into Image Builder:

                      
                        $ composer-cli blueprints push rhel8-base.toml
                      
                    

List the available image generators:

                      
                        $ composer-cli  blueprints list
example-atlas
example-development
example-http-server
rhel-8-base

                      
                    

Step 3: Use Image Builder to create a system image

Through Start Option to build an image for your CentOS / RHEL machine.

                      
                        $ composer-cli compose start BLUEPRINT-NAME IMAGE-TYPE
                      
                    

To view the available image types, run:

                      
                        $ composer-cli compose types
alibaba
ami
ext4-filesystem
google
live-iso
openstack
partitioned-disk
qcow2
tar
vhd
vmdk

                      
                    

Now, I will start writing with the blueprint and output type created.

                      
                        $ composer-cli compose start rhel-8-base ami
Compose 036fb329-0443-48ad-9444-a1c70caa4b36 added to the queue
                      
                    

To check the status of writing:

                      
                        $ composer-cli compose status
036fb329-0443-48ad-9444-a1c70caa4b36 RUNNING  Sat Apr  4 15:41:12 2020 rhel-8-base     0.0.1 ami            

$ composer-cli compose status
036fb329-0443-48ad-9444-a1c70caa4b36 FINISHED Sat Apr  4 15:46:52 2020 rhel-8-base     0.0.1 ami              4668260352  
                      
                    

After writing, download the generated image file:

                      
                        $ composer-cli compose image UUID

-- Example ---
$ composer-cli compose image 036fb329-0443-48ad-9444-a1c70caa4b36
036fb329-0443-48ad-9444-a1c70caa4b36-disk.ami: 4452.00 MB    
                      
                    

Step 4: Upload the AMI image to AWS

Install Python 3 and pip tools:

                      
                        sudo yum -y install python3 python3-pip
                      
                    

Use pip to install the AWS command line tool:

                      
                        sudo pip3 install awscli
                      
                    

Configure the AWS command line client based on your AWS access details:

                      
                        $ aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]:
Default output format [None]:
                      
                    

Configure the AWS command line client to use your bucket:

                      
                        $ BUCKET=ami-image-bucket
$ aws s3 mb s3://$BUCKET
                      
                    

Confirm the bucket creation:

                      
                        $ aws s3 ls 
2020-04-04 15:49:47 ami-image-bucket
                      
                    

Create the vmimport S3 role in IAM and grant it access to S3:

                      
                        printf '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "vmie.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals":{ "sts:Externalid": "vmimport" } } } ] }' > trust-policy.json

printf '{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Action":[ "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket" ], "Resource":[ "arn:aws:s3:::%s", "arn:aws:s3:::%s/*" ] }, { "Effect":"Allow", "Action":[ "ec2:ModifySnapshotAttribute", "ec2:CopySnapshot", "ec2:RegisterImage", "ec2:Describe*" ], "Resource":"*" } ] }' $BUCKET $BUCKET > role-policy.json

aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json

aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json
                      
                    

Upload the AMI image to AWS:

                      
                        $ BUCKET=ami-image-bucket
$ AMI=036fb329-0443-48ad-9444-a1c70caa4b36-disk.ami
$ aws s3 cp $AMI s3://$BUCKET
upload: ./036fb329-0443-48ad-9444-a1c70caa4b36-disk.ami to s3://ami-image-bucket/036fb329-0443-48ad-9444-a1c70caa4b36-disk.ami
                      
                    

After the upload to S3 is complete, import the image as a snapshot into EC2:

                      
                        printf '{ "Description": "my-image", "Format": "raw", "UserBucket": { "S3Bucket": "%s", "S3Key": "%s" } }' $BUCKET $AMI > containers.json

aws ec2 import-snapshot --disk-container file://containers.json
                      
                    

Sample output:

                      
                        {
    "ImportTaskId": "import-snap-0617ccf6944d82089",
    "SnapshotTaskDetail": {
        "DiskImageSize": 0.0,
        "Format": "RAW",
        "Progress": "3",
        "Status": "active",
        "StatusMessage": "pending",
        "UserBucket": {
            "S3Bucket": "ami-image-bucket",
            "S3Key": "036fb329-0443-48ad-9444-a1c70caa4b36-disk.ami"
        }
    }
}

                      
                    

Confirm the import process:

                      
                        $ aws ec2 describe-import-snapshot-tasks --filters Name=task-state,Values=active
{
    "ImportSnapshotTasks": [
        {
            "ImportTaskId": "import-snap-0617ccf6944d82089",
            "SnapshotTaskDetail": {
                "DiskImageSize": 4668260352.0,
                "Format": "RAW",
                "Progress": "94",
                "SnapshotId": "snap-0fd61ffa2f2cd4ad0",
                "Status": "active",
                "StatusMessage": "Preparing snapshot",
                "UserBucket": {
                    "S3Bucket": "ami-image-bucket",
                    "S3Key": "036fb329-0443-48ad-9444-a1c70caa4b36-disk.ami"
                }
            },
            "Tags": []
        }
    ]
}
                      
                    

Log in to AWS and confirm the existence of the snapshot.

Click “Snapshot” on EC2 and select Create an image :

Name the Image and set the virtualization type, disk size and description, etc.

Once created, the image will be available in the “AMI” section.

reference:

Similar guidelines:

Use Kickstart to automate RHEL and CentOS installation on KVM

Using Packer and Ansible to build an AWS EC2 machine image (AMI)

Ranch
You can download this article in PDF format to support us through the following link.

Download the guide as a PDF

turn off
Ranch

The
The

Related Posts