<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Umair-khurshid</title>
    <description>The latest articles on Forem by Umair-khurshid (@umairk).</description>
    <link>https://forem.com/umairk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1108711%2Ff748adcd-1bd6-411d-9c75-e4e8a6348f46.jpeg</url>
      <title>Forem: Umair-khurshid</title>
      <link>https://forem.com/umairk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/umairk"/>
    <language>en</language>
    <item>
      <title>Using Packer and Proxmox to Build Templates</title>
      <dc:creator>Umair-khurshid</dc:creator>
      <pubDate>Fri, 23 Aug 2024 17:57:11 +0000</pubDate>
      <link>https://forem.com/umairk/using-packer-and-proxmox-to-build-templates-455f</link>
      <guid>https://forem.com/umairk/using-packer-and-proxmox-to-build-templates-455f</guid>
      <description>&lt;p&gt;Automating the deployment of virtual machines (VMs) is an essential part of modern IT infrastructure. Packer and Proxmox are two powerful tools that, when combined, offer an effective solution for automated VM image creation. This article explores why using Packer with Proxmox is beneficial, as well as the practical implementation of this combination.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Packer for Proxmox?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reproducibility and consistency&lt;/strong&gt;: Packer lets you define all the configurations of a VM image in a file in HCL or JSON format. By using Packer, you guarantee reproducibility in the image creation process, ensuring consistency in your deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform support&lt;/strong&gt;: Packer supports multiple vendors, and Proxmox is just one of them. This flexibility allows you to create images that can be deployed on different types of platform, whether on-premise or in the cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimisation of resources&lt;/strong&gt;: You can automate the creation of lightweight, optimised images, eliminating unnecessary components and applying configurations specific to your environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time savings&lt;/strong&gt;: Automating the image creation process significantly reduces the time needed to prepare VMs. You can automate tasks such as software installation, network configuration and many others, speeding up the deployment cycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use Packer on Proxmox?
&lt;/h2&gt;

&lt;p&gt;Install Packer on your development machine and configure it to use the Proxmox provider by specifying the connection details (IP address of the server where the image will be created, username, password). For installation, I can only suggest that you visit the &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fdeveloper.hashicorp.com%2Fpacker%2Ftutorials%2Fdocker-get-started%2Fget-started-install-cli%" rel="noopener noreferrer"&gt;official website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are then 3 steps in the Packer image creation process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creation of Packer model definition and automated OS configuration files&lt;/li&gt;
&lt;li&gt;Create a Packer configuration file in HCL or JSON format describing the steps required to create your Proxmox image.&lt;/li&gt;
&lt;li&gt;Specify parameters such as operating system type, provisioning scripts and Proxmox-specific parameters.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Operating systems can be configured autonomously and dynamically, without having to click or enter commands. To do this, the use of configuration files must be taken into account and maintained in line with changing requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build execution:&lt;/strong&gt;&lt;br&gt;
Start the building process with Packer. Packer will connect to your Proxmox host, create a temporary VM, apply configurations and will transform it to a template. This template will be the source for your deployment, the template to clone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the generated image by deploying it on a Proxmox VM.&lt;/li&gt;
&lt;li&gt;Distribute the image to other Proxmox hosts or save it for future use.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  My use case and my configuration
&lt;/h2&gt;

&lt;p&gt;I use Packer in my homelab to generate templates (Debian 12 and Ubuntu 22.04) which I then re-use via Open Tofu to build the VMs I need. To make customization easier, I use variables as much as possible. So the base file is static and only the variables (in a separate file) need to be modified as required.&lt;/p&gt;

&lt;p&gt;I have already uploaded the Debian 12 ISO image to storage on my Proxmox host. It is possible to use Packer to download the ISO image from the Internet and send it to your Proxmox host. I didn't choose this solution because I wanted to limit web access and set myself up for full "self-hosting".&lt;/p&gt;

&lt;p&gt;To make the connection between Proxmox and Packer, I created a user in the "pve" realm, then I created a token for this user and finally assigned rights to the token API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the "Datacenter" tab, go to the "Permissions" section and click on "Users" and the "Add" button. Enter the necessary information (no password required) then save the form. Remember the name of this user.&lt;/li&gt;
&lt;li&gt;Still in the "Permissions" section, click on "API Token" and the "Add" button. Select the user previously created, give the token a name (to remember) and continue with the form; a secret will then be displayed and must be stored in a safe place. This secret is required to operate Proxmox with Packer.&lt;/li&gt;
&lt;li&gt;Finally, go back to the "Permissions" section, then click on the "Add - API Token Permission" button: select the user with the API ID you just created, and add the following rights to it:&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Path&lt;/em&gt;: "/"&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Role &lt;/em&gt;: "PVEAdmin" (it's a lot, but there's no choice. Alternatively, you can create your own role with the necessary rights…)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Propagate&lt;/em&gt;: tick the box (useful for having permissions over the entire infrastructure - machines, storage, network)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the folder where my files are stored, I have created an "autoinstall" subfolder, to put the preseed file that allows Debian to be installed automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/git/homelab/packer&lt;span class="nv"&gt;$ &lt;/span&gt;tree
&lt;span class="nb"&gt;.&lt;/span&gt;
├── autoinstall
│   ├── preseed.cfg
├── customdeb12.pkrvars.hcl
└── debian12.pkr.hcl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From now on, here are the files needed to create a Debian 12 image with Packer, for Proxmox:&lt;br&gt;
debian12.pkr.hcl" file: this is the file that defines the Packer requirements for our use case, the basis of our model, the connection to the Proxmox server and the variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;// debian12.pkr.hcl&lt;/span&gt;
&lt;span class="nx"&gt;packer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.1.6"&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github.com/hashicorp/proxmox"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"bios_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"boot_command"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"boot_wait"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"bridge_firewall"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"bridge_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"cloud_init"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"iso_file"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"iso_storage_pool"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"machine_default_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pc"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"network_model"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"virtio"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"os_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"l26"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_api_token_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_api_token_secret"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;sensitive&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_api_url"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"proxmox_node"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"qemu_agent_activation"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"scsi_controller_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ssh_timeout"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"tags"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"io_thread"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"cpu_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kvm64"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"vm_info"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"disk_discard"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"disk_format"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"qcow2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"disk_size"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"16G"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"disk_type"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"scsi"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"nb_core"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"nb_cpu"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"nb_ram"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ssh_username"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ssh_password"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"ssh_handshake_attempts"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"storage_pool"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local-lvm"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"vm_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99999&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"vm_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;packer_timestamp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formatdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"YYYYMMDD-hhmm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="s2"&gt;"proxmox-iso"&lt;/span&gt; &lt;span class="s2"&gt;"debian12"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bios&lt;/span&gt;                     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.bios_type}"&lt;/span&gt;
  &lt;span class="nx"&gt;boot_command&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"${var.boot_command}"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;boot_wait&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.boot_wait}"&lt;/span&gt;
  &lt;span class="nx"&gt;cloud_init&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.cloud_init}"&lt;/span&gt;
  &lt;span class="nx"&gt;cloud_init_storage_pool&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.storage_pool}"&lt;/span&gt;
  &lt;span class="nx"&gt;communicator&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ssh"&lt;/span&gt;
  &lt;span class="nx"&gt;cores&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.nb_core}"&lt;/span&gt;
  &lt;span class="nx"&gt;cpu_type&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.cpu_type}"&lt;/span&gt;
  &lt;span class="nx"&gt;http_directory&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"autoinstall"&lt;/span&gt;
  &lt;span class="nx"&gt;insecure_skip_tls_verify&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;iso_file&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.iso_file}"&lt;/span&gt;
  &lt;span class="nx"&gt;machine&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.machine_default_type}"&lt;/span&gt;
  &lt;span class="nx"&gt;memory&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.nb_ram}"&lt;/span&gt;
  &lt;span class="nx"&gt;node&lt;/span&gt;                     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.proxmox_node}"&lt;/span&gt;
  &lt;span class="nx"&gt;os&lt;/span&gt;                       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.os_type}"&lt;/span&gt;
  &lt;span class="nx"&gt;proxmox_url&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.proxmox_api_url}"&lt;/span&gt;
  &lt;span class="nx"&gt;qemu_agent&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.qemu_agent_activation}"&lt;/span&gt;
  &lt;span class="nx"&gt;scsi_controller&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.scsi_controller_type}"&lt;/span&gt;
  &lt;span class="nx"&gt;sockets&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.nb_cpu}"&lt;/span&gt;
  &lt;span class="nx"&gt;ssh_handshake_attempts&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.ssh_handshake_attempts}"&lt;/span&gt;
  &lt;span class="nx"&gt;ssh_pty&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;ssh_timeout&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.ssh_timeout}"&lt;/span&gt;
  &lt;span class="nx"&gt;ssh_username&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.ssh_username}"&lt;/span&gt;
  &lt;span class="nx"&gt;ssh_password&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.ssh_password}"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt;                     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.tags}"&lt;/span&gt;
  &lt;span class="nx"&gt;template_description&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.vm_info} - ${local.packer_timestamp}"&lt;/span&gt;
  &lt;span class="nx"&gt;token&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.proxmox_api_token_secret}"&lt;/span&gt;
  &lt;span class="nx"&gt;unmount_iso&lt;/span&gt;              &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;username&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.proxmox_api_token_id}"&lt;/span&gt;
  &lt;span class="nx"&gt;vm_id&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.vm_id}"&lt;/span&gt;
  &lt;span class="nx"&gt;vm_name&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.vm_name}"&lt;/span&gt;
  &lt;span class="nx"&gt;disks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;discard&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.disk_discard}"&lt;/span&gt;
    &lt;span class="nx"&gt;disk_size&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.disk_size}"&lt;/span&gt;
    &lt;span class="nx"&gt;format&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.disk_format}"&lt;/span&gt;
    &lt;span class="nx"&gt;io_thread&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.io_thread}"&lt;/span&gt;
    &lt;span class="nx"&gt;storage_pool&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.storage_pool}"&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.disk_type}"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;network_adapters&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bridge&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.bridge_name}"&lt;/span&gt;
    &lt;span class="nx"&gt;firewall&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.bridge_firewall}"&lt;/span&gt;
    &lt;span class="nx"&gt;model&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${var.network_model}"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sources&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"source.proxmox-iso.debian12"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom.pkvars.hcl" file: Variables are used to customise the model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;// custom.pkvars.hcl&lt;/span&gt;
&lt;span class="nx"&gt;bios_type&lt;/span&gt;                &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"seabios"&lt;/span&gt;
&lt;span class="nx"&gt;boot_command&lt;/span&gt;             &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;esc&amp;gt;&amp;lt;wait&amp;gt;auto console-keymaps-at/keymap=fr console-setup/ask_detect=false debconf/frontend=noninteractive fb=false url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg&amp;lt;enter&amp;gt;"&lt;/span&gt;
&lt;span class="nx"&gt;boot_wait&lt;/span&gt;                &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10s"&lt;/span&gt;
&lt;span class="nx"&gt;bridge_name&lt;/span&gt;              &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vmbr0"&lt;/span&gt;
&lt;span class="nx"&gt;bridge_firewall&lt;/span&gt;          &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="nx"&gt;cloud_init&lt;/span&gt;               &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;cpu_type&lt;/span&gt;                 &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"x86-64-v2-AES"&lt;/span&gt;
&lt;span class="nx"&gt;disk_discard&lt;/span&gt;             &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;disk_format&lt;/span&gt;              &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"qcow2"&lt;/span&gt;
&lt;span class="nx"&gt;disk_size&lt;/span&gt;                &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"12G"&lt;/span&gt;
&lt;span class="nx"&gt;disk_type&lt;/span&gt;                &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"scsi"&lt;/span&gt;
&lt;span class="nx"&gt;iso_file&lt;/span&gt;                 &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local:iso/debian-12.4.0-amd64-netinst.iso"&lt;/span&gt;
&lt;span class="nx"&gt;machine_default_type&lt;/span&gt;     &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"q35"&lt;/span&gt;
&lt;span class="nx"&gt;nb_core&lt;/span&gt;                  &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;nb_cpu&lt;/span&gt;                   &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;nb_ram&lt;/span&gt;                   &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt;
&lt;span class="nx"&gt;network_model&lt;/span&gt;            &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"virtio"&lt;/span&gt;
&lt;span class="nx"&gt;io_thread&lt;/span&gt;                &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="nx"&gt;os_type&lt;/span&gt;                  &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"l26"&lt;/span&gt;
&lt;span class="nx"&gt;proxmox_api_token_id&lt;/span&gt;     &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"packbot@pve!nom_token"&lt;/span&gt;
&lt;span class="nx"&gt;proxmox_api_token_secret&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"aaaaaa-aaaa-bbbb-cccc-123456789012"&lt;/span&gt;
&lt;span class="nx"&gt;proxmox_api_url&lt;/span&gt;          &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://ip_proxmox:8006/api2/json"&lt;/span&gt;
&lt;span class="nx"&gt;proxmox_node&lt;/span&gt;             &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nom_hôte_proxmox"&lt;/span&gt;
&lt;span class="nx"&gt;qemu_agent_activation&lt;/span&gt;    &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;scsi_controller_type&lt;/span&gt;     &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"virtio-scsi-pci"&lt;/span&gt;
&lt;span class="nx"&gt;ssh_handshake_attempts&lt;/span&gt;   &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="nx"&gt;ssh_timeout&lt;/span&gt;              &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"35m"&lt;/span&gt;
&lt;span class="nx"&gt;ssh_username&lt;/span&gt;             &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"umair"&lt;/span&gt;
&lt;span class="nx"&gt;ssh_password&lt;/span&gt;             &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"umairpwd"&lt;/span&gt;
&lt;span class="nx"&gt;storage_pool&lt;/span&gt;             &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"stoCeph"&lt;/span&gt;
&lt;span class="nx"&gt;tags&lt;/span&gt;                     &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"template"&lt;/span&gt;
&lt;span class="nx"&gt;vm_id&lt;/span&gt;                    &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99998&lt;/span&gt;
&lt;span class="nx"&gt;vm_info&lt;/span&gt;                  &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Debian 12 Packer Template"&lt;/span&gt;
&lt;span class="nx"&gt;vm_name&lt;/span&gt;                  &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pckr-deb12"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few notes about these variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't forget to change the values of "bridge_name", "iso_file" (the name of the storage where the ISO image is and its name), "proxmox_", "ssh_*"…&lt;/li&gt;
&lt;li&gt;The "boot_command" variable is used to force the ISO to use the preseed file&lt;/li&gt;
&lt;li&gt;"cloud_init is installed and activated to make it easier for Open Tofu to configure VMs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll leave you to take the other variables into account and modify them to suit your needs.&lt;/p&gt;

&lt;p&gt;"autoinstall/preseed.cfg" file: Debian installation configuration file, for zero-touch installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;#_preseed_V1
&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;debian&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;language&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;debian&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;EN&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;debian&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;locale&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;en_US&lt;/span&gt;.&lt;span class="n"&gt;UTF&lt;/span&gt;-&lt;span class="m"&gt;8&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;localechooser&lt;/span&gt;/&lt;span class="n"&gt;supported&lt;/span&gt;-&lt;span class="n"&gt;locales&lt;/span&gt; &lt;span class="n"&gt;multiselect&lt;/span&gt; &lt;span class="n"&gt;en_US&lt;/span&gt;.&lt;span class="n"&gt;UTF&lt;/span&gt;-&lt;span class="m"&gt;8&lt;/span&gt;, &lt;span class="n"&gt;en_US&lt;/span&gt;.&lt;span class="n"&gt;UTF&lt;/span&gt;-&lt;span class="m"&gt;8&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;keyboard&lt;/span&gt;-&lt;span class="n"&gt;configuration&lt;/span&gt;/&lt;span class="n"&gt;xkb&lt;/span&gt;-&lt;span class="n"&gt;keymap&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;console&lt;/span&gt;-&lt;span class="n"&gt;keymaps&lt;/span&gt;-&lt;span class="n"&gt;at&lt;/span&gt;/&lt;span class="n"&gt;keymap&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt;-&lt;span class="n"&gt;latin9&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;debian&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;keymap&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;en&lt;/span&gt;-&lt;span class="n"&gt;latin9&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;netcfg&lt;/span&gt;/&lt;span class="n"&gt;choose_interface&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;netcfg&lt;/span&gt;/&lt;span class="n"&gt;link_wait_timeout&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;netcfg&lt;/span&gt;/&lt;span class="n"&gt;dhcp_timeout&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;netcfg&lt;/span&gt;/&lt;span class="n"&gt;get_hostname&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;pckr&lt;/span&gt;-&lt;span class="n"&gt;deb12&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;netcfg&lt;/span&gt;/&lt;span class="n"&gt;get_domain&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;.&lt;span class="n"&gt;xyz&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;netcfg&lt;/span&gt;/&lt;span class="n"&gt;wireless_wep&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;hw&lt;/span&gt;-&lt;span class="n"&gt;detect&lt;/span&gt;/&lt;span class="n"&gt;load_firmware&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;mirror&lt;/span&gt;/&lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FR&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;mirror&lt;/span&gt;/&lt;span class="n"&gt;http&lt;/span&gt;/&lt;span class="n"&gt;hostname&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;deb&lt;/span&gt;.&lt;span class="n"&gt;debian&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;mirror&lt;/span&gt;/&lt;span class="n"&gt;http&lt;/span&gt;/&lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; /&lt;span class="n"&gt;debian&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;mirror&lt;/span&gt;/&lt;span class="n"&gt;http&lt;/span&gt;/&lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;root&lt;/span&gt;-&lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;make&lt;/span&gt;-&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;root&lt;/span&gt;-&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="n"&gt;umairpwd&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;root&lt;/span&gt;-&lt;span class="n"&gt;password&lt;/span&gt;-&lt;span class="n"&gt;again&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="n"&gt;umairpwd&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;user&lt;/span&gt;-&lt;span class="n"&gt;fullname&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;umair&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;umair&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;user&lt;/span&gt;-&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="n"&gt;umairpwd&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt;/&lt;span class="n"&gt;user&lt;/span&gt;-&lt;span class="n"&gt;password&lt;/span&gt;-&lt;span class="n"&gt;again&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="n"&gt;umairpwd&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;-&lt;span class="n"&gt;setup&lt;/span&gt;/&lt;span class="n"&gt;utc&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;/&lt;span class="n"&gt;zone&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;US&lt;/span&gt;/&lt;span class="n"&gt;New&lt;/span&gt; &lt;span class="n"&gt;York&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;-&lt;span class="n"&gt;setup&lt;/span&gt;/&lt;span class="n"&gt;ntp&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;-&lt;span class="n"&gt;setup&lt;/span&gt;/&lt;span class="n"&gt;ntp&lt;/span&gt;-&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;  &lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="n"&gt;us&lt;/span&gt;.&lt;span class="n"&gt;pool&lt;/span&gt;.&lt;span class="n"&gt;ntp&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;auto&lt;/span&gt;/&lt;span class="n"&gt;disk&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; /&lt;span class="n"&gt;dev&lt;/span&gt;/&lt;span class="n"&gt;sda&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;auto&lt;/span&gt;/&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;lvm&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;auto&lt;/span&gt;-&lt;span class="n"&gt;lvm&lt;/span&gt;/&lt;span class="n"&gt;guided_size&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;lvm&lt;/span&gt;/&lt;span class="n"&gt;device_remove_lvm&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;lvm&lt;/span&gt;/&lt;span class="n"&gt;confirm&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;lvm&lt;/span&gt;/&lt;span class="n"&gt;confirm_nooverwrite&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;auto&lt;/span&gt;/&lt;span class="n"&gt;choose_recipe&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;multi&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;partitioning&lt;/span&gt;/&lt;span class="n"&gt;confirm_write_new_label&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;/&lt;span class="n"&gt;choose_partition&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;/&lt;span class="n"&gt;confirm&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;/&lt;span class="n"&gt;confirm_nooverwrite&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;md&lt;/span&gt;/&lt;span class="n"&gt;confirm&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;-&lt;span class="n"&gt;partitioning&lt;/span&gt;/&lt;span class="n"&gt;confirm_write_new_label&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;/&lt;span class="n"&gt;choose_partition&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;/&lt;span class="n"&gt;confirm&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;/&lt;span class="n"&gt;confirm_nooverwrite&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;partman&lt;/span&gt;/&lt;span class="n"&gt;mount_style&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;install&lt;/span&gt;-&lt;span class="n"&gt;recommends&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;-&lt;span class="n"&gt;setup&lt;/span&gt;/&lt;span class="n"&gt;cdrom&lt;/span&gt;/&lt;span class="n"&gt;set&lt;/span&gt;-&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;-&lt;span class="n"&gt;setup&lt;/span&gt;/&lt;span class="n"&gt;use_mirror&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;apt&lt;/span&gt;-&lt;span class="n"&gt;setup&lt;/span&gt;/&lt;span class="n"&gt;security_host&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt;.&lt;span class="n"&gt;debian&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;
&lt;span class="n"&gt;tasksel&lt;/span&gt; &lt;span class="n"&gt;tasksel&lt;/span&gt;/&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="n"&gt;multiselect&lt;/span&gt; &lt;span class="n"&gt;standard&lt;/span&gt;, &lt;span class="n"&gt;ssh&lt;/span&gt;-&lt;span class="n"&gt;server&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;pkgsel&lt;/span&gt;/&lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;qemu&lt;/span&gt;-&lt;span class="n"&gt;guest&lt;/span&gt;-&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;sudo&lt;/span&gt; &lt;span class="n"&gt;ca&lt;/span&gt;-&lt;span class="n"&gt;certificates&lt;/span&gt; &lt;span class="n"&gt;cloud&lt;/span&gt;-&lt;span class="n"&gt;init&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;pkgsel&lt;/span&gt;/&lt;span class="n"&gt;upgrade&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="n"&gt;safe&lt;/span&gt;-&lt;span class="n"&gt;upgrade&lt;/span&gt;
&lt;span class="n"&gt;popularity&lt;/span&gt;-&lt;span class="n"&gt;contest&lt;/span&gt; &lt;span class="n"&gt;popularity&lt;/span&gt;-&lt;span class="n"&gt;contest&lt;/span&gt;/&lt;span class="n"&gt;participate&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;grub&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;only_debian&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;grub&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;with_other_os&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;grub&lt;/span&gt;-&lt;span class="n"&gt;installer&lt;/span&gt;/&lt;span class="n"&gt;bootdev&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;-&lt;span class="n"&gt;install&lt;/span&gt;/&lt;span class="n"&gt;reboot_in_progress&lt;/span&gt; &lt;span class="n"&gt;note&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;-&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;cdrom&lt;/span&gt;-&lt;span class="n"&gt;detect&lt;/span&gt;/&lt;span class="n"&gt;eject&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With all the above files and the user configuration in Proxmox, you should be able to create a machine. The Packer commands to run are as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# initialize the repository to retrieve:&lt;/span&gt;
packer init debian12.pkr.hcl
&lt;span class="c"&gt;# validate Packer files:&lt;/span&gt;
packer validate &lt;span class="nt"&gt;-var-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;customdeb12.pkrvars.hcl debian12.pkr.hcl
&lt;span class="c"&gt;# build the image, replacing the artefact if it already exists:&lt;/span&gt;
packer build &lt;span class="nt"&gt;-on-error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ask &lt;span class="nt"&gt;-force&lt;/span&gt; &lt;span class="nt"&gt;-var-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;customdeb12.pkrvars.hcl debian12.pkr.hcl

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>proxmox</category>
      <category>packer</category>
      <category>tutorial</category>
      <category>homelab</category>
    </item>
    <item>
      <title>Easily Encode/Decode Kubernetes Secrets in Base64</title>
      <dc:creator>Umair-khurshid</dc:creator>
      <pubDate>Sat, 27 Jul 2024 20:15:05 +0000</pubDate>
      <link>https://forem.com/umairk/easily-encodedecode-kubernetes-secrets-in-base64-3hbp</link>
      <guid>https://forem.com/umairk/easily-encodedecode-kubernetes-secrets-in-base64-3hbp</guid>
      <description>&lt;p&gt;Something we have to do aLL the time when manipulating Secrets objects in Kubernetes is to display in plain text the “secrets” contained in our Secret (or to encode them).&lt;/p&gt;

&lt;p&gt;For those who don't know, Secrets in Kubernetes are unfortunately not very secret, since they are nothing more or less than base64 encoded strings (which is therefore anthing but secure). To tell the truth, I even wonder why bother encoding them at all. The only security we add compared to ConfigMaps is simply that the string is not readable by a human who would stick his head over your shoulder.&lt;/p&gt;

&lt;p&gt;Anyways, you are probably going to have to encode or decode strings in base64 and it's sometimes a bit of a pain. The commonly accepted method is to simply use the linux echo and base64 binaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ma string"&lt;/span&gt; | &lt;span class="nb"&gt;base64
&lt;/span&gt;&lt;span class="nv"&gt;bWEgc3RyaW5nCg&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;

&lt;span class="nb"&gt;echo &lt;/span&gt;&lt;span class="nv"&gt;bWEgc3RyaW5nCg&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
my string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a pain to type, but it's relatively trivial.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's a trap!
&lt;/h2&gt;

&lt;p&gt;Except there are traps!&lt;/p&gt;

&lt;p&gt;The first one you will get when encoding. In my first example, the string is very short. And sometimes, size matters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"my long string"&lt;/span&gt; | &lt;span class="nb"&gt;base64
&lt;/span&gt;bWEgc3RyaW5nIHRyw6hzIGxvbmd1ZSBzdHJpbmcgcG91ciBtb250cmVyIHF1ZSDDp2EgdmEgcGFz
&lt;span class="nv"&gt;IGxlIGZhaXJlCg&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we end up with a line break in our output string. But, if you copy and paste this into your Kubernetes YAML, you're going to get a big syntax error.&lt;/p&gt;

&lt;p&gt;The YAML will only be valid if you put the entire string, on a single line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"my long string"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-w0&lt;/span&gt;
&lt;span class="nv"&gt;bWEgc3RyaW5nIHRyw6hzIGxvbmd1ZSBzdHJpbmcgcG91ciBtb250cmVyIHF1ZSDDp2EgdmEgcGFzIGxlIGZhaXJlCg&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it's not over!&lt;/p&gt;

&lt;p&gt;The 2nd trap is again a line break issue, but in the base64 string this time.&lt;/p&gt;

&lt;p&gt;In fact, it's super treacherous because you won't see it on the screen at first, but you should know that echo adds a line break at the end of your string. The return you got in base64 therefore contains a line break, which will almost systematically be unwanted when managing Secrets.&lt;/p&gt;

&lt;p&gt;So the correct command is not echo but echo -n !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"my string"&lt;/span&gt; | &lt;span class="nb"&gt;base64
&lt;/span&gt;&lt;span class="nv"&gt;bWEgc3RyaW5nCg&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"my string"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-w0&lt;/span&gt;
bWEgc3RyaW5n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Okay this is starting to get really annoying...
&lt;/h3&gt;

&lt;p&gt;To decode fortunately, it is simpler. The command given at the beginning is enough, even if it will be safer to add the “-n” to the echo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; bWEgc3RyaW5n | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
my string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gain some characters
&lt;/h3&gt;

&lt;p&gt;Since I'm lazy, I looked for a trick to save a few characters to type. There is a solution, but unfortunately it only works for decode, since in the case of encoding we risk adding an unwanted line break:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;bWEgc3RyaW5n | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; bWEgc3RyaW5n
my string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just saved 3 characters but especially a “|”, much more difficult to do on a standard qwerty keyboard than 3 “&amp;lt;”.&lt;/p&gt;

&lt;h2&gt;
  
  
  A little simpler
&lt;/h2&gt;

&lt;p&gt;Here's a ittle script to make our lives easier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; b64 &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; 
&amp;gt; #!/bin/bash
&amp;gt; echo -e "Base64 encoding.. &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"
&amp;gt; for arg in "&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;@"; do
&amp;gt;   echo "&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;arg :"
&amp;gt;   echo -n "&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;arg" | base64
&amp;gt;   echo
&amp;gt; done
&amp;gt; EOF
~&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;cat &amp;gt; b64d &amp;lt;&amp;lt;EOF 
&amp;gt; #!/bin/bash
&amp;gt; echo -e "Base64 decoding.. &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"
&amp;gt; for arg in "&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;@"; do
&amp;gt;   echo "&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;arg :"
&amp;gt;   echo -n "&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;arg" | base64 -d
&amp;gt;   echo
&amp;gt; done
&amp;gt; EOF
~&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;sudo cp b64* /usr/local/bin/
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now directly invoke b64 followed by any number of strings to have their value encoded, or b64d followed by any number of strings to decode them.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>tutorial</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I am an Avid Vim User, Finally Migrated to Neovim! How does it work, what do I gain from it?</title>
      <dc:creator>Umair-khurshid</dc:creator>
      <pubDate>Sun, 23 Jun 2024 19:00:05 +0000</pubDate>
      <link>https://forem.com/umairk/i-a-avid-vim-user-finally-migrated-to-neovim-how-does-it-work-what-do-i-gain-from-it-3a24</link>
      <guid>https://forem.com/umairk/i-a-avid-vim-user-finally-migrated-to-neovim-how-does-it-work-what-do-i-gain-from-it-3a24</guid>
      <description>&lt;p&gt;Having migrated to Neovim, I will give you some feedback and give you the keys to understanding and succeeding in your migration to Neovim! First of all, a little context and history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vim, the essential
&lt;/h2&gt;

&lt;p&gt;Who doesn't know Vim, if only through jokes about how to quit it? And for good reason Vim - or often its predecessor Vi, which has been around for over 44 years - often remains our most faithful ally, especially in minimal environments.&lt;/p&gt;

&lt;p&gt;Developed in 1976 by Bill Joy, Vi was a real revolution, notably by introducing the use of the entire screen, which for the time was a real revolution. It must be said that at that time the majority of text editing was done using ed, from which Vi and Vim will inherit the modal aspect.&lt;/p&gt;

&lt;p&gt;A decade later, a certain Vi user Bram Moolenaar sought to port it to the Amiga. He ended up developing version 1.0 of Vim in C in 1988. This version was intended to be an improved version of Vi, hence the acronym (VI iMproved). &lt;/p&gt;

&lt;p&gt;Vim continues to evolve from year to year still in the hands of Bram Moolenaar, even if the pace of this evolution has decreased over the last 2 decades. This slowdown can be accentuated by the very closed contribution management policy. The proposals are complex to have the creator accept. &lt;/p&gt;

&lt;h2&gt;
  
  
  NeoVim, reinventing yourself without forgetting yourself
&lt;/h2&gt;

&lt;p&gt;We might as well admit it, Vim development issues ended up impacting the user community. So much so that in 2014 part of the Vim community embarked on the NeoVim project, notably launching a fundraiser which was a success. The goal of NeoVim is simple: to create a more modern, extensible Vim, with better integrations, and of course a more efficient development community.&lt;/p&gt;

&lt;p&gt;From December 2015, version 0.1 of NeoVim was released, offering support for a very large part of Vim's functionalities. The community will quickly expand and the number of users will increase. The versions will also follow one another, regularly offering new features. To give you an idea, today we are at version 0.10.&lt;/p&gt;

&lt;p&gt;In short, a project which has already proven itself and which continues to evolve by gaining more and more features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why am I using Vim / NeoVim in 2024?
&lt;/h2&gt;

&lt;p&gt;Except for specific development needs, I assume that the majority of you use VSCode, although I have no doubt that the more hipsters use an IDE from the IntelliJ suite. First of all, yes, Vim/Neovim are not IDEs, but code editors. That's not to say they can't fulfill the same needs as an IDE once custom configuration and plugins are added. In short, yes, in my opinion and for my use, it is comparable in this case.&lt;/p&gt;

&lt;p&gt;I haven't always used Vim, I started on Eclipse in my early years when I was into Java EE development. Like many people, I suppose, I had the impression of using heavy software, full of overpowering features. But ultimately having the use of too little. Especially since at that time, I was still a student, I might as well tell you that when you move from Java to system-oriented C, your IDE is no longer suitable.&lt;/p&gt;

&lt;p&gt;After that, I went to the dark side. Needless to say, I spent more time in front of a terminal than anything else, even if automation made it possible to limit manual tasks. Unfortunately, sometimes we have no choice and have to make changes often via SSH. Suffice it to say that your IDE will be of little help to you. So I did like everyone else, use Vim. At the beginning, it's complicated: modal functioning seems from another time and it feels like we are doing violence to ourselves. Over time, I found myself working largely over an SSH connection and had to start getting into Vim and Tmux, which remains, in my opinion, an excellent combo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyw6pc7jg09su3e7t0q1q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyw6pc7jg09su3e7t0q1q.png" alt="tmux" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, I went back to working on my job. I could have started with an IDE, but in the end, I was starting to adapt to Vim. I wasn't an expert, but it was enough for my job. Over time, I started to get comfortable, added plugins that really changed my perception of Vim. From a very basic text editor, where the most advanced feature was syntax highlighting, I moved to an editor on steroids, with a real compression engine, Git integration, and lots of other tools. In short, everything I needed.&lt;/p&gt;

&lt;p&gt;But around this time Atom and later VSCode gained popularity, particularly in the DevOps environment. I'm not going to lie to you: I tried it. It was at this moment that I understood two things: Vim, with my configuration and my plugins, was just as powerful in terms of functionality for my use and above all, Vim had changed the way I worked. When I say “changed my way of working”, it is, in particular, for a detail that will seem stupid to you: Vim is in a terminal. Coupled with Tmux it has become, for me, an ideal combo. The organization of my Gnome workspaces, my screens, in fact my entire work workflow ended up being focused on this. So I decided to return to Vim, while continuing to develop my configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  What changes daily
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafr6mbqpoh5qra004kly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafr6mbqpoh5qra004kly.png" alt="Nvim meme" width="493" height="328"&gt;&lt;/a&gt;&lt;br&gt;
When I saw Neovim pass by, it seemed to me that it was in 0.4. At the time, I said to myself: “ah, another fork that doesn’t add much”. So, I stayed on Vim. Especially since version 8, released recently at that time, brought cool features, notably asynchronous support. I still followed the evolution of NeoVim from afar.&lt;/p&gt;

&lt;p&gt;One day, a new version 0.5 of NeoVim was released, and this was, I think, a real argument to start considering migration. This update brought a lot of very interesting features. Of course a fully integrated client for the LSP (we will talk about it later), better support for Lua configuration,and a new parsing system for syntax coloring in particular (Tree-sitter).&lt;/p&gt;

&lt;p&gt;In the end I ended up giving in and testing it in front of the list of its contributions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A client for directly integrated LSP&lt;/li&gt;
&lt;li&gt;Being able to configure in Lua: Vimscript quickly has its limits&lt;/li&gt;
&lt;li&gt;More open: many interesting plugins are available only on NeoVim&lt;/li&gt;
&lt;li&gt;Better documentation &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Casually, a more dynamic community, often with a modern approach&lt;br&gt;
I will spare you the bug fixes and little everyday joys, especially on the default settings, which are much less austere than Vi or even Vim. For many, this list must be vague and that is normal! Beyond the list, I suggest you take a quick tour of these new features, what they bring and especially how they work.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lua
&lt;/h3&gt;

&lt;p&gt;If you are a minimum advanced Vim user you have already encountered the famous VimScript, the language which allows you to configure your installation, but also to create plugins. It used to be an unpleasant point for a lot of people, including me. With Lua we have gained in comfort and possibilities.&lt;/p&gt;

&lt;p&gt;I was a little afraid of having trouble at first having never used Lua, but it's quite clear and simple. To be more comfortable, I still took a few minutes to know the basics and for that I recommend this &lt;a href="https://learnxinyminutes.com/docs/lua/" rel="noopener noreferrer"&gt;site.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing is still worth noting: you can have a lot of problems if, like me, you cut your code too much. Either way we can correct it, but personally it tired me out a lot for a minimal contribution so I put all my code in a file. &lt;/p&gt;

&lt;p&gt;Small example of code in Lua:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function map(mode, shortcut, command)
  vim.api.nvim_set_keymap(mode, shortcut, command, { noremap = true, silent = true })
end
map('', '&amp;lt;C-D&amp;gt;', ':Telescope find_files&amp;lt;CR&amp;gt;')
map('', '&amp;lt;C-F&amp;gt;', ':Telescope grep_string&amp;lt;CR&amp;gt;')
map('', '&amp;lt;C-X&amp;gt;', ':NvimTreeToggle&amp;lt;CR&amp;gt;')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Packer
&lt;/h3&gt;

&lt;p&gt;I have been talking about plugins since the beginning of the article, but using a simple editor doesn't involve doing everything by hand. So I have been using a plugin manager for a long time and if you don't, I strongly advise you to get started: it's very practical. I used &lt;a href="https://github.com/junegunn/vim-plug" rel="noopener noreferrer"&gt;Vim plug&lt;/a&gt; which was everything I like: simple and effective.&lt;/p&gt;

&lt;p&gt;But with NeoVim, a whole new world of plugins is available to us. And among these plugins, one of them, very popular, allows you to manage plugins: &lt;em&gt;it is called &lt;a href="https://github.com/wbthomason/packer.nvim" rel="noopener noreferrer"&gt;Packer&lt;/a&gt; and is not developed by Hashicorp.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This offers, in my opinion, everything I could expect from a plugin manager under Neovim:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developed and configured in Lua&lt;/li&gt;
&lt;li&gt;Manage dependencies&lt;/li&gt;
&lt;li&gt;Lots of installation and management options&lt;/li&gt;
&lt;li&gt;Manages installations through asynchronous tasks&lt;/li&gt;
&lt;li&gt;Supports Git especially in terms of tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The manager works well, allows you to install, update and delete different plugins. Beyond that, it installs easily and automatically with just a few lines of Lua code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local fn = vim.fn
-- Automatically install packer
local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim"
if fn.empty(fn.glob(install_path)) &amp;gt; 0 then
  PACKER_BOOTSTRAP = fn.system {
    "git",
    "clone",
    "--depth",
    "1",
    "https://github.com/wbthomason/packer.nvim",
    install_path,
  }
  print "Installing packer close and reopen Neovim..."
  vim.cmd [[packadd packer.nvim]]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installing plugins is just as simple and efficient:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('packer').startup(function(use)
  use 'wbthomason/packer.nvim' -- Package manager
    # Put all your plugins
  use { 'nvim-telescope/telescope.nvim', tag="nvim-0.6", requires = { 'nvim-lua/plenary.nvim' } } #Plugin with a dependency 
tag
end)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To interact with Packer: you just need to use the NeoVim console to execute commands, such as &lt;em&gt;PackerInstall&lt;/em&gt; and_ PackerSync_.&lt;/p&gt;

&lt;p&gt;Please note: Neovim having a more regular development cycle, the plugins are also often updated. If you are not using the latest version of Neovim, do not hesitate to tag the plugin installations. I had some unfortunate surprises: plugins, which, once updated, were no longer compatible with older versions of NeoVim. This is done simply as in the example given above.&lt;/p&gt;

&lt;h3&gt;
  
  
  LSP
&lt;/h3&gt;

&lt;p&gt;One of the weaknesses of Vim, for a long time, was the quality of comprehension, more especially of the engine which allowed the editor to understand the structure of the code in order to do autocompletion or even to notice errors. Syntactic problems and so on.&lt;/p&gt;

&lt;p&gt;This situation has already changed thanks to Language Server Protocol and the numerous implementations based on Json-RPC.&lt;br&gt;
Neovim provides a perfectly functional native client, which simplifes installation, and allow us to benefit from features worthy of the most popular editors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4w2unmsw6mxkmhrrn1n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4w2unmsw6mxkmhrrn1n9.png" alt="Neovim lsp" width="770" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It should be noted that, although Neovim integrates the client, certain plugins are necessary for LSP to give you a better integration experience. I advise you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nvim-lsp-installer which allows you to install language servers directly from the Neovim console&lt;/li&gt;
&lt;li&gt;nvim-lspconfig which brings together a set of basic configurations for LSP&lt;/li&gt;
&lt;li&gt;cmp-nvim-lua which displays small windows for autocompletion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to verify that your editor has detected the language and is using the correct server, you can use the command: &lt;em&gt;LspInfo&lt;/em&gt;, which will show you all the LSP client information.&lt;/p&gt;

&lt;p&gt;It may happen that your editor does not associate a file type with the language server. In this case, you can specify it, as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require'lspconfig'.terraformls.setup{
    capabilities = capabilities,
    filetypes = { "tf", "tfvar", "terraform" }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bonus tip, you can run a diagnostic of your Neovim, in order to identify certain problems. For this just run:_ checkhealth_.&lt;/p&gt;

&lt;h3&gt;
  
  
  Telescope, boosted fzf
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fht6t0gcv3eiafv2czk7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fht6t0gcv3eiafv2czk7t.png" alt="Neovim telescope" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Very often when you start customizing your Vim or Neovim, you install a plugin allowing you to display the tree structure in your editor. It's nice, it allows you to have a view of the structure, but moving from one file to another is slow. So, very quickly, we turn to &lt;a href="https://github.com/junegunn/fzf" rel="noopener noreferrer"&gt;Fuzzy-finder&lt;/a&gt;. And there, generally, we come back to life and we no longer want to leave our publisher.&lt;/p&gt;

&lt;p&gt;Fzf is good, but as I said above, Neovim offers a lot of new plugins with new implementations. And among them, a supercharged fzf: &lt;a href="https://github.com/nvim-telescope/telescope.nvim" rel="noopener noreferrer"&gt;Telescope&lt;/a&gt;! It allows you to search for files, and even text patterns, while offering an interface with file previews! A must have , quite simply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally the version of Vim we have been waiting for?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwfvv5lxhpdt8pc7rzv5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwfvv5lxhpdt8pc7rzv5.jpeg" alt="Neovim IDE" width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I decided to migrate to Neovim, I preferred to do away with Vimscripts, in favor of Lua. And looking back, I think it was the right approach. However, I must admit that I wasted a lot of time, particularly in wanting, at all costs, to divide my configuration files too much, which Lua obviously doesn't like. I ended up using a simple base I found online and adapting it to my taste. I still kept the theme which is a nice homage to Atom.io which I had tried.&lt;/p&gt;

&lt;p&gt;Vim was clearly my main IDE / code editor, I hesitated to change for a long time, not being sure of the contribution. In the end, the transition is going well: Neovim is a great development, but it does not destroy Vim's heritage. We therefore find the modal system, the lightness, the native terminal operation and everything that makes Vim so remarkable. &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>devops</category>
      <category>opensource</category>
      <category>linux</category>
    </item>
    <item>
      <title>Disable Effects of a Controller On its Pods in Kubernetes</title>
      <dc:creator>Umair-khurshid</dc:creator>
      <pubDate>Fri, 21 Jun 2024 20:57:34 +0000</pubDate>
      <link>https://forem.com/umairk/disable-effects-of-a-controller-on-its-pods-in-kubernetes-64a</link>
      <guid>https://forem.com/umairk/disable-effects-of-a-controller-on-its-pods-in-kubernetes-64a</guid>
      <description>&lt;p&gt;A controller is the name for several different elements in Kubernetes. One of these elements designates the global name of any resource responsible, among other things, for the creation and lifecycle management of the pods.&lt;/p&gt;

&lt;p&gt;A typical controller is a Deployment, which is used to deploy pods in several replicas but is also responsible for destroying or recreating them as needed. The other three most used types of controllers are StatefulSet, DaemonSet, and Job. When working with controllers, we may want to prevent them from making changes to pods temporarily. So, how do we do it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The cleanest solution (STS only)
&lt;/h2&gt;

&lt;p&gt;In the case of an StatefulSet (STS), we have a significant difference compared to a dDeployment, it is the presence of Rolling Update Strategies, at the root of spec, of which here is the entire API with the values ​​by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spec:
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;What we are interested in is &lt;em&gt;spec.updateStrategy.rollingUpdate.partition&lt;/em&gt;. This option is only available if &lt;em&gt;spec.updateStrategy.type&lt;/em&gt; is set to RollingUpdate. It allows you to specify, in a StatefulSet, the pod ordinal above which modifications made to the controller will be propagated. In other words, with the default value of 0, all pods will be updated when the StatefulSet changes. If set to 1, then all pods will be updated except the first pod, whose name ends with -0.&lt;/p&gt;

&lt;p&gt;This allows for canary deployment at a lower cost, such as modifying the image of only 30% of the pods to gradually introduce an update. The command to patch a StatefulSet is as follows:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sts=postgres
part=2
kubectl patch statefulset $sts -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":'$part'}}}}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the case of a canary deployment, we could first modify the image of a container in the pod template, then deploy the modifications gradually by regularly patching the controller and lowering the partition value step by step.&lt;/p&gt;

&lt;p&gt;Note that this will not prevent a pod from restarting if it is deleted; it only affects modifications to the pod template. For handling pod restarts, continue reading.&lt;/p&gt;

&lt;p&gt;Without a controller, there won't be any deletion or recreation of pods against your will. However, if you delete a controller, the pods created by it will disappear. To prevent this, you can use an option with the kubectl delete command that prevents a controller from eliminating its child pods. This option is --cascade=false (since it is true by default).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl delete sts postgresql --cascade=false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When deleting a controller this way, Kubernetes still removes the ownerReferences objects from all child pods, but does nothing else. You can then, for example, delete a pod and mount its data volume in a new pod for a special operation (such as an advanced backup). Using the backup example, this method can also be used to turn off the pods of a StatefulSet one by one and take the time to perform a cold backup of the data on the storage side.&lt;/p&gt;

&lt;p&gt;However, you should remember to recreate the deleted controller if you want to keep the pods alive after the operation. Here is a bash script that provides the basics of using this method properly:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;This script ensures that the controller is recreated as is once the operation is completed or if the script encounters a problem, or if the user kills it prematurely (except in the case of a kill -9 of course).&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
