Building a custom AMI with Packer
RunsOn provides base images (AMIs) for your workflows, which are regularly updated ↗.
In some cases though, you might want to generate a new AMI from one of those base images, and use it in your workflows.
This can be useful if you want to:
- prepopulate the AMI with your own software, docker images, data, etc.
- fulfill advanced compliancy requirements, with a stable image that you control.
An easy way to do this is to regularly rebuild your own AMI from the base images with Packer.
Manifest file
In this example we will generate a new AMI for arm64.
packer { required_plugins { amazon = { source = "github.com/hashicorp/amazon" version = "~> 1" } }}
variable "subnet_id" { type = string}
variable "region" { type = string}
variable "ami_prefix" { type = string}
data "amazon-ami" "runs-on-ami" { filters = { name = "runs-on-v2.2-ubuntu22-full-arm64-*" root-device-type = "ebs" virtualization-type = "hvm" } most_recent = true owners = ["135269210855"] region = "${var.region}"}
source "amazon-ebs" "build-ebs" { ami_name = "${var.ami_prefix}-runs-on-${formatdate("YYYY-MM-DD-hhmmss", timestamp())}" instance_type = "t4g.small" region = "${var.region}" source_ami = "${data.amazon-ami.runs-on-ami.id}" ssh_username = "ubuntu" subnet_id = "${var.subnet_id}" user_data_file = "./scripts/user_data.sh"}
build { sources = ["source.amazon-ebs.build-ebs"]
provisioner "shell" { script = "./scripts/provision.sh" }}
User data file
A user-data is required to start the SSH daemon, otherwise Packer can’t connect to the instance to perform the provisioning.
In the example this would be a file in scripts/user_data.sh
:
#!/bin/bashsystemctl start ssh
Provisioning file
The provisioning file is where you put your scripts to install software, run commands, etc.
In the example this would be a file in scripts/provision.sh
:
#!/bin/bashset -eapt-get updateapt-get install -y software1 software2
Building the image
Initialize Packer:
packer init custom-ami-arm64.pkr.hcl
Then build the image:
packer build -var "ami_prefix=MY_COMPANY" -var "subnet_id=your-subnet-id" -var "region=us-east-1" custom-ami-arm64.pkr.hcl
After some time you should get a new AMI registered into your AWS account, and you can start using it by referencing the AMI ID or name in your workflows.
See the documentation on custom images for more details.