diff --git a/build.sh b/build.sh index 8126713..52ae17f 100755 --- a/build.sh +++ b/build.sh @@ -132,6 +132,68 @@ menu_option_4() { } menu_option_5() { + INPUT_PATH="$SCRIPT_PATH"/builds/linux/rocky/8/ + echo -e "\nCONFIRM: Build a Rocky Linux 8 Template for Proxmox?" + echo -e "\nContinue? (y/n)" + read -r REPLY + if [[ ! $REPLY =~ ^[Yy]$ ]] + then + exit 1 + fi + + ### Build a Rocky Linux 8 for Proxmox. ### + echo "Building a Rocky Linux 8 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...." + packer build -force \ + -var-file="$CONFIG_PATH/proxmox.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/build.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/ansible.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/common.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/linux-storage.pkrvars.hcl" \ + "$INPUT_PATH" + + ### All done. ### + echo "Done." +} + +menu_option_6() { + INPUT_PATH="$SCRIPT_PATH"/builds/linux/rocky/9/ + echo -e "\nCONFIRM: Build a Rocky Linux 9 Template for Proxmox?" + echo -e "\nContinue? (y/n)" + read -r REPLY + if [[ ! $REPLY =~ ^[Yy]$ ]] + then + exit 1 + fi + + ### Build a Rocky Linux 9 for Proxmox. ### + echo "Building a Rocky Linux 9 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...." + packer build -force \ + -var-file="$CONFIG_PATH/proxmox.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/build.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/ansible.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/common.pkrvars.hcl" \ + -var-file="$CONFIG_PATH/linux-storage.pkrvars.hcl" \ + "$INPUT_PATH" + + ### All done. ### + echo "Done." +} + +menu_option_7() { INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/20-04-lts/ echo -e "\nCONFIRM: Build a Ubuntu Server 20.04 LTS Template for Proxmox?" echo -e "\nContinue? (y/n)" @@ -162,7 +224,7 @@ menu_option_5() { echo "Done." } -menu_option_6() { +menu_option_8() { INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/20-04-lts/ echo -e "\nCONFIRM: Build a Ubuntu Server 20.04 LTS (cloud-init) Template for Proxmox?" echo -e "\nContinue? (y/n)" @@ -194,7 +256,7 @@ menu_option_6() { echo "Done." } -menu_option_7() { +menu_option_9() { INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/22-04-lts/ echo -e "\nCONFIRM: Build a Ubuntu Server 22.04 LTS Template for Proxmox?" echo -e "\nContinue? (y/n)" @@ -225,7 +287,7 @@ menu_option_7() { echo "Done." } -menu_option_8() { +menu_option_10() { INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/22-04-lts/ echo -e "\nCONFIRM: Build a Ubuntu Server 22.04 LTS (cloud-init) Template for Proxmox?" echo -e "\nContinue? (y/n)" @@ -257,7 +319,7 @@ menu_option_8() { echo "Done." } -menu_option_9() { +menu_option_11() { INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/24-04-lts/ echo -e "\nCONFIRM: Build a Ubuntu Server 24.04 LTS Template for Proxmox?" echo -e "\nContinue? (y/n)" @@ -288,7 +350,7 @@ menu_option_9() { echo "Done." } -menu_option_10() { +menu_option_12() { INPUT_PATH="$SCRIPT_PATH"/builds/linux/ubuntu/24-04-lts/ echo -e "\nCONFIRM: Build a Ubuntu Server 24.04 LTS (cloud-init) Template for Proxmox?" echo -e "\nContinue? (y/n)" @@ -320,7 +382,7 @@ menu_option_10() { echo "Done." } -menu_option_11() { +menu_option_13() { INPUT_PATH="$SCRIPT_PATH"/builds/linux/opensuse/leap-15-5/ echo -e "\nCONFIRM: Build a OpenSUSE Leap 15.5 Template for Proxmox?" echo -e "\nContinue? (y/n)" @@ -387,13 +449,15 @@ until [ "$selection" = "0" ]; do echo " 2 - CentOS 9 Stream" echo " 3 - Debian 11 (Bullseye)" echo " 4 - Debian 12 (Bookworm)" - echo " 5 - Ubuntu Server 20.04 LTS" - echo " 6 - Ubuntu Server 20.04 LTS (cloud-init)" - echo " 7 - Ubuntu Server 22.04 LTS" - echo " 8 - Ubuntu Server 22.04 LTS (cloud-init)" - echo " 9 - Ubuntu Server 24.04 LTS" - echo " 10 - Ubuntu Server 24.04 LTS (cloud-init)" - echo " 11 - OpenSUSE Leap 15.5" + echo " 5 - Rocky Linux 8" + echo " 6 - Rocky Linux 9" + echo " 7 - Ubuntu Server 20.04 LTS" + echo " 8 - Ubuntu Server 20.04 LTS (cloud-init)" + echo " 9 - Ubuntu Server 22.04 LTS" + echo " 10 - Ubuntu Server 22.04 LTS (cloud-init)" + echo " 11 - Ubuntu Server 24.04 LTS" + echo " 12 - Ubuntu Server 24.04 LTS (cloud-init)" + echo " 13 - OpenSUSE Leap 15.5" echo "" echo " Other:" echo "" @@ -414,6 +478,8 @@ until [ "$selection" = "0" ]; do 9 ) clear ; menu_option_9 ; press_enter ;; 10) clear ; menu_option_10 ; press_enter ;; 11) clear ; menu_option_11 ; press_enter ;; + 12) clear ; menu_option_12 ; press_enter ;; + 13) clear ; menu_option_13 ; press_enter ;; [Ii] ) clear ; info ; press_enter ;; [Qq] ) clear ; exit ;; * ) clear ; incorrect_selection ; press_enter ;; diff --git a/builds/linux/rocky/8/data/ks.pkrtpl.hcl b/builds/linux/rocky/8/data/ks.pkrtpl.hcl new file mode 100644 index 0000000..2bdd9c7 --- /dev/null +++ b/builds/linux/rocky/8/data/ks.pkrtpl.hcl @@ -0,0 +1,85 @@ +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# Rocky Linux 8 + +### Installs from the first attached CD-ROM/DVD on the system. +cdrom + +### Performs the kickstart installation in text mode. +### By default, kickstart installations are performed in graphical mode. +text + +### Accepts the End User License Agreement. +eula --agreed + +### Sets the language to use during installation and the default language to use on the installed system. +lang ${vm_os_language} + +### Sets the default keyboard type for the system. +keyboard ${vm_os_keyboard} + +### Configure network information for target system and activate network devices in the installer environment (optional) +### --onboot enable device at a boot time +### --device device to be activated and / or configured with the network command +### --bootproto method to obtain networking configuration for device (default dhcp) +### --noipv6 disable IPv6 on this device +${network} + +### Lock the root account. +rootpw --lock + +### The selected profile will restrict root login. +### Add a user that can login and escalate privileges. +user --name=${build_username} --iscrypted --password=${build_password_encrypted} --groups=wheel + +### Configure firewall settings for the system. +### --enabled reject incoming connections that are not in response to outbound requests +### --ssh allow sshd service through the firewall +firewall --enabled --ssh + +### Sets up the authentication options for the system. +### The SSSD profile sets sha512 to hash passwords. Passwords are shadowed by default +### See the manual page for authselect-profile for a complete list of possible options. +authselect select sssd + +### Sets the state of SELinux on the installed system. +### Defaults to enforcing. +selinux --enforcing + +### Sets the system time zone. +timezone ${vm_os_timezone} + +### Partitioning +${storage} + +### Modifies the default set of services that will run under the default runlevel. +services --enabled=NetworkManager,sshd + +### Do not configure X on the installed system. +skipx + +### Packages selection. +%packages --ignoremissing --excludedocs +@core +-iwl*firmware +%end + +### Post-installation commands. +%post +dnf makecache +dnf install epel-release -y +dnf makecache +dnf install -y sudo qemu-guest-tools +%{ if additional_packages != "" ~} +dnf install -y ${additional_packages} +%{ endif ~} +echo "${build_username} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${build_username} +sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers +%end + +### Reboot after the installation is complete. +### --eject attempt to eject the media before rebooting. +reboot --eject diff --git a/builds/linux/rocky/8/data/network.pkrtpl.hcl b/builds/linux/rocky/8/data/network.pkrtpl.hcl new file mode 100644 index 0000000..a7949a7 --- /dev/null +++ b/builds/linux/rocky/8/data/network.pkrtpl.hcl @@ -0,0 +1,5 @@ +%{ if ip != null ~} +network --device=${device} --bootproto=static --ip=${ip} --netmask=${cidrnetmask("${ip}/${netmask}")} --gateway=${gateway} --nameserver=${join(",", dns)} +%{ else ~} +network --device=${device} --bootproto=dhcp +%{ endif ~} diff --git a/builds/linux/rocky/8/data/storage.pkrtpl.hcl b/builds/linux/rocky/8/data/storage.pkrtpl.hcl new file mode 100644 index 0000000..b35af89 --- /dev/null +++ b/builds/linux/rocky/8/data/storage.pkrtpl.hcl @@ -0,0 +1,73 @@ +### Sets how the boot loader should be installed. +bootloader --location=mbr + +### Initialize any invalid partition tables found on disks. +zerombr + +### Removes partitions from the system, prior to creation of new partitions. +### By default, no partitions are removed. +### --all Erases all partitions from the system +### --initlabel Initializes a disk (or disks) by creating a default disk label for all disks in their respective architecture. +clearpart --all --initlabel + +### Modify partition sizes for the virtual machine hardware. +### Create primary system partitions. +%{ for partition in partitions ~} +part +%{~ if partition.volume_group != "" ~} + pv.${partition.volume_group} +%{~ else ~} +%{~ if partition.format.fstype == "swap" ~} + swap +%{~ else ~} + ${partition.mount.path} +%{~ endif ~} +%{~ if partition.format.fstype != "" ~} + --label=${partition.format.label} +%{~ if partition.format.fstype == "fat32" ~} + --fstype vfat +%{~ else ~} + --fstype ${partition.format.fstype} +%{~ endif ~} +%{~ endif ~} +%{~ endif ~} +%{~ if partition.mount.options != "" ~} + --fsoptions="${partition.mount.options}" +%{~ endif ~} +%{~ if partition.size != -1 ~} + --size=${partition.size} +%{~ else ~} + --size=100 --grow +%{ endif ~} + +%{ endfor ~} +### Create a logical volume management (LVM) group. +%{ for index, volume_group in lvm ~} +volgroup sysvg pv.${volume_group.name} + +### Modify logical volume sizes for the virtual machine hardware. +### Create logical volumes. +%{ for partition in volume_group.partitions ~} +logvol +%{~ if partition.format.fstype == "swap" ~} + swap +%{~ else ~} + ${partition.mount.path} +%{~ endif ~} + --name=${partition.name} --vgname=${volume_group.name} --label=${partition.format.label} +%{~ if partition.format.fstype == "fat32" ~} + --fstype vfat +%{~ else ~} + --fstype ${partition.format.fstype} +%{~ endif ~} +%{~ if partition.mount.options != "" ~} + --fsoptions="${partition.mount.options}" +%{~ endif ~} +%{~ if partition.size != -1 ~} + --size=${partition.size} +%{~ else ~} + --size=100 --grow +%{ endif ~} + +%{ endfor ~} +%{ endfor ~} \ No newline at end of file diff --git a/builds/linux/rocky/8/data/storage.pkrtpl.hcl.orig b/builds/linux/rocky/8/data/storage.pkrtpl.hcl.orig new file mode 100644 index 0000000..d048cf0 --- /dev/null +++ b/builds/linux/rocky/8/data/storage.pkrtpl.hcl.orig @@ -0,0 +1,66 @@ +### Sets how the boot loader should be installed. +bootloader --location=mbr + +### Initialize any invalid partition tables found on disks. +zerombr + +### Removes partitions from the system, prior to creation of new partitions. +### By default, no partitions are removed. +### --all Erases all partitions from the system +### --initlabel Initializes a disk (or disks) by creating a default disk label for all disks in their respective architecture. +clearpart --all --initlabel + +### Modify partition sizes for the virtual machine hardware. +### Create primary system partitions. +%{ if length(partitions) == 1 && partitions[0].name == "autopart" ~} + %{ if partitions[0].format.fstype == "lvm" ~} +autopart --type=lvm + %{ endif } + %{ if partitions[0].format.fstype == "simple" ~} +autopart --type=plain + %{ endif } + %{ if partitions[0].format.fstype == "" ~} +autopart --type=plain + %{ endif } +%{ else } + %{ for partition in partitions ~} + %{ if partition.format.fstype == "swap" ~} +part swap --size=${partition.size} + + %{ endif ~} + %{ if partition.mount.path == "/boot/efi" ~} +part ${partition.mount.path} --fstype vfat --size=${partition.size} --label=${partition.format.label} + + %{ endif ~} + %{ if partition.mount.path != "" ~} +part ${partition.mount.path} --fstype ${partition.format.fstype} --size=${partition.size} --label=${partition.format.label} %{~ if partition.mount.options != "" ~}--fsoptions="${partition.mount.options}"%{~ endif ~} + + %{ endif ~} + %{ if partition.volume_group != "" ~} + %{ if partition.size == -1 ~} +part pv.${partition.volume_group} --size=100 --grow + + %{ else ~} +part pv.${partition.volume_group} --size=${partition.size} + + %{ endif ~} +### Create a logical volume management (LVM) group. +### Modify logical volume sizes for the virtual machine hardware. + %{ for index, volume_group in lvm ~} + %{ if partition.volume_group != "" ~} +volgroup ${volume_group.name} --pesize=4096 pv.${partition.volume_group} + + %{ endif ~} +### Create logical volumes. + %{ for partition in volume_group.partitions ~} + %{ if partition.format.fstype == "swap" ~} +logvol swap --fstype ${partition.format.fstype} --name=${partition.name} --vgname=${volume_group.name} --size=${partition.size} --label=${partition.format.label} + %{ else ~} +logvol ${partition.mount.path} %{ if partition.format.fstype == "fat32" } --fstype vfat %{ else } --fstype ${partition.format.fstype} %{ endif } %{ if partition.size != -1 } --size=${partition.size} %{ else } --size=100 --grow %{ endif } --name=${partition.name} --vgname=${volume_group.name} --label=${partition.format.label} %{ if partition.mount.options != "" ~} --fsoptions="${partition.mount.options}" %{~ endif ~} + + %{ endif ~} + %{ endfor ~} + %{ endfor ~} + %{ endif ~} + %{ endfor ~} +%{ endif } diff --git a/builds/linux/rocky/8/linux-rocky.auto.pkrvars.hcl b/builds/linux/rocky/8/linux-rocky.auto.pkrvars.hcl new file mode 100644 index 0000000..8d649e6 --- /dev/null +++ b/builds/linux/rocky/8/linux-rocky.auto.pkrvars.hcl @@ -0,0 +1,45 @@ +/* + DESCRIPTION: + Rocky Linux 8 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 = "rocky" +vm_os_version = "8" + +// Virtual Machine Guest Operating System Setting +vm_os_type = "l26" + +// Virtual Machine Hardware Settings +vm_bios = "seabios" +vm_cpu_count = 1 +vm_cpu_sockets = 1 +vm_cpu_type = "kvm64" +vm_mem_size = 2048 +vm_disk_type = "virtio" +vm_disk_size = "32G" +vm_disk_format = "raw" +vm_storage_pool = "vm-data" +vm_disk_controller_type = "virtio-scsi-pci" +vm_network_card_model = "virtio" +vm_bridge_interface = "vmbr0" +vm_vlan_tag = "102" + +// Removable Media Settings +iso_path = "iso" +iso_file = "Rocky-8.10-x86_64-dvd1.iso" +iso_checksum = "file:https://download.rockylinux.org/pub/rocky/8/isos/x86_64/CHECKSUM" + +// Boot Settings +vm_boot = "order=virtio0;ide2;net0" +vm_boot_wait = "10s" + +// EFI Settings +vm_firmware_path = "./OVMF.fd" +vm_efi_storage_pool = "vm-data" +vm_efi_pre_enrolled_keys = false +vm_efi_type = "4m" diff --git a/builds/linux/rocky/8/linux-rocky.pkr.hcl b/builds/linux/rocky/8/linux-rocky.pkr.hcl new file mode 100644 index 0000000..9a21856 --- /dev/null +++ b/builds/linux/rocky/8/linux-rocky.pkr.hcl @@ -0,0 +1,204 @@ +/* + DESCRIPTION: + Rocky Linux 8 template using the Packer Builder for Proxmox (proxmox-iso). +*/ + +// BLOCK: packer +// The Packer configuration. + +packer { + required_version = ">= 1.9.1" + required_plugins { + ansible = { + source = "github.com/hashicorp/ansible" + version = "~> 1" + } + git = { + version = ">= 0.4.2" + source = "github.com/ethanmdavidson/git" + } + proxmox = { + version = ">= 1.0.6" + source = "github.com/hashicorp/proxmox" + } + } +} + +// BLOCK: data +// Defines the data sources. + +data "git-repository" "cwd" {} + +// BLOCK: locals +// Defines the local variables. + +locals { + 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_cloud_init_enable}" + 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 = { + "/ks.cfg" = templatefile("${abspath(path.root)}/data/ks.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_bridge_interface + ip = var.vm_ip_address + netmask = var.vm_ip_netmask + gateway = var.vm_ip_gateway + dns = var.vm_dns_list + }) + common_data_source = var.common_data_source + # lvm needs to be here so late commands can access vg names + lvm = var.vm_disk_lvm + 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 = join(" ", var.additional_packages) + }) + } + data_source_command = var.common_data_source == "http" ? "inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg" : "inst.ks=/cdrom/ks.cfg" + vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}" + vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null +} + +// BLOCK: source +// Defines the builder configuration blocks. + +source "proxmox-iso" "linux-rocky" { + + // 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 + } + } + unmount_iso = true + ssh_username = "${var.build_username}" + ssh_password = "${var.build_password}" + ssh_timeout = "${var.timeout}" + ssh_port = "22" + iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}" + iso_checksum = "${var.iso_checksum}" + 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_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 = [ + "", + "", + " text ${local.data_source_command}", + "" + ] + + 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_cloud_init_enable + cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null + +} + +# Build Definition to create the VM Template +build { + sources = ["source.proxmox-iso.linux-rocky"] + + provisioner "ansible" { + user = "${var.build_username}" + playbook_file = "${path.cwd}/ansible/main.yml" + roles_path = "${path.cwd}/ansible/roles" + ansible_env_vars = [ + "ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg" + ] + extra_arguments = [ + "--extra-vars", "display_skipped_hosts=false", + "--extra-vars", "BUILD_USERNAME=${var.build_username}", + "--extra-vars", "BUILD_SECRET='${var.build_key}'", + "--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}", + "--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'", + ] + } + + 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_cloud_init_enable = "${var.vm_cloud_init_enable}" + } + } +} diff --git a/builds/linux/rocky/8/variables-network.pkr.hcl b/builds/linux/rocky/8/variables-network.pkr.hcl new file mode 100644 index 0000000..84b081f --- /dev/null +++ b/builds/linux/rocky/8/variables-network.pkr.hcl @@ -0,0 +1,36 @@ +/* + DESCRIPTION: + Rocky Linux 8 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 = "ens192" +} + +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 = [] +} diff --git a/builds/linux/rocky/8/variables-storage.pkr.hcl b/builds/linux/rocky/8/variables-storage.pkr.hcl new file mode 100644 index 0000000..daf1f52 --- /dev/null +++ b/builds/linux/rocky/8/variables-storage.pkr.hcl @@ -0,0 +1,53 @@ +/* + DESCRIPTION: + Rocky Linux 8 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 = [] +} diff --git a/builds/linux/rocky/8/variables.pkr.hcl b/builds/linux/rocky/8/variables.pkr.hcl new file mode 100644 index 0000000..ded878b --- /dev/null +++ b/builds/linux/rocky/8/variables.pkr.hcl @@ -0,0 +1,304 @@ +/* + DESCRIPTION: + Rocky Linux 8 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')" +} + +variable "vm_efi_type" { + type = string + description = "Specifies the version of the OVMF firmware to be used. (e.g. '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)" +} + +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_cloud_init_enable" { + 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--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_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 = [] +} diff --git a/builds/linux/rocky/9/data/ks.pkrtpl.hcl b/builds/linux/rocky/9/data/ks.pkrtpl.hcl new file mode 100644 index 0000000..93e36e2 --- /dev/null +++ b/builds/linux/rocky/9/data/ks.pkrtpl.hcl @@ -0,0 +1,85 @@ +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# Rocky Linux 9 + +### Installs from the first attached CD-ROM/DVD on the system. +cdrom + +### Performs the kickstart installation in text mode. +### By default, kickstart installations are performed in graphical mode. +text + +### Accepts the End User License Agreement. +eula --agreed + +### Sets the language to use during installation and the default language to use on the installed system. +lang ${vm_os_language} + +### Sets the default keyboard type for the system. +keyboard ${vm_os_keyboard} + +### Configure network information for target system and activate network devices in the installer environment (optional) +### --onboot enable device at a boot time +### --device device to be activated and / or configured with the network command +### --bootproto method to obtain networking configuration for device (default dhcp) +### --noipv6 disable IPv6 on this device +${network} + +### Lock the root account. +rootpw --lock + +### The selected profile will restrict root login. +### Add a user that can login and escalate privileges. +user --name=${build_username} --iscrypted --password=${build_password_encrypted} --groups=wheel + +### Configure firewall settings for the system. +### --enabled reject incoming connections that are not in response to outbound requests +### --ssh allow sshd service through the firewall +firewall --enabled --ssh + +### Sets up the authentication options for the system. +### The SSSD profile sets sha512 to hash passwords. Passwords are shadowed by default +### See the manual page for authselect-profile for a complete list of possible options. +authselect select sssd + +### Sets the state of SELinux on the installed system. +### Defaults to enforcing. +selinux --enforcing + +### Sets the system time zone. +timezone ${vm_os_timezone} + +### Partitioning +${storage} + +### Modifies the default set of services that will run under the default runlevel. +services --enabled=NetworkManager,sshd + +### Do not configure X on the installed system. +skipx + +### Packages selection. +%packages --ignoremissing --excludedocs +@core +-iwl*firmware +%end + +### Post-installation commands. +%post +dnf makecache +dnf install epel-release -y +dnf makecache +dnf install -y sudo qemu-guest-tools +%{ if additional_packages != "" ~} +dnf install -y ${additional_packages} +%{ endif ~} +echo "${build_username} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${build_username} +sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers +%end + +### Reboot after the installation is complete. +### --eject attempt to eject the media before rebooting. +reboot --eject diff --git a/builds/linux/rocky/9/data/network.pkrtpl.hcl b/builds/linux/rocky/9/data/network.pkrtpl.hcl new file mode 100644 index 0000000..a7949a7 --- /dev/null +++ b/builds/linux/rocky/9/data/network.pkrtpl.hcl @@ -0,0 +1,5 @@ +%{ if ip != null ~} +network --device=${device} --bootproto=static --ip=${ip} --netmask=${cidrnetmask("${ip}/${netmask}")} --gateway=${gateway} --nameserver=${join(",", dns)} +%{ else ~} +network --device=${device} --bootproto=dhcp +%{ endif ~} diff --git a/builds/linux/rocky/9/data/storage.pkrtpl.hcl b/builds/linux/rocky/9/data/storage.pkrtpl.hcl new file mode 100644 index 0000000..2ec0342 --- /dev/null +++ b/builds/linux/rocky/9/data/storage.pkrtpl.hcl @@ -0,0 +1,73 @@ +### Sets how the boot loader should be installed. +bootloader --location=mbr + +### Initialize any invalid partition tables found on disks. +zerombr + +### Removes partitions from the system, prior to creation of new partitions. +### By default, no partitions are removed. +### --all Erases all partitions from the system +### --initlabel Initializes a disk (or disks) by creating a default disk label for all disks in their respective architecture. +clearpart --all --initlabel + +### Modify partition sizes for the virtual machine hardware. +### Create primary system partitions. +%{ for partition in partitions ~} +part +%{~ if partition.volume_group != "" ~} + pv.${partition.volume_group} +%{~ else ~} +%{~ if partition.format.fstype == "swap" ~} + swap +%{~ else ~} + ${partition.mount.path} +%{~ endif ~} +%{~ if partition.format.fstype != "" ~} + --label=${partition.format.label} +%{~ if partition.format.fstype == "fat32" ~} + --fstype vfat +%{~ else ~} + --fstype ${partition.format.fstype} +%{~ endif ~} +%{~ endif ~} +%{~ endif ~} +%{~ if partition.mount.options != "" ~} + --fsoptions="${partition.mount.options}" +%{~ endif ~} +%{~ if partition.size != -1 ~} + --size=${partition.size} +%{~ else ~} + --size=100 --grow +%{ endif ~} + +%{ endfor ~} +### Create a logical volume management (LVM) group. +%{ for index, volume_group in lvm ~} +volgroup sysvg pv.${volume_group.name} + +### Modify logical volume sizes for the virtual machine hardware. +### Create logical volumes. +%{ for partition in volume_group.partitions ~} +logvol +%{~ if partition.format.fstype == "swap" ~} + swap +%{~ else ~} + ${partition.mount.path} +%{~ endif ~} + --name=${partition.name} --vgname=${volume_group.name} --label=${partition.format.label} +%{~ if partition.format.fstype == "fat32" ~} + --fstype vfat +%{~ else ~} + --fstype ${partition.format.fstype} +%{~ endif ~} +%{~ if partition.mount.options != "" ~} + --fsoptions="${partition.mount.options}" +%{~ endif ~} +%{~ if partition.size != -1 ~} + --size=${partition.size} +%{~ else ~} + --size=100 --grow +%{ endif ~} + +%{ endfor ~} +%{ endfor ~} diff --git a/builds/linux/rocky/9/linux-rocky.auto.pkrvars.hcl b/builds/linux/rocky/9/linux-rocky.auto.pkrvars.hcl new file mode 100644 index 0000000..d4c34a4 --- /dev/null +++ b/builds/linux/rocky/9/linux-rocky.auto.pkrvars.hcl @@ -0,0 +1,45 @@ +/* + DESCRIPTION: + Rocky Linux 9 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 = "rocky" +vm_os_version = "9" + +// Virtual Machine Guest Operating System Setting +vm_os_type = "l26" + +// Virtual Machine Hardware Settings +vm_bios = "seabios" +vm_cpu_count = 1 +vm_cpu_sockets = 1 +vm_cpu_type = "x86-64-v2-AES" +vm_mem_size = 2048 +vm_disk_type = "virtio" +vm_disk_size = "32G" +vm_disk_format = "raw" +vm_storage_pool = "vm-data" +vm_disk_controller_type = "virtio-scsi-pci" +vm_network_card_model = "virtio" +vm_bridge_interface = "vmbr0" +vm_vlan_tag = "102" + +// Removable Media Settings +iso_path = "iso" +iso_file = "Rocky-9.4-x86_64-dvd.iso" +iso_checksum = "file:https://download.rockylinux.org/pub/rocky/9/isos/x86_64/CHECKSUM" + +// Boot Settings +vm_boot = "order=virtio0;ide2;net0" +vm_boot_wait = "10s" + +// EFI Settings +vm_firmware_path = "./OVMF.fd" +vm_efi_storage_pool = "vm-data" +vm_efi_pre_enrolled_keys = false +vm_efi_type = "4m" diff --git a/builds/linux/rocky/9/linux-rocky.pkr.hcl b/builds/linux/rocky/9/linux-rocky.pkr.hcl new file mode 100644 index 0000000..731ea55 --- /dev/null +++ b/builds/linux/rocky/9/linux-rocky.pkr.hcl @@ -0,0 +1,204 @@ +/* + DESCRIPTION: + Rocky Linux 9 template using the Packer Builder for Proxmox (proxmox-iso). +*/ + +// BLOCK: packer +// The Packer configuration. + +packer { + required_version = ">= 1.9.1" + required_plugins { + ansible = { + source = "github.com/hashicorp/ansible" + version = "~> 1" + } + git = { + version = ">= 0.4.2" + source = "github.com/ethanmdavidson/git" + } + proxmox = { + version = ">= 1.0.6" + source = "github.com/hashicorp/proxmox" + } + } +} + +// BLOCK: data +// Defines the data sources. + +data "git-repository" "cwd" {} + +// BLOCK: locals +// Defines the local variables. + +locals { + 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_cloud_init_enable}" + 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 = { + "/ks.cfg" = templatefile("${abspath(path.root)}/data/ks.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_bridge_interface + ip = var.vm_ip_address + netmask = var.vm_ip_netmask + gateway = var.vm_ip_gateway + dns = var.vm_dns_list + }) + common_data_source = var.common_data_source + # lvm needs to be here so late commands can access vg names + lvm = var.vm_disk_lvm + 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 = join(" ", var.additional_packages) + }) + } + data_source_command = var.common_data_source == "http" ? "inst.ks=http://{{.HTTPIP}}:{{.HTTPPort}}/ks.cfg" : "inst.ks=/cdrom/ks.cfg" + vm_name = "${var.vm_os_family}-${var.vm_os_name}-${var.vm_os_version}" + vm_bios = var.vm_bios == "ovmf" ? var.vm_firmware_path : null +} + +// BLOCK: source +// Defines the builder configuration blocks. + +source "proxmox-iso" "linux-rocky" { + + // 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 + } + } + unmount_iso = true + ssh_username = "${var.build_username}" + ssh_password = "${var.build_password}" + ssh_timeout = "${var.timeout}" + ssh_port = "22" + iso_file = "${var.common_iso_storage}:${var.iso_path}/${var.iso_file}" + iso_checksum = "${var.iso_checksum}" + 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_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 = [ + "", + "", + " text ${local.data_source_command}", + "" + ] + + 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_cloud_init_enable + cloud_init_storage_pool = var.vm_cloud_init_enable == true ? var.vm_storage_pool : null + +} + +# Build Definition to create the VM Template +build { + sources = ["source.proxmox-iso.linux-rocky"] + + provisioner "ansible" { + user = "${var.build_username}" + playbook_file = "${path.cwd}/ansible/main.yml" + roles_path = "${path.cwd}/ansible/roles" + ansible_env_vars = [ + "ANSIBLE_CONFIG=${path.cwd}/ansible/ansible.cfg" + ] + extra_arguments = [ + "--extra-vars", "display_skipped_hosts=false", + "--extra-vars", "BUILD_USERNAME=${var.build_username}", + "--extra-vars", "BUILD_SECRET='${var.build_key}'", + "--extra-vars", "ANSIBLE_USERNAME=${var.ansible_username}", + "--extra-vars", "ANSIBLE_SECRET='${var.ansible_key}'", + ] + } + + 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_cloud_init_enable = "${var.vm_cloud_init_enable}" + } + } +} diff --git a/builds/linux/rocky/9/variables-network.pkr.hcl b/builds/linux/rocky/9/variables-network.pkr.hcl new file mode 100644 index 0000000..29f8a32 --- /dev/null +++ b/builds/linux/rocky/9/variables-network.pkr.hcl @@ -0,0 +1,36 @@ +/* + DESCRIPTION: + Rocky Linux 9 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 = "ens192" +} + +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 = [] +} diff --git a/builds/linux/rocky/9/variables-storage.pkr.hcl b/builds/linux/rocky/9/variables-storage.pkr.hcl new file mode 100644 index 0000000..edfadb6 --- /dev/null +++ b/builds/linux/rocky/9/variables-storage.pkr.hcl @@ -0,0 +1,53 @@ +/* + DESCRIPTION: + Rocky Linux 9 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 = [] +} diff --git a/builds/linux/rocky/9/variables.pkr.hcl b/builds/linux/rocky/9/variables.pkr.hcl new file mode 100644 index 0000000..15810aa --- /dev/null +++ b/builds/linux/rocky/9/variables.pkr.hcl @@ -0,0 +1,304 @@ +/* + DESCRIPTION: + Rocky Linux 9 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')" +} + +variable "vm_efi_type" { + type = string + description = "Specifies the version of the OVMF firmware to be used. (e.g. '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)" +} + +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_cloud_init_enable" { + 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--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_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 = [] +} diff --git a/builds/network.pkrvars.hcl.example b/builds/network.pkrvars.hcl.example new file mode 100644 index 0000000..e3f5fdf --- /dev/null +++ b/builds/network.pkrvars.hcl.example @@ -0,0 +1,12 @@ +/* + DESCRIPTION: + Network variables used for all builds. + - Variables are passed to and used by guest operating system configuration files (e.g., ks.cfg). + +*/ + +// VM Network Settings (default DHCP) +// vm_ip_address = "192.168.101.100" +// vm_ip_netmask = 24 +// vm_ip_gateway = "192.168.101.1" +// vm_dns_list = [ "8.8.8.8", "8.8.4.4" ]