Automated Custom AMI Baking with Packer

Sagar Veeranna Shiva
NEW IT Engineering
Published in
4 min readMar 24, 2024

In cloud environments like AWS, having the ability to create tailored AMIs to fit specific requirements is crucial. These custom AMIs often contain specialized software configurations, security measures, and optimizations that streamline deployment processes. By crafting custom AMIs, organizations can ensure consistency, security, and efficiency across their AWS deployments.

Why Bake Custom AMIs?

Creating custom AMIs offers numerous benefits, including:

  • Consistency: Custom AMIs provide a consistent environment for your applications, ensuring that each instance is identical and eliminating configuration drift.
  • Security: By pre-configuring security settings and applying patches to the base image, custom AMIs enhance the security posture of your infrastructure.
  • Efficiency: Custom AMIs reduce the time required to deploy new instances by including pre-installed software packages and configurations, enabling faster scaling and provisioning.

Introduction to Packer

Packer is a tool developed by HashiCorp that enables the automated creation of machine images across multiple platforms, including AWS. With Packer, users can define image configurations using a variety of formats, including HCL (HashiCorp Configuration Language) and JSON. Packer’s approach to infrastructure as code allows for consistent and repeatable image builds, reducing manual intervention and ensuring reliability in the deployment process.

Writing Packer Configuration in HCL Format

Packer configurations are typically written in HCL (HashiCorp Configuration Language) or JSON format. Here’s an example of a Packer configuration in HCL format:

# packer.hcl
packer {
required_plugins {
amazon = {
version = ">= 0.0.2"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "ubuntu" {
ami_name = "custom-ubuntu-ami-{{timestamp}}"
instance_type = "t2.micro"
source_ami_filter {
filters = {
name = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["099720109477"]
}
}
build {
sources = ["source.amazon-ebs.ubuntu2204"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y <package1> <package2>"
]
}
}

Automating with Jenkins Pipeline

Jenkins is a popular open-source automation server that facilitates the continuous integration and delivery (CI/CD) of software projects. In our case, we’ll leverage Jenkins pipelines to automate the creation of custom Ubuntu AMIs using Packer.

pipeline {
agent any

environment {
AWS_ACCESS_KEY_ID = credentials('aws-access-key-id')
AWS_SECRET_ACCESS_KEY = credentials('aws-secret-access-key')
}

stages {
stage('Checkout Repository') {
steps {
git 'https://github.com/yourusername/your-repository.git'
}
}

stage('Initialize Packer') {
steps {
dir('path/to/packer/hcl') {
sh 'packer init packer.hcl'
}
}
}

stage('Build AMI') {
steps {
dir('path/to/packer/hcl') {
sh 'packer build packer.hcl'
}
}
}
}
}

Workflow

  1. Jenkins Trigger: Utilizing a simple cron expression, Jenkins can initiate builds on a predefined schedule, offering flexibility and control over your project’s execution flow.
  2. Docker Agent: As previously discussed, a custom-built Docker container can serve as a Jenkins agent, containing the preinstalled Packer CLI.
  3. Checkout Repository: The Jenkins pipeline begins by checking out the repository containing the Packer configuration file (packer.hcl) and any additional required resources.
  4. Initialize Packer: Packer is initialized within the directory containing the packer.hcl file to ensure access to all necessary resources and plugins.
  5. Build AMI: The pipeline executes the “packer build” command, triggering the creation of an EC2 instance from a base Ubuntu AMI.
  6. Execute Provisioners: Provisioning tasks specified in packer.hcl, such as installing software packages and configuring security settings, are executed.
  7. Create AMI: Upon completion of provisioners, an AMI is created and pushed to AWS.
  8. Exit: The temporary EC2 instance created for building purposes is destroyed after the successful creation of the AMI.

By the end of this process, the Jenkins pipeline will have successfully created a custom Ubuntu AMI tailored to the specifications defined in the Packer configuration file. This AMI can then be used to deploy instances in AWS, providing a consistent and reliable foundation for your applications.

Conclusion

Baking a custom Ubuntu AMI for AWS using Packer and automating it with Jenkins offers unparalleled flexibility and control over your infrastructure. By defining your AMI configuration as code and automating the build process, you ensure consistency and efficiency in your deployments.

This custom process empowers users to tailor their infrastructure to specific requirements, whether it’s pre-installing software dependencies, configuring security measures, or optimizing performance settings.

So, why settle for generic solutions when you can craft custom AMIs tailored to your needs? Start baking your custom AMIs today!

References

--

--

Sagar Veeranna Shiva
NEW IT Engineering

Senior Devops Engineer, AWS certified developer associate, interested in DevOps, IoT, and Robotics