Aller au contenu

VMware - Configuration Packer

Configuration des templates Packer HCL pour construire des images VM sur vSphere.


Structure du projet

mkdir -p packer-vsphere/ansible/roles/{guest,hardening,container_engine,system_metrics}/{tasks,handlers,defaults,vars}
mkdir -p packer-vsphere/http

Structure cible :

packer-vsphere/
├── rocky9-server.pkr.hcl          # Template principal (vsphere-iso)
├── rocky9-clone.pkr.hcl           # Alternative (vsphere-clone)
├── variables.pkr.hcl              # Variables
├── rocky9.auto.pkrvars.hcl        # Valeurs des variables
├── http/
│   └── ks.cfg                     # Kickstart Rocky 9
└── ansible/
    ├── playbook.yml
    ├── requirements.yml
    └── roles/
        ├── guest/
        ├── hardening/
        ├── container_engine/
        └── system_metrics/

Plugin requis

Packer a besoin du plugin vsphere. Declarez-le dans votre template.

Template principal (vsphere-iso)

Créez packer-vsphere/rocky9-server.pkr.hcl :

packer {
  required_plugins {
    vsphere = {
      version = ">= 1.3.0"
      source  = "github.com/hashicorp/vsphere"
    }
    ansible = {
      version = ">= 1.1.0"
      source  = "github.com/hashicorp/ansible"
    }
  }
}

source "vsphere-iso" "rocky9-server" {
  # --- Connexion vCenter ---
  vcenter_server      = var.vcenter_server
  username            = var.vcenter_username
  password            = var.vcenter_password
  insecure_connection = var.vcenter_insecure

  # --- Placement ---
  datacenter = var.datacenter
  cluster    = var.cluster
  datastore  = var.datastore
  folder     = var.vm_folder

  # --- VM ---
  vm_name       = "rocky9-server-{{timestamp}}"
  guest_os_type = "rhel9_64Guest"
  CPUs          = var.vm_cpus
  RAM           = var.vm_ram
  disk_controller_type = ["pvscsi"]
  storage {
    disk_size             = var.vm_disk_size
    disk_thin_provisioned = true
  }
  network_adapters {
    network      = var.network
    network_card = "vmxnet3"
  }

  # --- Installation automatisee ---
  iso_paths = ["[${var.datastore}] ISO/Rocky-9-latest-x86_64-minimal.iso"]

  http_directory = "http"
  boot_wait      = "5s"
  boot_command = [
    "<up><wait>",
    "e<wait>",
    "<down><down><end>",
    " inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg",
    "<leftCtrlOn>x<leftCtrlOff>"
  ]

  ssh_username = "packer"
  ssh_password = "packer"
  ssh_timeout  = "30m"

  # --- Sortie ---
  convert_to_template = true
}

build {
  sources = ["source.vsphere-iso.rocky9-server"]

  provisioner "ansible" {
    playbook_file = "./ansible/playbook.yml"
    user          = "packer"
    extra_arguments = [
      "--scp-extra-args", "'-O'"
    ]
  }
}

Alternative : vsphere-clone

Créez packer-vsphere/rocky9-clone.pkr.hcl :

packer {
  required_plugins {
    vsphere = {
      version = ">= 1.3.0"
      source  = "github.com/hashicorp/vsphere"
    }
    ansible = {
      version = ">= 1.1.0"
      source  = "github.com/hashicorp/ansible"
    }
  }
}

source "vsphere-clone" "rocky9-server" {
  vcenter_server      = var.vcenter_server
  username            = var.vcenter_username
  password            = var.vcenter_password
  insecure_connection = var.vcenter_insecure

  datacenter = var.datacenter
  cluster    = var.cluster
  datastore  = var.datastore
  folder     = var.vm_folder

  template     = var.source_template
  vm_name      = "rocky9-server-{{timestamp}}"
  linked_clone = false

  ssh_username = "packer"
  ssh_password = "packer"

  convert_to_template = true
}

build {
  sources = ["source.vsphere-clone.rocky9-server"]

  provisioner "ansible" {
    playbook_file = "./ansible/playbook.yml"
    user          = "packer"
    extra_arguments = [
      "--scp-extra-args", "'-O'"
    ]
  }
}

Quand utiliser vsphere-clone

Utilisez vsphere-clone quand un template de base existe déjà (provisionne par un autre processus ou fourni par l'équipe plateforme). Le build est plus rapide car il n'y a pas d'installation OS.

Variables

Créez packer-vsphere/variables.pkr.hcl :

# --- Connexion vCenter ---
variable "vcenter_server" {
  type        = string
  description = "Adresse du serveur vCenter"
}

variable "vcenter_username" {
  type        = string
  description = "Utilisateur vCenter"
}

variable "vcenter_password" {
  type        = string
  sensitive   = true
  description = "Mot de passe vCenter"
}

variable "vcenter_insecure" {
  type        = bool
  default     = false
  description = "Ignorer la verification du certificat TLS vCenter"
}

# --- Placement ---
variable "datacenter" {
  type        = string
  description = "Nom du datacenter vSphere"
}

variable "cluster" {
  type        = string
  description = "Nom du cluster vSphere"
}

variable "datastore" {
  type        = string
  description = "Nom du datastore"
}

variable "vm_folder" {
  type        = string
  default     = "Templates/Packer"
  description = "Dossier VM dans l'inventaire vCenter"
}

variable "network" {
  type        = string
  description = "Nom du port group reseau"
}

# --- VM ---
variable "vm_cpus" {
  type        = number
  default     = 2
  description = "Nombre de vCPU"
}

variable "vm_ram" {
  type        = number
  default     = 4096
  description = "Memoire en Mo"
}

variable "vm_disk_size" {
  type        = number
  default     = 40960
  description = "Taille du disque en Mo"
}

# --- Clone ---
variable "source_template" {
  type        = string
  default     = "rocky9-base-template"
  description = "Template source pour vsphere-clone"
}

Valeurs des variables

Créez packer-vsphere/rocky9.auto.pkrvars.hcl :

vcenter_server   = "vcenter.example.com"
vcenter_username = "packer-builder@vsphere.local"
vcenter_password = "CHANGE_ME"
vcenter_insecure = true

datacenter = "DC-Paris"
cluster    = "Cluster-Prod"
datastore  = "DS-SSD-01"
vm_folder  = "Templates/Packer"
network    = "VLAN-120-Build"

Ne pas commiter vos valeurs

Ajoutez *.auto.pkrvars.hcl a votre .gitignore. Commitez un fichier rocky9.auto.pkrvars.hcl.example avec des placeholders.

Authentification

Méthode A : Utilisateur / mot de passe (simple)

Les variables vcenter_username et vcenter_password dans le fichier .auto.pkrvars.hcl. Simple pour débuter.

Sécurité

  • Ne commitez jamais le mot de passe en clair
  • Utilisez des variables d'environnement :
export PKR_VAR_vcenter_password="mon-mot-de-passe"

Méthode B : Service account vSphere (recommandee)

Créez un compte de service dédié avec un rôle custom minimal.

Rôle custom Packer

Dans vCenter, créez un rôle Packer Builder avec ces privileges :

Catégorie Privileges
Virtual Machine > Interaction Power On, Power Off, Console
Virtual Machine > Edit Inventory Create new, Remove
Virtual Machine > Provisioning Clone, Template, Customize
Virtual Machine > Configuration All
Datastore Allocate Space, Browse Datastore
Network Assign Network
Resource Assign VM to Resource Pool
Host > Local Opérations Create VM, Delete VM

Créer le service account

Dans vCenter :

  1. Administration > SSO > Users and Groups
  2. Créer l'utilisateur packer-builder@vsphere.local
  3. Administration > Access Control > Global Permissions
  4. Attribuer le rôle Packer Builder a packer-builder@vsphere.local avec propagation

VCF / Aria

Sur VMware Cloud Foundation, le service account peut être créé dans le SDDC Manager. Les permissions se propagent automatiquement au vCenter intégré.

Initialisation

cd packer-vsphere
packer init .

Attendu :

Installed plugin github.com/hashicorp/vsphere v1.x.x ...
Installed plugin github.com/hashicorp/ansible v1.x.x ...

Validation

packer validate .

Attendu :

The configuration is valid.

Livrable

Checklist

Avant de passer à la suite, verifiez que :

  • La structure du projet est créée
  • packer init . téléchargé les plugins vsphere et ansible sans erreur
  • packer validate . retourné The configuration is valid
  • Le service account vSphere est créé avec le rôle custom (méthode B)
  • Les variables sensibles ne sont pas commitees