How to create an image recipe in AWS Image Builder?
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
Today we will discuss how to create an image recipe in AWS Image Builder service using AWS CLI.
What is image recipe in AWS Image Builder?
An EC2 Image Builder recipe defines the base image to use as your starting point to create a new image, along with the set of components that you add to customize your image and verify that everything is working as expected. Automatic version choices are provided for each component. A maximum of 20 components, which include build and test, can be applied to a recipe.
After you create an image recipe, or a container recipe, you cannot modify or replace the recipe. To update components after a recipe is created, you must create a new recipe or recipe version. You can, however, always apply tags to your recipe.
How to create an image recipe in AWS Image Builder?
Prerequisites:
AWS CLI installed and configured.
Step 1: Create a new directory for this demo.
1 2 |
## Create a directory for the demo mkdir demo && cd demo |
Step 2: Create a component configuration file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
## Create a component document cat << 'EOF' > component_config.yaml name: HelloWorld description: Hello World App schemaVersion: 1.0 phases: - name: build steps: - name: UpdateOS action: ExecuteBash inputs: commands: - sudo yum update -y - name: InstallWebServer action: ExecuteBash inputs: commands: - sudo yum install httpd -y - sudo systemctl start httpd - sudo systemctl is-enabled httpd - echo "hello world v1" > /var/www/html/index.html - curl -s localhost - name: validate steps: - name: ValidateWebServer action: ExecuteBash inputs: commands: - | CUR_STATE=$(sudo systemctl is-active httpd) if [[ $CUR_STATE == "active" ]]; then echo "Httpd service is active." exit 0 else echo "Httpd service is not active." exit 1 fi - name: TestWebServer action: ExecuteBash inputs: commands: - | OUTPUT=$(curl -s localhost) if [[ $OUTPUT == "hello world v1" ]]; then echo "Webserver is working fine" exit 0 else echo "Webserver not working fine" exit 0 fi EOF |
Step 3: Create an S3 bucket with a proper bucket policy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
## Create an S3 bucket aws s3api create-bucket \ --bucket cloudaffaire-image-builder \ --create-bucket-configuration LocationConstraint=ap-south-1 ## Get S3 bucket ARN and AWS Account ID and ARN S3_BUCKET_ARN='arn:aws:s3:::cloudaffaire-image-builder' && ACCOUNT_ARN=$(aws sts get-caller-identity | jq -r .Arn) && ACCOUNT_ID=$(aws sts get-caller-identity | jq -r .Account) ## Create a s3 bucket policy definition file cat << EOF > bucket_policy_config.json { "Version": "2012-10-17", "Statement": [ { "Sid": "HelloWorldPolicy", "Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": ["$S3_BUCKET_ARN/*"], "Condition": { "StringEquals": { "aws:SourceAccount": "$ACCOUNT_ID", "s3:x-amz-acl": "bucket-owner-full-control" } } } ] } EOF ## Create a s3 bucket policy aws s3api put-bucket-policy \ --bucket cloudaffaire-image-builder \ --policy file://bucket_policy_config.json |
Step 4: Create a custom component in AWS Image builder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
## Upload component document in S3 bucket aws s3 cp component_config.yaml \ s3://cloudaffaire-image-builder/component_config.yaml ## Create custom component config def cat << 'EOF' > image_component_config.json { "name": "HelloWorldComponent", "semanticVersion": "1.0.0", "description": "Hello World App", "changeDescription": "Initial version.", "platform": "Linux", "uri": "s3://cloudaffaire-image-builder/component_config.yaml", "tags": { "App": "Hello World" } } EOF ## Create the custom component aws imagebuilder create-component \ --cli-input-json file://image_component_config.json ## List all available components owned by You aws imagebuilder list-components \ --owner Self ## List component build version COMPONENT_VERSION_ARN=$(aws imagebuilder list-components \ --owner Self | jq -r .componentVersionList[].arn) && echo $COMPONENT_VERSION_ARN && COMPONENT_BUILD_VERSION_ARN=$(aws imagebuilder list-component-build-versions \ --component-version-arn $COMPONENT_VERSION_ARN | jq -r .componentSummaryList[].arn) && echo $COMPONENT_BUILD_VERSION_ARN && aws imagebuilder list-component-build-versions \ --component-version-arn $COMPONENT_VERSION_ARN ## Get custom component details aws imagebuilder get-component \ --component-build-version-arn $COMPONENT_BUILD_VERSION_ARN |
Step 5: Get the AMI ID to be used in the image recipe.
1 2 3 4 5 6 |
## Get Amazon Linux 2 latest AMI ID AWS_AMI_ID=$(aws ec2 describe-images \ --owners 'amazon' \ --filters 'Name=name,Values=amzn2-ami-kernel-5.10-hvm-2.0.????????.0-x86_64-gp2' 'Name=state,Values=available' \ --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' \ --output 'text') && echo $AWS_AMI_ID |
Step 6: Create an image recipe configuration file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
## Create a image recipe document cat << EOF > image_recipe_config.json { "name": "HelloWorldRecipe", "description": "Hello World App", "semanticVersion": "2019.12.03", "components": [ { "componentArn": "$COMPONENT_VERSION_ARN" } ], "parentImage": "$AWS_AMI_ID" } EOF |
Step 7: Create an image recipe using AWS CLI.
1 2 3 |
## Create a custom image recipe aws imagebuilder create-image-recipe \ --cli-input-json file://image_recipe_config.json |
Step 8: Get details on the image recipe.
1 2 3 4 5 6 7 8 9 |
## List all available image recipes owned by You aws imagebuilder list-image-recipes \ --owner Self ## Get image recipe details IMAGE_RECIPE_ARN=$(aws imagebuilder list-image-recipes \ --owner Self | jq -r .imageRecipeSummaryList[].arn ) && aws imagebuilder get-image-recipe \ --image-recipe-arn $IMAGE_RECIPE_ARN |
You can also use AWS management console to create or view an image recipe.
Step 9: Clean up.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
## Delete image recipe aws imagebuilder delete-image-recipe \ --image-recipe-arn $IMAGE_RECIPE_ARN ## Delete the custom component aws imagebuilder delete-component \ --component-build-version-arn $COMPONENT_BUILD_VERSION_ARN ## Delete the S3 bucket with objects aws s3 rb \ s3://cloudaffaire-image-builder --force ## Delete the demo directory cd .. && rm -rf demo |
Hope you have enjoyed this article. To get more details in AWS Image Builder, please refer the below documentation.
https://docs.aws.amazon.com/imagebuilder/index.html