AlmaLinux OS Cloud Images is a project that contains Packer templates and other tools for building AlmaLinux OS images for various cloud platforms.
Make sure the required Packer plugins are installed and the latest:
packer init -upgrade .
x86_64
BIOS only (Default):
packer build -only=qemu.almalinux-8-gencloud-x86_64 .
x86_64
UEFI only:
See: How to build UEFI and Secure Boot supported Images
packer build -only=qemu.almalinux-8-gencloud-uefi-x86_64 .
AArch64
:
packer build -only=qemu.almalinux-8-gencloud-aarch64 .
ppc64le
:
packer build -only=qemu.almalinux-8-gencloud-ppc64le .
x86_64
BIOS+UEFI (Default):
See: How to build UEFI and Secure Boot supported Images
packer build -only=qemu.almalinux-9-gencloud-x86_64 .
x86_64
BIOS only:
packer build -only=qemu.almalinux-9-gencloud-bios-x86_64 .
AArch64
:
packer build -only=qemu.almalinux-9-gencloud-aarch64 .
ppc64le
:
packer build -only=qemu.almalinux-9-gencloud-ppc64le .
Both AlmaLinux OS 8 and 9 cloud images supports Generation 1 and Generation 2 VMs.
See: How to build UEFI and Secure Boot supported Images
x86_64
BIOS + UEFI:
packer build -only=qemu.almalinux-8-azure-x86_64 .
x86_64
BIOS + UEFI:
See: How to build UEFI and Secure Boot supported Images
packer build -only=qemu.almalinux-9-azure-x86_64 .
See https://www.packer.io/plugins/builders/amazon#authentication for instructions.
Note: Use aws_profile
Packer input variable if you configured multiple profiles on the shared credentials file.
us-east-1
.The us-east-1
is set as a default region of:
aws_source_ami_9_x86_64
, aws_source_ami_9_aarch64
, aws_source_ami_8_x86_64
, aws_source_ami_8_aarch64
.aws_ami_region
aws_ami_regions
You can get the ID of source AMI using one of these methods:
AlmaLinux Wiki:
Latest AMIs are published on: https://wiki.almalinux.org/cloud/AWS.html#community-amis
AWS Console:
On the page of EC2 service, click on AMIs on the left panel. Select filter as "Public Images" and paste this Owner = 764336703387
.
AWS CLI:
Replace the $REGION
with yours. e.g. us-west-1
:
AlmaLinux OS 8:
aws ec2 describe-images --owners 764336703387 --query 'sort_by(Images, &CreationDate)[*].[CreationDate,Name,ImageId]' --filters "Name=name,Values=AlmaLinux OS 8*" --region $REGION --output table
AlmaLinux OS 9:
aws ec2 describe-images --owners 764336703387 --query 'sort_by(Images, &CreationDate)[*].[CreationDate,Name,ImageId]' --filters "Name=name,Values=AlmaLinux OS 9*" --region $REGION --output table
Use the one of the methods listed below to set input variables:
Command line option
packer build \
-var='aws_source_ami_9_x86_64=ami-1234567890abcdef0' \
-var='aws_ami_region=us-west-1' \
-var='aws_ami_regions=["us-west-1"]' \
-only=amazon-ebssurrogate.almalinux_9_ami_x86_64 .
Variable definition file
Auto-loaded with .auto.pkrvars.hcl
file extension:
foo.auto.pkrvars.hcl
aws_source_ami_9_x86_64 = "ami-1234567890abcdef0"
aws_ami_region = "us-west-1"
aws_ami_regions = ["us-west-1"]
Standard definition with .pkrvars.hcl
ending:
packer build -var-file="foo.pkrvars.hcl" -only=amazon-ebssurrogate.almalinux_9_ami_x86_64 .
Environment Variables
export PKR_VAR_aws_source_ami_9_x86_64='ami-1234567890abcdef0'
export PKR_VAR_aws_ami_region='us-west-1'
export PKR_VAR_aws_ami_regions='["us-west-1"]'
packer build -only=amazon-ebssurrogate.almalinux_9_ami_x86_64 .
or
PKR_VAR_aws_source_ami_9_x86_64='ami-1234567890abcdef0' PKR_VAR_aws_ami_region='us-west-1' PKR_VAR_aws_ami_regions='["us-west-1"]' packer build -only=amazon-ebssurrogate.almalinux_9_ami_x86_64 .
x86_64
:
packer build -only=amazon-ebssurrogate.almalinux_8_ami_x86_64 .
AArch64
:
packer build -only=amazon-ebssurrogate.almalinux_8_ami_aarch64 .
x86_64
:
packer build -only=amazon-ebssurrogate.almalinux_9_ami_x86_64 .
AArch64
:
packer build -only=amazon-ebssurrogate.almalinux_9_ami_aarch64 .
These input variables can be used for the cutomization of AMIs:
aws_volume_type
aws_volume_size
You can also speed-up the build time with upgrading the instance type for builder EC2 Instances:
t3.small
): aws_instance_type_x86_64
t4g.small
): aws_instance_type_aarch64
Note: Only Nitro based EC2 instances are supported as a builder.
For any customization inside the AMI, import your custom ansible playbook after the "Install AWS Guest Tools" task on ansible/roles/ami_[8-9]_(x86_64|aarch64)/tasks/main.yaml
.
Libvirt x86_64
BIOS only:
packer build -only=qemu.almalinux-8 .
Libvirt x86_64
UEFI only:
See:
packer build -only=qemu.almalinux-8-uefi .
VirtualBox x86_64
:
packer build -only=virtualbox-iso.almalinux-8 .
VMware Desktop x86_64
:
packer build -only=vmware-iso.almalinux-8 .
Parallels x86_64
:
packer build -only=parallels-iso.almalinux-8 .
Hyper-V x86_64
:
packer build -only="hyperv-iso.almalinux-8" .
With custom Virtual Switch:
packer build -var hyperv_switch_name="HyperV-vSwitch" -only="hyperv-iso.almalinux-8" .
Libvirt x86_64
BIOS + UEFI:
See:
packer build -only=qemu.almalinux-9 .
VirtualBox x86_64
:
packer build -only=virtualbox-iso.almalinux-9 .
VMware Desktop x86_64
:
packer build -only=vmware-iso.almalinux-9 .
VMware Desktop aarch64
:
packer build -only=vmware-iso.almalinux-9-aarch64 .
Note: At this time, VMWare Fusion desktop, Apple M1 processor expects additional config settings to run
vagrant box built for aarch64. It's behavior of VMWare Fusion, not an issue of AlmaLinux OS.
Vagrant.configure("2") do |config|
config.vm.box = "almalinux/9.aarch64"
config.vm.box_version = "9.1.20230122"
config.vm.provider "vmware_desktop" do |v|
v.gui = true
v.vmx["ethernet0.virtualdev"] = "vmxnet3"
end
end
Parallels x86_64
:
packer build -only=parallels-iso.almalinux-9 .
Parallels aarch64
:
packer build -only=parallels-iso.almalinux-9-aarch64 .
Hyper-V x86_64
:
packer build -only="hyperv-iso.almalinux-9" .
With custom Virtual Switch:
packer build -var hyperv_switch_name="HyperV-vSwitch" -only="hyperv-iso.almalinux-9" .
x86_64
BIOS only:
packer build -only=qemu.almalinux-8-opennebula-x86_64 .
AArch64
:
packer build -only=qemu.almalinux-8-opennebula-aarch64 .
x86_64
BIOS + UEFI (Default)
packer build -only=qemu.almalinux-9-opennebula-x86_64 .
x86_64
BIOS only:
packer builder -only=qemu.almalinux-9-opennebula-bios-x86_64 .
AArch64
:
packer build -only=qemu.almalinux-9-opennebula-aarch64 .
Update the Oracle Cloud Agent RPM link if a newer version is available
ansible/roles/oci_guest/defaults/main.yml
x86_64
UEFI only (Default):
packer build -only=qemu.almalinux-8-oci-uefi-x86_64 .
x86_64
BIOS only:
packer build -only=qemu.almalinux-8-oci-x86_64 .
AArch64
:
packer build -only=qemu.almalinux-8-oci-aarch64 .
x86_64
BIOS + UEFI (Default):
packer build -only=qemu.almalinux-9-oci-x86_64 .
x86_64
BIOS only:
packer build -only=qemu.almalinux-9-oci-bios-x86_64 .
AArch64
packer build -only=qemu.almalinux-9-oci-aarch64 .
You need to setup a key for packer to use. This is done by going to DigitalOcean's cloud console.
Make it available through an environment variable:
export DIGITALOCEAN_API_TOKEN="ENTER_YOUR_ACCESS_TOKEN_HERE"
A space needs to be created in order to import the image through it. Please, read the relevant documentation. Take note of the access and secret keys in order to use them later on.
There are a few environment variables you will need to make available.
DIGITALOCEAN_SPACE_NAME
.DIGITALOCEAN_SPACES_ACCESS_KEY
.DIGITALOCEAN_SPACES_SECRET_KEY
.You can do this by exporting them as well:
export DIGITALOCEAN_SPACE_NAME='YOUR_SPACES_BUCKET_NAME'
export DIGITALOCEAN_SPACES_ACCESS_KEY='YOUR_BUCKET_ACCESS_KEY'
export DIGITALOCEAN_SPACES_SECRET_KEY='YOUR_BUCKET_SECRET_KEY'
Now, you're all setup. You can try building the image with:
x86_64
BIOS only:
packer build -only qemu.almalinux-8-digitalocean-x86_64 .
x86_64
BIOS only:
packer build -only qemu.almalinux-9-digitalocean-x86_64 .
Import the image to DigitalOcean:
You can upload your image or Import it via URL from the GitHub release section.
In Images >> Custom Images section, click on Import via URL
and enter the URL of image file : https://github.com/AlmaLinux/cloud-images/releases/download/digitalocean-20210810/almalinux-8-DigitalOcean-8.4.20210810.x86_64.qcow2
You need a 1.0.7
or newer version of the QEMU packer plugin and OVMF to build UEFI images.
The ovmf_code
and ovmf_vars
Packer variables are set to default OVMF Secure Boot paths for the EL and Fedora. Use the table below for the OVMF package name and the firmware paths for your distro.
Distro | Package | ovmf_code |
ovmf_code |
---|---|---|---|
Arch Linux | edk2-ovmf |
/usr/share/OVMF/OVMF_CODE.secboot.fd |
/usr/share/OVMF/OVMF_VARS.fd |
Debian and derivatives | ovmf |
/usr/share/OVMF/OVMF_CODE.secboot.fd |
/usr/share/OVMF/OVMF_VARS.ms.fd |
Gentoo | edk2-ovmf |
/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd |
/usr/share/edk2-ovmf/OVMF_VARS.secboot.fd |
OpenSUSE | qemu-ovmf-x86_64 |
/usr/share/qemu/ovmf-x86_64-smm-ms-code.bin |
/usr/share/qemu/ovmf-x86_64-smm-ms-vars.bin |
If your distro is not present in the table above or you want to build in different combinations like without Secure Boot, with AMD SEV or Intel TDX, check QEMU firmware metadata files in /usr/share/qemu/firmware
for the correct paths and combinations.
EL:
packer build -var qemu_binary="/usr/libexec/qemu-kvm" -only=qemu.almalinux-9-gencloud-x86_64 .
Fedora:
packer build -only=qemu.almalinux-8-azure-x86_64 .
Debian and derivatives:
packer build -var ovmf_code="/usr/share/OVMF/OVMF_CODE.secboot.fd" -var ovmf_vars="/usr/share/OVMF/OVMF_VARS.ms.fd" -only=qemu.almalinux-8-gencloud-uefi-x86_64 .
or set the ovmf_code
and ovmf_vars
Packer variables in .auto.pkrvars.hcl
file:
uefi.auto.pkrvars.hcl
in OpenSUSE:
ovmf_code = "/usr/share/qemu/ovmf-x86_64-smm-ms-code.bin"
ovmf_vars = "/usr/share/qemu/ovmf-x86_64-smm-ms-vars.bin"
Libvirt:
AlmaLinux OS 8 - almalinux/8.uefi UEFI only
AlmaLinux OS 9 almalinux/9 BIOS + UEFI
Copy the OVMF NVRAM file:
cp /usr/share/OVMF/OVMF_VARS.secboot.fd OVMF_VARS.secboot_almalinux-uefi.fd
Set these values:
libvirt.loader
- Location of OVMF_CODElibvirt.nvram
- Copied OVMF_VARS filelibvirt.machine_type = "q35"
Example Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "almalinux/8.uefi"
config.vm.hostname = "almalinux8-uefi.test"
config.vm.provider "libvirt" do |libvirt|
libvirt.qemu_use_session = false
libvirt.memory = 2048
libvirt.loader = "/usr/share/OVMF/OVMF_CODE.secboot.fd"
libvirt.nvram = "OVMF_VARS.secboot_almalinux-uefi.fd"
libvirt.machine_type = "q35"
end
end
Load the KVM-HV kernel module
modprobe kvm_hv
Verify that the KVM kernel module is loaded
lsmod | grep kvm
If KVM loaded successfully, the output of this command includes kvm_hv
.
The external packer plugins don't have the ppc64le
builds yet, So use internal packer plugins.
mv versions.pkr.hcl versions.pkr.hcl.ignore
>= 1.7.0
>= 2.12
x86_64
ones and all AArch64
images)The cracklib-dicts's /usr/sbin/packer
takes precedence over Hashicorp's /usr/bin/packer
in the $PATH
.
Use packer.io
instead of the packer
. See: https://learn.hashicorp.com/tutorials/packer/get-started-install-cli#troubleshooting
ln -s /usr/bin/packer /usr/bin/packer.io
Output:
Failed creating Qemu driver: exec: "qemu-system-x86_64": executable file not found in $PATH
By default, Packer looks for QEMU binary as qemu-system-x86_64
. If it is different in your system, You can set your qemu binary with the qemu_binary
Packer variable.
on EL, it's /usr/libexec/qemu-kvm
:
packer build -var qemu_binary="/usr/libexec/qemu-kvm" -only=qemu.almalinux-8-gencloud-x86_64 .
or set the qemu_binary
Packer variable in .auto.pkrvars.hcl
file:
qemu_on_el.auto.pkrvars.hcl
qemu_binary = "/usr/libexec/qemu-kvm"
On AlmaLinux OS 8, Debian 11 (bullseye) and Ubuntu 20.04 LTS (Focal Fossa), comment "ANSIBLE_SCP_EXTRA_ARGS=-O"
Ansible variable:
sed -i 's/.*\("ANSIBLE_SCP_EXTRA_ARGS=-O"\).*/# \1/g' almalinux*.pkr.hcl
Error output:
fatal: [default]: FAILED! => {"msg": "failed to transfer file to /home/vagrant/.ansible/tmp/ansible-local-3759yjc1ghcz/tmpzo9a3_vb/grub.conf.j2 /tmp/ansible-tmp-1715955434.1781824-3861-34379722779259/source:\n\nunknown option -- O\r\nusage: scp [-346BCpqrTv] [-c cipher] [-F ssh_config] [-i identity_file]\n [-J destination] [-l limit] [-o ssh_option] [-P port]\n [-S program] source ... target\n"}
FIXED: Starting with the 1.1.0
version, ECDSA
keypair is generated and used by default instead of RSA
.
To upgrade the plugin and disable SHA1:
packer init -upgrade .
update-crypto-policies --set DEFAULT
Error output:
fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "Data could not be sent to remote host \"127.0.0.1\". Make sure this host can be reached over ssh: ssh_dispatch_run_fatal: Connection to 127.0.0.1 port 43729: error in libcrypto\r\n", "unreachable": true}
Enable the SHA1
on the system's default crypto policy until Packer's Ansible Plugin use a stronger key types and signature algorithms(rsa-sha2-256
,rsa-sha2-512
, ecdsa-sha2-nistp256
, ssh-ed25519
) than ssh-rsa
.
Fedora and EL:
update-crypto-policies --set DEFAULT:SHA1
EL8:
See:
EL9:
See: