Use Case - Building a RHEL AWS AMI image using bootc-image-builder
Warning
This example requires an active AWS account. Free tier could not be enough due to the 5GB limitation on S3 storage.
In this example, we will build a container image from a Containerfile and we will generate an AWS AMI to use as a base for Instances.
The Containerfile in the example:
- Updates packages
- Installs tmux and mkpasswd to create a simple user password
- Creates a bootc-user user in the image
- Adds the wheel group to sudoers
- Installs Apache Server
- Enables the systemd unit for httpd
- Adds a custom index.html
Review Containerfile.ami
MAINTAINER Alessandro Rossi <al.rossi87@gmail.com>
FROM registry.redhat.io/rhel9/rhel-bootc:9.5
RUN dnf -y update && dnf -y install tmux mkpasswd
RUN pass=$(mkpasswd --method=SHA-512 --rounds=4096 redhat) && useradd -m -G wheel bootc-user -p $pass
RUN echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/wheel-sudo
RUN dnf -y install httpd && \
systemctl enable httpd && \
mv /var/www /usr/share/www && \
sed -ie 's,/var/www,/usr/share/www,' /etc/httpd/conf/httpd.conf
RUN echo "Welcome to the bootc-http instance!" > /usr/share/www/html/index.html
EXPOSE 80
Building the image
From the root folder of the repository, switch to the use case directory:
To build the image:
Testing the image
You can now test it using:
Note: The "-p 8080:80" part forwards the container's http port to the port 8080 on the host to test that it is working.
The container will now start and a login prompt will appear:
On another terminal tab or in your browser, you can verify that the httpd server is working and serving traffic.
Terminal
Browser
Tagging and pushing the image
To tag and push the image you can simply run (replace YOURQUAYUSERNAME with the account name):
Log-in to Quay.io:
And push the image:
You can now browse to https://quay.io/repository/YOURQUAYUSERNAME/rhel-bootc-vm?tab=settings and ensure that the repository is set to "Public".
Configure required resources for AWS
The AMI building process will need some configuration both on the client (for CLI configuration and credentials) and on AWS (for resources and IAM).
The specific needs are:
- an S3 bucket to temporarily store the AMI image that will be imported in the catalog
- a policy (vmimport) to allow importing from S3 to the AMI catalog
- a role to allow the vmie service and bind the policy
In the files folder are stored the policy definition and the role definition that you can review below before applying.
Review aws-policy.json
{
"Version":"2012-10-17",
"Statement":[
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::rhel-bootc-demo",
"arn:aws:s3:::rhel-bootc-demo/*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:ModifySnapshotAttribute",
"ec2:CopySnapshot",
"ec2:RegisterImage",
"ec2:Describe*"
],
"Resource": "*"
}
]
}
Review aws-role.json
To start the configuration use the aws configure command and provide the required information:
[~]$ aws configure
AWS Access Key ID []:
AWS Secret Access Key []:
Default region name []:
Default output format [json]:
Once this is in place, we can proceed with the resources.
For S3 (replace YOURREGION with the correct region, ie. eu-west-1):
Tip
S3 Bucket names are globally registered and unique, based on the name you find available, edit the reference in lines 12-13 of the aws-policy.json file
[~]$ export REGION=YOURREGION
aws s3api create-bucket --bucket rhel-bootc-demo --create-bucket-configuration LocationConstraint=$REGION
Let's proceed with the role:
And then associate the policy to the role:
aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://files/aws-policy.json
We are now good to go!
Generating the AWS AMI image
To generate the AMI image we will be using bootc-image-builder container image that will help us transitioning from our newly generated bootable container image to an AMI image that can be used on AWS.
Let's proceed with the QCOW image creation:
sudo podman run \
--rm \
-it \
--privileged \
--pull=newer \
-v $HOME/.aws:/root/.aws:ro \
--env AWS_PROFILE=default \
registry.redhat.io/rhel9/bootc-image-builder:latest \
build \
--type ami \
--aws-ami-name rhel-bootc-x86 \
--aws-bucket rhel-bootc-demo \
--aws-region eu-west-1 \
quay.io/$QUAY_USER/rhel-bootc-vm:ami
The process will take care of all required steps (deploying the image, SELinux configuration, filesystem configuration, ostree configuration, etc.), after a couple of minutes we will find in the output:
Building manifest-ami.json
starting -Pipeline source org.osbuild.containers-storage: 6ec72d5cb7fb74985ee0fcdc8d90db85079cd08caa64fde9153c40aae3744f18
Build
root: <host>
Pipeline build: 733863e98e5497425dbf00ac2eec52175d453834f17868944ed3408bcd9a3d16
Build
root: <host>
runner: org.osbuild.rhel82 (org.osbuild.rhel82)
[...]
⏱ Duration: 1s
manifest - finished successfully
build: 733863e98e5497425dbf00ac2eec52175d453834f17868944ed3408bcd9a3d16
image: 6b2f313ea4e75ddb9f8c9f2da14d4234760986240d1957093bb3631f0010c09e
qcow2: 194f4993f08ada94b56bc5a59d17a08251388f9210e13f4671d231f7cd9abb97
vmdk: 6d03b4759af85fd6408f36c72fde3eaa271466beef14a5f1af0499410055df9c
ovf: c2410b0f4eecb91c7298d17c98dc672b42aedd02bb9809dab8feb1b185259689
archive: 950f23c305d2b41148790246e9abb8c925da34077f2954fabad284b9782f914e
Build complete!
Uploading image/disk.raw to rhel-bootc-demo:b1a83f25-051e-434c-a50f-ab634d1b798c-disk.raw
10.00 GiB / 10.00 GiB [------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 79.03 MiB p/s
File uploaded to https://rhel-bootc-demo.s3.eu-west-1.amazonaws.com/b1a83f25-051e-434c-a50f-ab634d1b798c-disk.raw
Registering AMI rhel-bootc-x86
Deleted S3 object rhel-bootc-demo:b1a83f25-051e-434c-a50f-ab634d1b798c-disk.raw
AMI registered: ami-0ade40e197a89bb69
Snapshot ID: snap-068821f35b9b832af
You can verify that the AMI is now present in the AMIs section on AWS. (the URL may be different based on the region).
Create the Instance on AWS
Using your preferred method, either via GUI or CLI, you can now create a fresh instance using the AMI we just imported.
Wait for the Instance to be ready and retrieve the IP address to log-in using SSH using bootc-user/redhat credentials:
~ ▓▒░
❯ ssh bootc-user@*****
The authenticity of host '***** (*****)' can't be established.
ED25519 key fingerprint is SHA256:OgY5Ym9dycIE2KPS5SRYRcmogUHalrUD35CyEH2A/j4.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '*****' (ED25519) to the list of known hosts.
bootc-user@*****'s password:
[bootc-user@ip-172-31-22-31 ~]$