Merge pull request #17 from ajschroeder/develop

feat: add Ubuntu 25.04
This commit is contained in:
TheHitman1977
2025-10-21 20:24:45 -05:00
committed by GitHub
13 changed files with 898 additions and 13 deletions

View File

@@ -39,6 +39,7 @@ The following builds are available:
| Rocky Linux | 10 | ✓ | ✓ | ✓ | ✓ | | Rocky Linux | 10 | ✓ | ✓ | ✓ | ✓ |
| Rocky Linux | 9 | ✓ | ✓ | ✓ | ✓ | | Rocky Linux | 9 | ✓ | ✓ | ✓ | ✓ |
| Rocky Linux | 8 | ✓ | ✓ | ✓ | ✓ | | Rocky Linux | 8 | ✓ | ✓ | ✓ | ✓ |
| Ubuntu Server | 25.04 | ✓ | ✓ | ✓ | ✓ |
| Ubuntu Server | 24.04 LTS | ✓ | ✓ | ✓ | ✓ | | Ubuntu Server | 24.04 LTS | ✓ | ✓ | ✓ | ✓ |
| Ubuntu Server | 22.04 LTS | ✓ | ✓ | ✓ | ✓ | | Ubuntu Server | 22.04 LTS | ✓ | ✓ | ✓ | ✓ |
| Ubuntu Server | 20.04 LTS | ✓ | ✓ | ✓ | ✓ | | Ubuntu Server | 20.04 LTS | ✓ | ✓ | ✓ | ✓ |
@@ -188,8 +189,8 @@ Operating systems and versions tested with the project:
After installing the required software, the quickest way to get building is to clone this repository. After installing the required software, the quickest way to get building is to clone this repository.
```shell ```shell
git clone https://github.com/ajschroeder/packer-examples-for-proxmox.git git clone https://github.com/ajschroeder/proxmox-packer-examples.git
cd packer-examples-for-proxmox cd proxmox-packer-examples
``` ```
The following table describes the directory structure. The following table describes the directory structure.

View File

@@ -567,6 +567,43 @@ menu_option_14() {
} }
menu_option_15() { menu_option_15() {
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/25-04/
BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"}
BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl"
echo -e "\nCONFIRM: Build a Ubuntu Server 25.04 Template for Proxmox?"
echo -e "\nContinue? (y/n)"
read -r REPLY
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
exit 1
fi
### Build a Ubuntu Server 25.04 Template for Proxmox. ###
echo "Building a Ubuntu Server 25.04 Template for Proxmox..."
### Initialize HashiCorp Packer and required plugins. ###
echo "Initializing HashiCorp Packer and required plugins..."
packer init "$INPUT_PATH"
### Start the Build. ###
echo "Starting the build...."
echo "packer build -force -on-error=ask $debug_option"
packer build -force -on-error=ask $debug_option \
-var-file="$CONFIG_PATH/ansible.pkrvars.hcl" \
-var-file="$CONFIG_PATH/build.pkrvars.hcl" \
-var-file="$CONFIG_PATH/common.pkrvars.hcl" \
-var-file="$CONFIG_PATH/linux-storage.pkrvars.hcl" \
-var-file="$CONFIG_PATH/network.pkrvars.hcl" \
-var-file="$CONFIG_PATH/proxmox.pkrvars.hcl" \
-var-file="$CONFIG_PATH/$BUILD_VARS" \
"$INPUT_PATH"
### All done. ###
echo "Done."
}
menu_option_16() {
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/24-04-lts/ INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/24-04-lts/
BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"} BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"}
BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl" BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl"
@@ -603,7 +640,8 @@ menu_option_15() {
echo "Done." echo "Done."
} }
menu_option_16() {
menu_option_17() {
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/22-04-lts/ INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/22-04-lts/
BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"} BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"}
BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl" BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl"
@@ -640,7 +678,7 @@ menu_option_16() {
echo "Done." echo "Done."
} }
menu_option_17() { menu_option_18() {
INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/20-04-lts/ INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/20-04-lts/
BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"} BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"}
BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl" BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl"
@@ -677,7 +715,7 @@ menu_option_17() {
echo "Done." echo "Done."
} }
menu_option_18() { menu_option_19() {
INPUT_PATH="$SCRIPT_PATH"/builds/windows/desktop/11/ INPUT_PATH="$SCRIPT_PATH"/builds/windows/desktop/11/
BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"} BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"}
BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl" BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl"
@@ -713,7 +751,7 @@ menu_option_18() {
echo "Done." echo "Done."
} }
menu_option_19() { menu_option_20() {
INPUT_PATH="$SCRIPT_PATH"/builds/windows/desktop/11/ INPUT_PATH="$SCRIPT_PATH"/builds/windows/desktop/11/
BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"} BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"}
BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl" BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl"
@@ -750,7 +788,7 @@ menu_option_19() {
echo "Done." echo "Done."
} }
menu_option_20() { menu_option_21() {
INPUT_PATH="$SCRIPT_PATH"/builds/windows/desktop/11/ INPUT_PATH="$SCRIPT_PATH"/builds/windows/desktop/11/
BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"} BUILD_PATH=${INPUT_PATH#"${SCRIPT_PATH}/builds/"}
BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl" BUILD_VARS="$(echo "${BUILD_PATH%/}" | tr -s '/' | tr '/' '-').pkrvars.hcl"
@@ -810,6 +848,8 @@ until [ "$selection" = "0" ]; do
echo "" echo ""
echo " ____ __ ____ " echo " ____ __ ____ "
echo " / __ \ ____ _ _____ / /__ ___ _____ / __ \ _____ ____ _ __ ____ ___ ____ _ __ " echo " / __ \ ____ _ _____ / /__ ___ _____ / __ \ _____ ____ _ __ ____ ___ ____ _ __ "
# Don't want to expand this non-expression, it's just ANSI art
# shellcheck disable=SC2016
echo ' / /_/ // __ `// ___// //_// _ \ / ___/ / /_/ // ___// __ \ | |/_// __ `__ \ / __ \ | |/_/ ' echo ' / /_/ // __ `// ___// //_// _ \ / ___/ / /_/ // ___// __ \ | |/_// __ `__ \ / __ \ | |/_/ '
echo " / ____// /_/ // /__ / ,< / __// / / ____// / / /_/ /_> < / / / / / // /_/ /_> < " echo " / ____// /_/ // /__ / ,< / __// / / ____// / / /_/ /_> < / / / / / // /_/ /_> < "
echo '/_/ \__,_/ \___//_/|_| \___//_/ /_/ /_/ \____//_/|_|/_/ /_/ /_/ \____//_/|_| ' echo '/_/ \__,_/ \___//_/|_| \___//_/ /_/ /_/ \____//_/|_|/_/ /_/ /_/ \____//_/|_| '
@@ -833,12 +873,13 @@ until [ "$selection" = "0" ]; do
echo " 12 - Rocky Linux 10" echo " 12 - Rocky Linux 10"
echo " 13 - Rocky Linux 9" echo " 13 - Rocky Linux 9"
echo " 14 - Rocky Linux 8" echo " 14 - Rocky Linux 8"
echo " 15 - Ubuntu Server 24.04 LTS" echo " 15 - Ubuntu Server 25.04"
echo " 16 - Ubuntu Server 22.04 LTS" echo " 16 - Ubuntu Server 24.04 LTS"
echo " 17 - Ubuntu Server 20.04 LTS" echo " 17 - Ubuntu Server 22.04 LTS"
echo " 18 - Windows 11 - All" echo " 18 - Ubuntu Server 20.04 LTS"
echo " 19 - Windows 11 - Enterprise Only" echo " 19 - Windows 11 - All"
echo " 20 - Windows 11 - Professional Only" echo " 20 - Windows 11 - Enterprise Only"
echo " 21 - Windows 11 - Professional Only"
echo "" echo ""
echo " Other:" echo " Other:"
echo "" echo ""
@@ -868,6 +909,7 @@ until [ "$selection" = "0" ]; do
18) clear ; menu_option_18 ; press_enter ;; 18) clear ; menu_option_18 ; press_enter ;;
19) clear ; menu_option_19 ; press_enter ;; 19) clear ; menu_option_19 ; press_enter ;;
20) clear ; menu_option_20 ; press_enter ;; 20) clear ; menu_option_20 ; press_enter ;;
21) clear ; menu_option_21 ; press_enter ;;
[Ii] ) clear ; info ; press_enter ;; [Ii] ) clear ; info ; press_enter ;;
[Qq] ) clear ; exit ;; [Qq] ) clear ; exit ;;
* ) clear ; incorrect_selection ; press_enter ;; * ) clear ; incorrect_selection ; press_enter ;;

View File

View File

@@ -0,0 +1,19 @@
network:
network:
version: 2
ethernets:
%{ if ip != null ~}
${device}:
dhcp4: false
addresses:
- ${ip}/${netmask}
gateway4: ${gateway}
nameservers:
addresses:
%{ for item in dns ~}
- ${item}
%{ endfor ~}
%{ else ~}
${device}:
dhcp4: true
%{ endif ~}

View File

@@ -0,0 +1,113 @@
%{~ if length(partitions) == 1 && partitions[0].name == "autopart" ~}
%{~ if partitions[0].format.fstype == "lvm" ~}
storage:
layout:
name: lvm
%{~ endif ~}
%{~ if partitions[0].format.fstype == "simple" ~}
storage:
layout:
name: direct
%{~ endif ~}
%{~ if partitions[0].format.fstype == "" ~}
storage:
layout:
name: direct
%{~ endif ~}
%{~ else ~}
storage:
config:
- ptable: gpt
path: /dev/${device}
wipe: superblock
preserve: false
%{ if vm_bios == "seabios" ~}
grub_device: true
%{ endif ~}
type: disk
id: disk-${device}
%{if vm_bios == "seabios" ~}
- device: disk-${device}
size: 1M
flag: bios_grub
number: 1
preserve: false
type: partition
id: partition-grub
%{ endif ~}
%{ for index, partition in partitions ~}
- device: disk-${device}
%{ if partition.size != -1 ~}
size: ${partition.size}M
%{ else ~}
size: ${partition.size}
%{ endif ~}
wipe: superblock
preserve: false
%{ if partition.mount.path == "/boot" && vm_bios == "seabios" && index == 0 ~}
flag: bios_grub
grub_device: false
%{ endif ~}
%{ if partition.mount.path == "/boot/efi" && index == 0 ~}
flag: boot
grub_device: true
%{ endif ~}
type: partition
id: partition-${partition.name}
%{ if partition.format.fstype != "" ~}
- id: format-${partition.name}
type: format
volume: partition-${partition.name}
label: ${partition.format.label}
fstype: ${partition.format.fstype}
%{ endif ~}
%{ if partition.volume_group == "" && partition.name != "bios_grub" ~}
- id: mount-${partition.name}
type: mount
%{ if partition.mount.path == "" ~}
path: none
%{ else ~}
path: ${partition.mount.path}
%{ endif ~}
device: format-${partition.name}
%{ if partition.mount.options != "" ~}
options: ${partition.mount.options}
%{ endif ~}
%{ endif ~}
%{ endfor ~}
%{ for index, volume_group in lvm ~}
- id: volgroup-${volume_group.name}
type: lvm_volgroup
name: ${volume_group.name}
devices:
%{ for index, partition in partitions ~}
%{ if lookup(partition, "volume_group", "") == volume_group.name ~}
- partition-${partition.name}
%{ endif ~}
%{ endfor ~}
%{ for index, partition in volume_group.partitions ~}
- id: partition-${partition.name}
type: lvm_partition
name: ${partition.name}
size: ${partition.size}M
volgroup: volgroup-${volume_group.name}
- id: format-${partition.name}
type: format
volume: partition-${partition.name}
label: ${partition.format.label}
fstype: ${partition.format.fstype}
- id: mount-${partition.name}
type: mount
%{ if partition.mount.path == "" ~}
path: none
%{ else ~}
path: ${partition.mount.path}
%{ endif ~}
device: format-${partition.name}
%{ if partition.mount.options != "" ~}
options: ${partition.mount.options}
%{ endif ~}
%{ endfor ~}
%{ endfor ~}
%{~ endif ~}

View File

@@ -0,0 +1,29 @@
#cloud-config
autoinstall:
version: 1
early-commands:
- sudo systemctl stop ssh
locale: ${vm_os_language}
keyboard:
layout: ${vm_os_keyboard}
${storage}
${network}
identity:
hostname: ubuntu-server
username: ${build_username}
password: ${build_password_encrypted}
ssh:
install-server: true
allow-pw: true
packages:
- openssh-server
- cloud-init
user-data:
disable_root: false
timezone: ${vm_os_timezone}
late-commands:
- sed -i -e 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /target/etc/ssh/sshd_config
- echo '${build_username} ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/${build_username}
- curtin in-target --target=/target -- chmod 440 /etc/sudoers.d/${build_username}
- curtin in-target -- apt-get update
- curtin in-target -- apt-get install -y qemu-guest-agent

View File

@@ -0,0 +1,237 @@
/*
DESCRIPTION:
Ubuntu Server 25.04 LTS template using the Packer Builder for Proxmox (proxmox-iso).
*/
// BLOCK: packer
// The Packer configuration.
packer {
required_version = ">= 1.12.0"
required_plugins {
ansible = {
source = "github.com/hashicorp/ansible"
version = "~> 1"
}
git = {
version = ">= 0.6.2"
source = "github.com/ethanmdavidson/git"
}
proxmox = {
version = "= 1.2.1"
source = "github.com/hashicorp/proxmox"
}
}
}
// BLOCK: data
// Defines the data sources.
data "git-repository" "cwd" {}
// BLOCK: locals
// Defines the local variables.
locals {
bios_boot_command = [
"c<wait5>",
"linux /casper/vmlinuz --- autoinstall ${local.data_source_command}",
"<enter><wait10>",
"initrd /casper/initrd",
"<enter><wait10>",
"boot",
"<enter>"
]
uefi_boot_command = [
// This waits for 3 seconds, sends the "c" key, and then waits for another 3 seconds. In the GRUB boot loader, this is used to enter command line mode.
"<wait3s>c<wait3s>",
// This types a command to load the Linux kernel from the specified path with the 'autoinstall' option and the value of the 'data_source_command' local variable.
// The 'autoinstall' option is used to automate the installation process.
// The 'data_source_command' local variable is used to specify the kickstart data source configured in the common variables.
"linux /casper/vmlinuz --- autoinstall ${local.data_source_command}",
// This sends the "enter" key and then waits. This is typically used to execute the command and give the system time to process it.
"<enter><wait>",
// This types a command to load the initial RAM disk from the specified path.
"initrd /casper/initrd",
// This sends the "enter" key and then waits. This is typically used to execute the command and give the system time to process it.
"<enter><wait>",
// This types the "boot" command. This starts the boot process using the loaded kernel and initial RAM disk.
"boot",
// This sends the "enter" key. This is typically used to execute the command.
"<enter>"
]
build_by = "Built by: HashiCorp Packer ${packer.version}"
build_date = formatdate("DD-MM-YYYY hh:mm ZZZ", "${timestamp()}" )
build_version = data.git-repository.cwd.head
build_description = "Version: ${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}\nCloud-Init: ${var.vm_cloudinit}"
vm_disk_type = var.vm_disk_type == "virtio" ? "vda" : "sda"
manifest_date = formatdate("YYYY-MM-DD hh:mm:ss", timestamp())
manifest_path = "${path.cwd}/manifests/"
manifest_output = "${local.manifest_path}${local.manifest_date}.json"
data_source_content = {
"/meta-data" = file("${abspath(path.root)}/data/meta-data")
"/user-data" = templatefile("${abspath(path.root)}/data/user-data.pkrtpl.hcl", {
build_username = var.build_username
build_password = var.build_password
build_password_encrypted = var.build_password_encrypted
vm_disk_type = local.vm_disk_type
vm_os_language = var.vm_os_language
vm_os_keyboard = var.vm_os_keyboard
vm_os_timezone = var.vm_os_timezone
network = templatefile("${abspath(path.root)}/data/network.pkrtpl.hcl", {
device = var.vm_network_device
ip = var.vm_ip_address
netmask = var.vm_ip_netmask
gateway = var.vm_ip_gateway
dns = var.vm_dns_list
})
storage = templatefile("${abspath(path.root)}/data/storage.pkrtpl.hcl", {
device = var.vm_disk_device
swap = var.vm_disk_use_swap
partitions = var.vm_disk_partitions
lvm = var.vm_disk_lvm
vm_bios = var.vm_bios
})
additional_packages = var.additional_packages
})
}
data_source_command = var.common_data_source == "http" ? "ds=\"nocloud-net;seedfrom=http://{{.HTTPIP}}:{{.HTTPPort}}/\"" : "ds=\"nocloud\""
vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}"
boot_command = var.vm_bios == "ovmf" ? local.uefi_boot_command : local.bios_boot_command
vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null
}
// BLOCK: source
// Defines the builder configuration blocks.
source "proxmox-iso" "ubuntu" {
// Proxmox Connection Settings and Credentials
proxmox_url = "https://${var.proxmox_hostname}:8006/api2/json"
username = "${var.proxmox_api_token_id}"
token = "${var.proxmox_api_token_secret}"
insecure_skip_tls_verify = "${var.proxmox_insecure_connection}"
// Proxmox Settings
node = "${var.proxmox_node}"
// Virtual Machine Settings
vm_name = "${local.vm_name}"
bios = "${var.vm_bios}"
sockets = "${var.vm_cpu_sockets}"
cores = "${var.vm_cpu_count}"
cpu_type = "${var.vm_cpu_type}"
memory = "${var.vm_mem_size}"
os = "${var.vm_os_type}"
scsi_controller = "${var.vm_disk_controller_type}"
disks {
disk_size = "${var.vm_disk_size}"
type = "${var.vm_disk_type}"
storage_pool = "${var.vm_storage_pool}"
format = "${var.vm_disk_format}"
}
dynamic "efi_config" {
for_each = var.vm_bios == "ovmf" ? [1] : []
content {
efi_storage_pool = var.vm_bios == "ovmf" ? var.vm_efi_storage_pool : null
efi_type = var.vm_bios == "ovmf" ? var.vm_efi_type : null
pre_enrolled_keys = var.vm_bios == "ovmf" ? var.vm_efi_pre_enrolled_keys : null
}
}
ssh_username = "${var.build_username}"
ssh_password = "${var.build_password}"
ssh_timeout = "${var.timeout}"
ssh_port = "22"
qemu_agent = true
network_adapters {
bridge = "${var.vm_bridge_interface}"
model = "${var.vm_network_card_model}"
vlan_tag = "${var.vm_vlan_tag}"
}
// Removable Media Settings
http_content = "${var.common_data_source}" == "http" ? "${local.data_source_content}" : null
// Boot and Provisioning Settings
http_interface = var.common_data_source == "http" ? var.common_http_interface : null
http_bind_address = var.common_data_source == "http" ? var.common_http_bind_address : null
http_port_min = var.common_data_source == "http" ? var.common_http_port_min : null
http_port_max = var.common_data_source == "http" ? var.common_http_port_max : null
boot = var.vm_boot
boot_wait = var.vm_boot_wait
boot_command = local.boot_command
boot_iso {
iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}"
unmount = true
iso_checksum = "${var.iso_checksum}"
}
dynamic "additional_iso_files" {
for_each = var.common_data_source == "disk" ? [1] : []
content {
cd_files = var.common_data_source == "disk" ? local.data_source_content : null
cd_label = var.common_data_source == "disk" ? "cidata" : null
iso_storage_pool = var.common_data_source == "disk" ? "local" : null
}
}
template_name = "${local.vm_name}"
template_description = "${local.build_description}"
# VM Cloud Init Settings
cloud_init = var.vm_cloudinit
cloud_init_storage_pool = var.vm_cloudinit == true ? var.vm_storage_pool : null
}
# Build Definition to create the VM Template
build {
sources = ["source.proxmox-iso.ubuntu"]
provisioner "ansible" {
user = var.build_username
galaxy_file = "${path.cwd}/ansible/linux-requirements.yml"
galaxy_force_with_deps = true
playbook_file = "${path.cwd}/ansible/linux-playbook.yml"
roles_path = "${path.cwd}/ansible/roles"
ansible_env_vars = [
"ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg",
"ANSIBLE_PYTHON_INTERPRETER=/usr/bin/python3"
]
extra_arguments = [
"--extra-vars", "display_skipped_hosts=false",
"--extra-vars", "build_username=${var.build_username}",
"--extra-vars", "build_key='${var.build_key}'",
"--extra-vars", "ansible_username=${var.ansible_username}",
"--extra-vars", "ansible_key='${var.ansible_key}'",
"--extra-vars", "enable_cloudinit='${var.vm_cloudinit}'",
]
}
post-processor "manifest" {
output = local.manifest_output
strip_path = true
strip_time = true
custom_data = {
ansible_username = "${var.ansible_username}"
build_username = "${var.build_username}"
build_date = "${local.build_date}"
build_version = "${local.build_version}"
common_data_source = "${var.common_data_source}"
vm_cpu_sockets = "${var.vm_cpu_sockets}"
vm_cpu_count = "${var.vm_cpu_count}"
vm_disk_size = "${var.vm_disk_size}"
vm_bios = "${var.vm_bios}"
vm_os_type = "${var.vm_os_type}"
vm_mem_size = "${var.vm_mem_size}"
vm_network_card_model = "${var.vm_network_card_model}"
vm_cloudinit = "${var.vm_cloudinit}"
}
}
}

View File

@@ -0,0 +1,40 @@
/*
DESCRIPTION:
Ubuntu Server 25.04 LTS variables used by the Packer Plugin for Proxmox (proxmox-iso).
*/
// Guest Operating System Metadata
vm_os_language = "en_US"
vm_os_keyboard = "us"
vm_os_timezone = "UTC"
vm_os_family = "linux"
vm_os_name = "ubuntu"
vm_os_version = "25.04-lts"
// Virtual Machine Guest Operating System Setting
vm_os_type = "l26"
vm_cloudinit = true
// Virtual Machine Hardware Settings
vm_bios = "ovmf"
vm_cpu_count = 1
vm_cpu_sockets = 1
vm_cpu_type = "x86-64-v3"
vm_mem_size = 2048
vm_disk_type = "virtio"
vm_disk_size = "32G"
vm_disk_format = "raw"
vm_disk_controller_type = "virtio-scsi-pci"
vm_network_card_model = "virtio"
// Removable Media Settings
iso_path = "iso"
iso_file = "ubuntu-25.04-live-server-amd64.iso"
iso_checksum = "https://releases.ubuntu.com/plucky/SHA256SUMS"
// Boot Settings
vm_boot = "order=virtio0;ide2;net0"
vm_boot_wait = "5s"
// EFI Settings
vm_firmware_path = "./OVMF.fd"

View File

@@ -0,0 +1,36 @@
/*
DESCRIPTION:
Ubuntu 25.04 LTS network variables used by the Packer Plugin for Proxmox (proxmox-iso).
*/
// VM Network Settings
variable "vm_network_device" {
type = string
description = "The network device of the VM."
default = "ens18"
}
variable "vm_ip_address" {
type = string
description = "The IP address of the VM (e.g. 172.16.100.192)."
default = null
}
variable "vm_ip_netmask" {
type = number
description = "The netmask of the VM (e.g. 24)."
default = null
}
variable "vm_ip_gateway" {
type = string
description = "The gateway of the VM (e.g. 172.16.100.1)."
default = null
}
variable "vm_dns_list" {
type = list(string)
description = "The nameservers of the VM."
default = []
}

View File

@@ -0,0 +1,53 @@
/*
DESCRIPTION:
Ubuntu Server 25.04 LTS storage variables used by the Packer Plugin for Proxmox (proxmox-iso).
*/
// VM Storage Settings
variable "vm_disk_device" {
type = string
description = "The device for the virtual disk. (e.g. 'sda')"
}
variable "vm_disk_use_swap" {
type = bool
description = "Whether to use a swap partition."
}
variable "vm_disk_partitions" {
type = list(object({
name = string
size = number
format = object({
label = string
fstype = string
})
mount = object({
path = string
options = string
})
volume_group = string
}))
description = "The disk partitions for the virtual disk."
}
variable "vm_disk_lvm" {
type = list(object({
name = string
partitions = list(object({
name = string
size = number
format = object({
label = string
fstype = string
})
mount = object({
path = string
options = string
})
}))
}))
description = "The LVM configuration for the virtual disk."
default = []
}

View File

@@ -0,0 +1,313 @@
/*
DESCRIPTION:
Ubuntu Server 25.04 LTS variables using the Packer Builder for Proxmox (proxmox-iso).
*/
// BLOCK: variable
// Defines the input variables.
// Proxmox Credentials
variable "proxmox_hostname" {
type = string
description = "The FQDN or IP address of a Proxmox node. Only one node should be specified in a cluster."
}
variable "proxmox_api_token_id" {
type = string
description = "The token to login to the Proxmox node/cluster. The format is USER@REALM!TOKENID. (e.g. packer@pam!packer_pve_token)"
}
variable "proxmox_api_token_secret" {
type = string
description = "The secret for the API token used to login to the Proxmox API."
# sensitive = true
}
variable "proxmox_insecure_connection" {
description = "true/false to skip Proxmox TLS certificate checks."
type = bool
default = true
}
// Proxmox Settings
variable "proxmox_node" {
type = string
description = "The name of the Proxmox node that Packer will build templates on."
}
// Virtual Machine Settings
variable "vm_os_language" {
type = string
description = "The guest operating system language."
default = "en_US"
}
variable "vm_os_keyboard" {
type = string
description = "The guest operating system keyboard layout."
default = "us"
}
variable "vm_os_timezone" {
type = string
description = "The guest operating system timezone."
default = "UTC"
}
variable "vm_os_family" {
type = string
description = "The guest operating system family. Used for naming. (e.g. 'linux')"
}
variable "vm_os_name" {
type = string
description = "The guest operating system name. Used for naming. (e.g. 'ubuntu')"
}
variable "vm_os_version" {
type = string
description = "The guest operating system version. Used for naming. (e.g. '22-04-lts')"
}
variable "vm_os_type" {
type = string
description = "The guest operating system type. (e.g. 'l26')"
}
variable "vm_bios" {
type = string
description = "The firmware type. Allowed values 'ovmf' or 'seabios'"
default = "ovmf"
validation {
condition = contains(["ovmf", "seabios"], var.vm_bios)
error_message = "The vm_bios value must be 'ovmf' or 'seabios'."
}
}
variable "vm_firmware_path" {
type = string
description = "The firmware file to be used. Needed for EFI"
default = "/usr/share/ovmf/OVMF.fd"
}
variable "vm_efi_storage_pool" {
type = string
description = "Set the UEFI disk storage location. (e.g. 'local-lvm')"
default = "local-lvm"
}
variable "vm_efi_type" {
type = string
description = "Specifies the version of the OVMF firmware to be used. (e.g. '4m')"
default = "4m"
}
variable "vm_efi_pre_enrolled_keys" {
type = bool
description = "Whether Microsoft Standard Secure Boot keys should be pre-loaded on the EFI disk. (e.g. false)"
default = false
}
variable "vm_cpu_count" {
type = number
description = "The number of virtual CPUs. (e.g. '2')"
}
variable "vm_cpu_sockets" {
type = number
description = "The number of virtual CPU sockets. (e.g. '1')"
}
variable "vm_cpu_type" {
type = string
description = "The CPU type to emulate. See the Proxmox API documentation for the complete list of accepted values. For best performance, set this to host. Defaults to kvm64."
}
variable "vm_mem_size" {
type = number
description = "The size for the virtual memory in MB. (e.g. '2048')"
}
variable "vm_disk_controller_type" {
type = string
description = "The SCSI controller model to emulate. (e.g. 'virtio-scsi-pci')"
}
variable "vm_disk_type" {
type = string
description = "The type of disk to emulate. (e.g. 'virtio')"
}
variable "vm_storage_pool" {
type = string
description = "The name of the Proxmox storage pool to store the VM template. (e.g. 'local-lvm')"
}
variable "vm_disk_size" {
type = string
description = "The size for the virtual disk in GB. (e.g. '32G')"
}
variable "vm_disk_format" {
type = string
description = "The format of the file backing the disk. (e.g. 'qcow2')"
}
variable "vm_network_card_model" {
type = string
description = "The model of the virtual network adapter to emulate. (e.g. 'virtio')"
}
variable "vm_bridge_interface" {
type = string
description = "The name of the Proxmox bridge to attach the adapter to."
}
variable "vm_vlan_tag" {
type = string
description = "If the adapter should tag packets, give the VLAN ID. (e.g. '102')"
}
// Cloud-Init Settings
variable "vm_cloudinit" {
type = bool
description = "Enable or disable cloud-init drive in Proxmox. (e.g. false)"
default = false
}
// Removable Media Settings
variable "common_iso_storage" {
type = string
description = "The name of the source Proxmox storage location for ISO images. (e.g. 'local-lvm')"
}
variable "iso_path" {
type = string
description = "The path on the source Proxmox storage location for ISO images. (e.g. 'iso')"
}
variable "iso_file" {
type = string
description = "The file name of the ISO image used by the vendor. (e.g. 'ubuntu-<version>-live-server-amd64.iso')"
}
variable "iso_checksum" {
type = string
description = "The checksum value of the ISO image provided by the vendor."
}
// Boot Settings
variable "common_data_source" {
type = string
description = "The provisioning data source. (e.g. 'http' or 'disk')"
}
variable "common_http_bind_address" {
type = string
description = "Define an IP address on the host to use for the HTTP server."
default = null
}
variable "common_http_interface" {
type = string
description = "Name of the network interface that Packer gets HTTPIP from. Defaults to the first non loopback interface."
default = null
}
variable "common_http_port_min" {
type = number
description = "The start of the HTTP port range."
}
variable "common_http_port_max" {
type = number
description = "The end of the HTTP port range."
}
variable "vm_boot" {
type = string
description = "The boot order for virtual machine devices. (e.g. 'order=virtio0;ide2;net0')"
}
variable "vm_boot_wait" {
type = string
description = "The time to wait after booting the initial VM before typing the boot_command (e.g '10s')"
}
variable "common_ip_wait_timeout" {
type = string
description = "Time to wait for guest operating system IP address response."
}
variable "common_shutdown_timeout" {
type = string
description = "Time to wait for guest operating system shutdown."
}
// Communicator Settings and Credentials
variable "build_username" {
type = string
description = "The username to login to the guest operating system. (e.g. 'ubuntu')"
# sensitive = true
}
variable "build_password" {
type = string
description = "The password to login to the guest operating system."
# sensitive = true
}
variable "build_password_encrypted" {
type = string
description = "The encrypted password to login to the guest operating system."
# sensitive = true
}
variable "build_key" {
type = string
description = "The SSH public key to login to the guest operating system."
# sensitive = true
}
variable "timeout" {
description = "not sure why I need so high a timeout but here we are"
default = "90m"
}
// Ansible Credentials
variable "ansible_username" {
type = string
description = "The username for Ansible to login to the guest operating system. (e.g. 'ansible')"
# sensitive = true
}
variable "ansible_key" {
type = string
description = "The public key for Ansible to login to the guest operating system."
# sensitive = true
}
// HCP Packer Settings
variable "common_hcp_packer_registry_enabled" {
type = bool
description = "Enable the HCP Packer registry."
default = false
}
// Additional Settings
variable "additional_packages" {
type = list(string)
description = "Additional packages to install."
default = []
}

View File

@@ -1,3 +1,4 @@
# shellcheck shell=sh
follow_link() { follow_link() {
FILE="$1" FILE="$1"
while [ -h "$FILE" ]; do while [ -h "$FILE" ]; do

View File

@@ -30,6 +30,7 @@ INPUT_PATHS=(
"$SCRIPT_PATH/builds/linux/rocky/10/" "$SCRIPT_PATH/builds/linux/rocky/10/"
"$SCRIPT_PATH/builds/linux/rocky/9/" "$SCRIPT_PATH/builds/linux/rocky/9/"
"$SCRIPT_PATH/builds/linux/rocky/8/" "$SCRIPT_PATH/builds/linux/rocky/8/"
"$SCRIPT_PATH/builds/linux/ubuntu/25-04/"
"$SCRIPT_PATH/builds/linux/ubuntu/24-04-lts/" "$SCRIPT_PATH/builds/linux/ubuntu/24-04-lts/"
"$SCRIPT_PATH/builds/linux/ubuntu/22-04-lts/" "$SCRIPT_PATH/builds/linux/ubuntu/22-04-lts/"
"$SCRIPT_PATH/builds/linux/ubuntu/20-04-lts/" "$SCRIPT_PATH/builds/linux/ubuntu/20-04-lts/"