Using dynamic build to manage multiple preseed?

Hi,

I’m trying to create 2 debian templates, the only differences between the 2 is that one has 1 disk, the other 2 disks.

Instead of duplicating my code and managing 2 sources, I’m trying to build one base source with all similarity between the templates and using a dynamic source to set specific images value.

I don’t know how I can properly add storage only to the second template, I have the following draft to explain where am I right now

I’m not really sure all of this can work but if anyone manage to make something like that :smiley:

My base source

source "vsphere-iso" "base-debian-amd64" {

  // vSphere Settings
  datacenter = var.vsphere_datacenter
  cluster    = var.vsphere_cluster
  datastore  = var.vsphere_datastore
  folder     = var.vsphere_folder

  // Virtual Machine Settings
  vm_name              = "vm-template-${var.guest_os_family}-${var.guest_os_name}-${var.guest_os_version}-2023-001"
  guest_os_type        = var.guest_os_type
  firmware             = var.firmware
  CPUs                 = var.cpu_count
  cpu_cores            = var.cpu_cores
  CPU_hot_plug         = var.cpu_hot_add
  RAM                  = var.RAM
  RAM_hot_plug         = var.RAM_hot_plug
  cdrom_type           = var.cdrom_type
  disk_controller_type = var.disk_controller_type
  storage {
    disk_size             = var.disk_size
    disk_thin_provisioned = var.disk_thin_provisioned
  }
  network_adapters {
    network      = var.vsphere_network
    network_card = var.network_card
  }
  vm_version           = var.vm_version
  remove_cdrom         = var.common_remove_cdrom
  tools_upgrade_policy = var.common_tools_upgrade_policy
  notes                = local.build_description

  // Removable Media Settings
  iso_urls     = var.iso_urls
  iso_checksum = var.iso_checksum

  // Boot and Provisioning Settings
  http_ip       = var.common_data_source == "http" ? var.http_ip : null
  http_port_min = var.common_data_source == "http" ? var.http_port_min : null
  http_port_max = var.common_data_source == "http" ? var.http_port_max : null
  boot_order    = var.boot_order
  boot_wait     = var.boot_wait
  ip_wait_timeout  = var.common_ip_wait_timeout
  shutdown_command = "echo '${var.common_ssh_password}' | sudo -S -E shutdown -P now"
  shutdown_timeout = var.common_shutdown_timeout

  // Communicator Settings and Credentials
  communicator       = var.communicator
  ssh_username       = var.common_ssh_username
  ssh_password       = var.common_ssh_password
  ssh_port           = var.ssh_port
  ssh_timeout        = var.ssh_timeout
}

My builds

builds = {
  debian-classic = {
    preseed = {
       "/ks.cfg" = templatefile("${abspath(path.root)}/data/debian-classic.pkrtpl.hcl",{
      kickstart = var
      common_ssh_username      = var.common_ssh_username
      common_ssh_password      = var.common_ssh_password
      guest_os_language        = var.guest_os_language
      guest_os_keyboard        = var.guest_os_keyboard
      guest_os_timezone        = var.guest_os_timezone
      common_data_source       = var.common_data_source
      common_ansible_pkey      = var.common_ansible_pkey
      }
    }
  }
  debian-kube = {
    preseed = {
      "/ks.cfg" = templatefile("${abspath(path.root)}/data/debian-kube.pkrtpl.hcl",  {
      common_ssh_username      = var.common_ssh_username
      common_ssh_password      = var.common_ssh_password
      guest_os_language        = var.guest_os_language
      guest_os_keyboard        = var.guest_os_keyboard
      guest_os_timezone        = var.guest_os_timezone
      common_data_source       = var.common_data_source
      common_ansible_pkey      = var.common_ansible_pkey
      }
    }
// This is the part I don't know how to manage
    storage = {
      disk_size          = var.disk_containerd_size
      disk_eagerly_scrub = var.disk_eagerly_scrub
    }
  }
}

My dynamic source

dynamic "source" {
  for_each = local.builds
  content {
    name                    = source.key
    http_content            = source.value.storage.preseed

    boot_command     = [
    "<wait3s>c<wait3s>",
    "linux /install.amd/vmlinuz",
    " auto-install/enable=true",
    " debconf/priority=critical",
    " netcfg/disable_autoconfig=true",
    " netcfg/use_autoconfig=false",
    " netcfg/get_ipaddress=192.168.1.171",
    " netcfg/get_netmask=255.255.255.0",
    " netcfg/get_gateway=192.168.1.1",
    " netcfg/get_nameservers=192.168.1.10",
    " url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg",
    " noprompt --<enter>",
    "initrd /install.amd/initrd.gz<enter>",
    "boot<enter>",
    "<wait30s>",
    "<enter><wait>",
    "<enter><wait>",
    "<leftAltOn><f2><leftAltOff>",
    "<enter><wait>",
    "mount /dev/sr1 /media<enter>",
    "<leftAltOn><f1><leftAltOff>",
    "<down><down><down><down><enter>"
    ]
    output_directory = "virtualbox_iso_ubuntu_2010_amd64_${source.key}"
  }
}

Have you considered adding one disk by default to all templates.

Then running an ansible provisioner with a play that checks for a 2nd disk, if found formats and configures as desired?