How to Install Packer for Machine Image Automation on RHEL 7
Packer, developed by HashiCorp, is an open-source tool that enables you to create identical machine images for multiple platforms from a single source configuration. Whether you are building AMIs for AWS, OVA files for VMware, or disk images for on-premises hypervisors, Packer automates the entire process — dramatically reducing the time spent on golden image maintenance. On Red Hat Enterprise Linux 7, Packer integrates seamlessly into infrastructure automation pipelines and pairs naturally with Terraform for a complete infrastructure-as-code workflow. This guide walks you through downloading and installing Packer on RHEL 7, writing your first HCL2 template, working with builders and provisioners, and connecting Packer-built artifacts to Terraform.
Prerequisites
- RHEL 7 server or workstation with sudo or root access
- Active internet connection to reach HashiCorp releases
unzipinstalled:yum install -y unzip- Optional: AWS CLI configured if you plan to use the
amazon-ebsbuilder - Optional: VirtualBox installed if you plan to use the
virtualbox-isobuilder - Terraform installed if you plan to consume Packer artifacts downstream
Step 1: Download the Packer Binary from HashiCorp
HashiCorp distributes Packer as a single pre-compiled binary. Visit the HashiCorp releases page or use curl to download the appropriate Linux AMD64 archive directly to your RHEL 7 machine.
# Check the latest stable version on the releases page, then substitute below.
# Example using Packer 1.10.3
PACKER_VERSION="1.10.3"
curl -fsSL "https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_linux_amd64.zip"
-o /tmp/packer.zip
# Verify the checksum
curl -fsSL "https://releases.hashicorp.com/packer/${PACKER_VERSION}/packer_${PACKER_VERSION}_SHA256SUMS"
-o /tmp/packer_SHA256SUMS
sha256sum -c /tmp/packer_SHA256SUMS --ignore-missing
You should see output like packer_1.10.3_linux_amd64.zip: OK. If the checksum fails, re-download the archive; do not proceed with a corrupted binary.
Step 2: Install Packer and Configure PATH
Extract the binary and place it in a directory that is on your system PATH. /usr/local/bin is the conventional location for locally installed binaries on RHEL 7.
unzip /tmp/packer.zip -d /tmp/packer_extract
sudo mv /tmp/packer_extract/packer /usr/local/bin/packer
sudo chmod +x /usr/local/bin/packer
# Confirm the installation
packer --version
Expected output:
1.10.3
If you receive a command not found error, verify that /usr/local/bin is included in your PATH:
echo $PATH
# If missing, add it permanently:
echo 'export PATH=$PATH:/usr/local/bin' >> ~/.bash_profile
source ~/.bash_profile
Step 3: Initialize a Packer Project with HCL2
Packer historically used JSON templates, but the modern approach — and the format used in all new documentation — is HCL2 (HashiCorp Configuration Language version 2), which uses .pkr.hcl file extensions. HCL2 offers variable interpolation, reusable modules, and much more readable syntax.
Create a working directory for your first Packer project:
mkdir ~/packer-demo && cd ~/packer-demo
Create the main template file:
cat > build.pkr.hcl <<'EOF'
packer {
required_plugins {
amazon = {
version = ">= 1.3.0"
source = "github.com/hashicorp/amazon"
}
}
}
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "base_ami" {
type = string
default = "ami-0c02fb55956c7d316" # RHEL 7 HVM in us-east-1 (example)
}
source "amazon-ebs" "rhel7_base" {
region = var.aws_region
source_ami = var.base_ami
instance_type = "t3.micro"
ssh_username = "ec2-user"
ami_name = "rhel7-golden-{{timestamp}}"
ami_description = "RHEL 7 golden image built with Packer"
tags = {
Builder = "Packer"
Environment = "production"
}
}
build {
name = "rhel7-ami"
sources = ["source.amazon-ebs.rhel7_base"]
provisioner "shell" {
inline = [
"sudo yum update -y",
"sudo yum install -y wget curl git vim",
"sudo systemctl enable firewalld",
"sudo systemctl start firewalld"
]
}
}
EOF
Step 4: Working with the VirtualBox Builder
If you need a local virtualbox-iso image rather than an AWS AMI, the configuration differs slightly. This builder boots a VM from an ISO, installs the OS automatically via a Kickstart or Preseed file, and then runs provisioners.
cat > virtualbox.pkr.hcl <<'EOF'
source "virtualbox-iso" "rhel7_local" {
iso_url = "http://mirror.example.com/rhel-server-7.9-x86_64-dvd.iso"
iso_checksum = "sha256:your_iso_sha256_here"
vm_name = "rhel7-base"
guest_os_type = "RedHat_64"
disk_size = 20480
memory = 2048
cpus = 2
headless = true
boot_command = [
" inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg"
]
http_directory = "http"
shutdown_command = "sudo /sbin/halt -h -p"
ssh_username = "vagrant"
ssh_password = "vagrant"
ssh_timeout = "30m"
output_directory = "output-rhel7"
format = "ova"
}
build {
sources = ["source.virtualbox-iso.rhel7_local"]
provisioner "shell" {
script = "scripts/provision.sh"
}
}
EOF
Step 5: Using Ansible as a Provisioner
Shell scripts work well for simple provisioning, but Ansible offers idempotency, roles, and a much richer module ecosystem. Packer includes a built-in Ansible provisioner.
# Install Ansible on the machine running Packer
sudo yum install -y epel-release
sudo yum install -y ansible
# Update the build block in your .pkr.hcl to use ansible:
# provisioner "ansible" {
# playbook_file = "./playbooks/site.yml"
# user = "ec2-user"
# use_proxy = false
# extra_arguments = ["--extra-vars", "env=production"]
# }
Create a minimal playbook at playbooks/site.yml:
---
- hosts: all
become: yes
tasks:
- name: Ensure useful packages are installed
yum:
name:
- vim
- wget
- curl
- net-tools
state: present
- name: Enable and start firewalld
systemctl:
name: firewalld
enabled: yes
state: started
Step 6: Initialize Plugins and Run a Build
Before running a build that uses external plugins (such as the Amazon plugin), you must initialize the project so Packer can download the required plugin binaries:
cd ~/packer-demo
packer init .
Validate the template syntax before executing a full build:
packer validate build.pkr.hcl
Run the actual build:
packer build build.pkr.hcl
# Pass variable overrides at the command line:
packer build -var "aws_region=eu-west-1" build.pkr.hcl
# Use a variables file:
packer build -var-file="prod.pkrvars.hcl" build.pkr.hcl
Packer will output progress for each step: booting the instance, running SSH, executing provisioners, creating the AMI snapshot, and finally printing the artifact ID.
Step 7: Inspecting Built Artifacts
After a successful build, Packer logs the artifact identifiers. For the Amazon EBS builder, this is the AMI ID. You can also use the Packer inspect subcommand to examine template metadata without running a build:
# Inspect a template to see sources, builds, and variables
packer inspect build.pkr.hcl
# Sample output:
# Packer Inspect: HCL2 config
#
# Sources:
# amazon-ebs.rhel7_base
#
# Builds:
# rhel7-ami
# sources: amazon-ebs.rhel7_base
# provisioners: shell
# After a build, Packer writes a manifest if you add the manifest post-processor:
# post-processor "manifest" {
# output = "packer-manifest.json"
# }
cat packer-manifest.json
Step 8: Integrating Packer Artifacts with Terraform
A common pattern is to build AMIs with Packer and then reference them in Terraform configurations using the aws_ami data source, ensuring your infrastructure always uses the latest golden image.
# In your Terraform configuration (main.tf):
data "aws_ami" "rhel7_golden" {
most_recent = true
owners = ["self"]
filter {
name = "name"
values = ["rhel7-golden-*"]
}
filter {
name = "tag:Builder"
values = ["Packer"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.rhel7_golden.id
instance_type = "t3.medium"
tags = {
Name = "web-server"
}
}
This approach decouples image building from infrastructure provisioning. Packer runs in CI/CD to produce a fresh AMI on every approved OS update, while Terraform always picks up the newest artifact automatically.
Conclusion
Packer transforms machine image creation from a manual, error-prone task into a reproducible, version-controlled process. On RHEL 7, you can leverage Packer to build AWS AMIs, VirtualBox OVAs, and other artifact formats using the same HCL2 template with different source blocks. By combining shell and Ansible provisioners, you can enforce a consistent software baseline across all images. The integration with Terraform closes the loop on the infrastructure-as-code lifecycle — Packer owns image creation, Terraform owns deployment. As a next step, consider adding Packer builds to your Jenkins or GitLab CI pipeline so that every merge to your infrastructure repository triggers a fresh golden image build automatically.