Skip to content

Instantly share code, notes, and snippets.

@BDelacour
Last active January 22, 2024 11:22
Show Gist options
  • Save BDelacour/9393e6614bc3b1400333e53b93fff934 to your computer and use it in GitHub Desktop.
Save BDelacour/9393e6614bc3b1400333e53b93fff934 to your computer and use it in GitHub Desktop.
Packer debian 12 EFI
packer {
required_version = ">= 1.9.4"
required_plugins {
vsphere = {
source = "github.com/hashicorp/vsphere"
version = ">= 1.2.1"
}
}
}
locals {
build_by = "Built by: HashiCorp Packer ${packer.version}"
build_date = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp())
build_description = "Built on: ${local.build_date}\n${local.build_by}"
data_source_content = {
"/ks.cfg" = templatefile("${abspath(path.root)}/ks.pkrtpl.hcl", {
vm_username = var.vm_username
vm_password_encrypted = var.vm_password_encrypted
vm_ip = var.vm_ip
vm_gateway_ip = var.vm_gateway_ip
vm_nameservers = var.vm_nameservers
vm_netmask = var.vm_netmask
})
}
data_source_command = "file=/media/ks.cfg"
mount_cdrom_command = "<leftAltOn><f2><leftAltOff> <enter><wait> mount /dev/sr1 /media<enter> <leftAltOn><f1><leftAltOff>"
mount_cdrom = local.mount_cdrom_command
}
// BLOCK: source
// Defines the builder configuration blocks.
source "vsphere-iso" "linux-debian" {
// vCenter Server Endpoint Settings and Credentials
vcenter_server = var.vsphere_server
username = var.vsphere_username
password = var.vsphere_password
insecure_connection = var.vsphere_insecure_connection
// vSphere Settings
datacenter = var.vsphere_datacenter
cluster = var.vsphere_cluster
datastore = var.vsphere_datastore
// Virtual Machine Settings
vm_name = var.vm_name
guest_os_type = var.vm_guest_os_type
firmware = "efi-secure"
CPUs = var.vm_cpu_count
RAM = var.vm_mem_size
cdrom_type = "sata"
disk_controller_type = ["pvscsi"]
storage {
disk_size = var.vm_disk_size
disk_thin_provisioned = true
}
network_adapters {
network = var.vsphere_network
network_card = "vmxnet3"
}
remove_cdrom = true
tools_upgrade_policy = true
notes = local.build_description
// Removable Media Settings
iso_urls = [var.iso_url]
iso_checksum = var.iso_checksum
cd_content = local.data_source_content
// Boot and Provisioning Settings
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.
"linux /install.amd/vmlinuz",
// This types a string that sets the auto-install/enable option to true. This is used to automate the installation process.
" auto-install/enable=true",
// This types a string that sets the debconf/priority option to critical. This is used to minimize the number of questions asked during the installation process.
" debconf/priority=critical",
// This types the value of the 'data_source_command' local variable. This is used to specify the kickstart data source configured in the common variables.
" ${local.data_source_command}",
// This types a string that sets the noprompt option and then sends the "enter" key. This is used to prevent the installer from pausing for user input.
" noprompt --<enter>",
// This types a command to load the initial RAM disk from the specified path and then sends the "enter" key.
"initrd /install.amd/initrd.gz<enter>",
// This types the "boot" command and then sends the "enter" key. This starts the boot process using the loaded kernel and initial RAM disk.
"boot<enter>",
// This waits for 30 seconds. This is typically used to give the system time to boot before sending more commands.
"<wait30s>",
// This sends the "enter" key and then waits. This is typically used to dismiss any prompts or messages that appear during boot.
"<enter><wait>",
// This sends the "enter" key and then waits. This is typically used to dismiss any prompts or messages that appear during boot.
"<enter><wait>",
// This types the value of the `mount_cdrom` local variable. This is typically used to mount the installation media.
" ${local.mount_cdrom}",
// This sends four "down arrow" keys and then the "enter" key. This is typically used to select a specific option in a menu.
"<down><down><down><down><enter>"
]
ip_wait_timeout = "20m"
ip_settle_timeout = "5s"
shutdown_command = "sudo -S -E shutdown -P now"
shutdown_timeout = "15m"
// Communicator Settings and Credentials
communicator = "ssh"
ssh_username = var.vm_username
ssh_password = var.vm_password
ssh_port = 22
ssh_timeout = "30m"
// Template and Content Library Settings
convert_to_template = true
}
build {
sources = ["source.vsphere-iso.linux-debian"]
}
# Debian 12
# https://www.debian.org/releases/bookworm/amd64/
# Locale and Keyboard
d-i debian-installer/locale string en_US
d-i keyboard-configuration/xkb-keymap select us
# Clock and Timezone
d-i clock-setup/utc boolean true
d-i clock-setup/ntp boolean true
d-i time/zone string UTC
# Grub and Reboot Message
d-i finish-install/reboot_in_progress note
d-i grub-installer/only_debian boolean true
# Partitioning
d-i partman-auto/disk string /dev/sda
d-i partman-auto/method string lvm
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-auto-lvm/new_vg_name string vg
d-i partman-efi/non_efi_system boolean true
d-i partman-partitioning/choose_label select gpt
d-i partman-partitioning/default_label string gpt
d-i partman-auto/choose_recipe select custom
d-i partman-auto/expert_recipe string \
custom :: \
512 512 512 fat32 \
$primary{ } \
mountpoint{ /boot/efi } \
method{ efi } \
format{ } \
use_filesystem{ } \
filesystem{ vfat } \
label { EFIFS } \
. \
456 456 456 ext2 \
$primary{ } \
$bootable{ } \
mountpoint{ /boot } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext2 } \
label{ BOOTFS } \
. \
1024 1024 1024 linux-swap \
$lvmok{ } \
lv_name{ lv_swap } \
in_vg { vg } \
method{ swap } \
format{ } \
label { SWAPFS } \
. \
2048 2048 2048 ext4 \
$lvmok{ } \
mountpoint{ / } \
lv_name{ lv_root } \
in_vg { vg } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
label { ROOTFS } \
. \
1024 1024 1024 ext4 \
$lvmok{ } \
mountpoint{ /home } \
lv_name{ lv_home } \
in_vg { vg } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
label { HOMEFS } \
options/nodev{ nodev } \
options/nosuid{ nosuid } \
. \
1024 1024 1024 ext4 \
$lvmok{ } \
mountpoint{ /opt } \
lv_name{ lv_opt } \
in_vg { vg } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
label { OPTFS } \
options/nodev{ nodev } \
. \
1024 1024 1024 ext4 \
$lvmok{ } \
mountpoint{ /tmp } \
lv_name{ lv_tmp } \
in_vg { vg } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
label { TMPFS } \
options/nodev{ nodev } \
options/noexec{ noexec } \
options/nosuid{ nosuid } \
. \
2048 2048 2048 ext4 \
$lvmok{ } \
mountpoint{ /var } \
lv_name{ lv_var } \
in_vg { vg } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
label { VARFS } \
options/nodev{ nodev } \
. \
1024 1024 1024 ext4 \
$lvmok{ } \
mountpoint{ /var/log } \
lv_name{ lv_varlog } \
in_vg { vg } \
method{ format } \
format{ } \
use_filesystem{ } \
filesystem{ ext4 } \
label { LOGFS } \
options/nodev{ nodev } \
options/noexec{ noexec } \
options/nosuid{ nosuid } \
. \
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
# Network configuration
d-i netcfg/choose_interface select auto
d-i netcfg/disable_autoconfig boolean true
d-i netcfg/get_ipaddress string ${vm_ip}
d-i netcfg/get_netmask string ${vm_netmask}
d-i netcfg/get_gateway string ${vm_gateway_ip}
d-i netcfg/get_nameservers string ${vm_nameservers}
d-i netcfg/confirm_static boolean true
# Mirror settings
d-i mirror/country string manual
d-i mirror/http/hostname string cdn-fastly.deb.debian.org
d-i mirror/http/directory string /debian
d-i mirror/http/proxy string
# User Configuration
d-i passwd/root-login boolean false
d-i passwd/user-fullname string ${vm_username}
d-i passwd/username string ${vm_username}
d-i passwd/user-password-crypted password ${vm_password_encrypted}
# Package Configuration
d-i pkgsel/run_tasksel boolean false
d-i pkgsel/include string openssh-server open-vm-tools python3-apt perl
# Add User to Sudoers
d-i preseed/late_command string \
echo '${vm_username} ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/${vm_username} ; \
in-target chmod 440 /etc/sudoers.d/${vm_username} ;
# Umount preseed media early
d-i preseed/early_command string \
umount /media && echo 1 > /sys/block/sr1/device/delete ;
// Connection Settings
variable "vsphere_server" {
type = string
description = "The fully qualified domain name or IP address of the vCenter Server instance."
}
variable "vsphere_username" {
type = string
description = "The username to login to the vCenter Server instance."
sensitive = true
}
variable "vsphere_password" {
type = string
description = "The password for the login to the vCenter Server instance."
sensitive = true
}
variable "vsphere_insecure_connection" {
type = bool
description = "Do not validate vCenter Server TLS certificate."
}
// vSphere Settings
variable "vsphere_datacenter" {
type = string
description = "The name of the target vSphere datacenter."
default = ""
}
variable "vsphere_cluster" {
type = string
description = "The name of the target vSphere cluster."
default = ""
}
variable "vsphere_datastore" {
type = string
description = "The name of the target vSphere datastore."
}
variable "vsphere_network" {
type = string
description = "The name of the target vSphere network segment."
}
// Virtual Machine Settings
variable "vm_name" {
type = string
description = "The virtual machine name."
}
variable "vm_guest_os_type" {
type = string
description = "The guest operating system type, also know as guestid."
}
variable "vm_cpu_count" {
type = number
description = "The number of virtual CPUs."
}
variable "vm_mem_size" {
type = number
description = "The size for the virtual memory in MB."
}
variable "vm_disk_size" {
type = number
description = "The size for the virtual disk in MB."
}
variable "vm_ip" {
type = string
description = "The IPV4 the VM will use during build."
}
variable "vm_gateway_ip" {
type = string
description = "The IPV4 Gateway for vm_ip."
}
variable "vm_netmask" {
type = string
description = "The netmask for vm_ip."
}
variable "vm_nameservers" {
type = string
description = "The comma-separated list of nameservers to use."
}
// OS Iso Settings
variable "iso_url" {
type = string
description = "The URL pointing to the OS ISO."
}
variable "iso_checksum" {
type = string
description = "The checksum of the iso_url ISO file."
}
// Communicator Settings and Credentials
variable "vm_username" {
type = string
description = "The username to login to the guest operating system."
sensitive = true
}
variable "vm_password" {
type = string
description = "The password to login to the guest operating system."
sensitive = true
}
variable "vm_password_encrypted" {
type = string
description = "The encrypted password to login the guest operating system."
sensitive = true
}
variable "vm_ssh_pubkey" {
type = string
description = "The public key to login to the guest operating system."
sensitive = true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment