Aller au contenu principal

Templates Proxmox avec Packer et Ansible

Dans le monde de l'infrastructure informatique, l'automatisation et la sécurisation des environnements sont devenus des enjeux majeurs. Je vais vous parler aujourd'hui de la construction de templates Proxmox en utilisant Packer, tout en intégrant Ansible comme provisionner. Cet assemblage d'outils permet de créer des images de machines virtuelles de manière efficace, reproductible et sécurisée. Proxmox offre une solution robuste pour la virtualisation, tandis que Packer simplifie la création d'images de machines virtuelles de manière automatisée. L'utilisation d'Ansible pour le provisionnement ajoute une couche supplémentaire d'automatisation, permettant de configurer les machines selon des spécifications précises dès leur création.

Concepts Fondamentaux

Avant de plonger dans les détails techniques de la construction de templates Proxmox avec Packer et Ansible, il est essentiel de comprendre les concepts fondamentaux qui sous-tendent ces outils.

Proxmox est une plateforme de gestion de virtualisation open-source qui permet de déployer et de gérer des machines virtuelles (VMs) et des conteneurs. Elle combine les fonctionnalités de virtualisation basée sur KVM et de conteneurisation avec LXC, offrant ainsi une solution complète pour la virtualisation d'infrastructures.

Packer, de son côté, est un outil open-source conçu pour créer des images de machines virtuelles de manière automatisée à partir d'un fichier de configuration unique. Packer prend en charge de multiples fournisseurs de plateformes de virtualisation, y compris Proxmox, ce qui le rend particulièrement utile pour préparer des environnements virtualisés qui peuvent être déployés rapidement et de manière reproductible.

Ansible est un outil d'automatisation qui permet de configurer et de gérer des serveurs. Il utilise une approche déclarative pour automatiser le provisionnement, le déploiement d'applications, et d'autres tâches d'administration système. En intégrant Ansible avec Packer, on peut non seulement créer des images de machines virtuelles, mais également les configurer selon des exigences précises dès leur création, en utilisant des playbooks Ansible.

La combinaison de ces trois outils crée un workflow puissant pour la gestion d'infrastructures virtualisées, où Proxmox fournit la plateforme de virtualisation, Packer automatise la création d'images VM prêtes à l'emploi, et Ansible assure leur configuration automatique et conforme aux standards de sécurité tels que ceux définis par l'ANSSI et les CIS Benchmarks. Ce workflow non seulement simplifie le déploiement d'environnements virtualisés, mais garantit également leur conformité aux meilleures pratiques de sécurité dès le moment de leur création.

Configuration de l'environnement

Maintenant que nous avons accès à notre serveur Proxmox, nous pouvons installer Packer et Ansible sur notre machine de rebonds.

Dans une premier, nous allons configurer Proxmox pour accepter des connexions API pour permettre à Packer de communiquer avec Proxmox lors de la création des templates.

Connectez-vous à votre serveur Proxmox via SSH ou accédez à son terminal si vous y avez un accès physique.

Proxmox permet de créer des rôles personnalisés avec des permissions spécifiques. Utilisez la commande suivante, en vous connectant en ssh auparavant, pour créer un nouveau rôle (par exemple, Packer) avec des permissions adaptées à Packer:

sudo -i
pveum role add Packer -privs "Datastore.Allocate Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Console VM.Migrate VM.Monitor VM.PowerMgmt SDN.Use"

Cette commande crée un rôle Packer avec des privilèges adaptés pour gérer les machines virtuelles.

Créez un utilisateur spécifique pour Terraform. Par exemple, pour créer un utilisateur packer dans le domaine @pve avec un mot de passe, utilisez:

pveum user add packerv@pve --password <password>

Après avoir créé l'utilisateur, attribuez-lui le rôle créé précédemment. Vous pouvez le faire pour l'ensemble du datacenter :

pveum aclmod / -user packer@pve -role Packer

Cette commande assigne le rôle Packer à packer@pve pour toutes les ressources du datacenter.

Pour une intégration sécurisée et efficace entre Packer et Proxmox, l'utilisation d'un token API est recommandée. Cela permet à Packer de se connecter et d'interagir avec Proxmox sans nécessiter des informations d'identification utilisateur classiques. Voici la procédure pour créer un token API dans Proxmox.

pveum user token add packer@pve packer -expire 0 -privsep 0 -comment "Packer token"
┌──────────────┬──────────────────────────────────────────────────────────┐
│ key          │ value                                                    │
╞══════════════╪══════════════════════════════════════════════════════════╡
│ full-tokenid │ packer-prov@pve!packer                                   │
├──────────────┼──────────────────────────────────────────────────────────┤
│ info         │ {"comment":"Packer token","expire":"0","privsep":"0"}    │
├──────────────┼──────────────────────────────────────────────────────────┤
│ value        │ 85b12793-73c5-4d72-87b8-54d8dbba6d62                     │
└──────────────┴──────────────────────────────────────────────────────────┘

Création du template Proxmox

La création de templates Proxmox avec Packer est une étape importante pour automatiser la mise en place d'environnements virtualisés. Je vais vous guider à travers les étapes principales pour réussir cette tâche.

Tout commence par la rédaction d'un fichier de configuration HCL pour Packer. Ce fichier détaille les paramètres nécessaires pour créer l'image Proxmox. Il inclut la source du type proxmox-iso contenant les informations d'authentification pour se connecter à l'API Proxmox et les spécifications de la machine virtuelle comme le CPU, la mémoire, l'image iso et le stockage. Attention à bien configurer les paramètres réseau.

packer {
  required_plugins {
    proxmox = {
      version = "1.1.6"
      source  = "github.com/hashicorp/proxmox"
    }
    ansible = {
      version = "~> 1"
      source = "github.com/hashicorp/ansible"
    }

  }
}

variable "proxmox_api_url" {
  type = string
  default = "https://proxmox.robert.local/api2/json"
}

variable "proxmox_api_token_id" {
  type = string
  default = "packer@pve!packer"
}

variable "proxmox_api_token_secret" {
  type      = string
  sensitive = true
}

variable "ssh_username" {
  type      = string
  default = "bob"
}

variable "ssh_password" {
  type      = string
  default = "password"
}

source "proxmox-iso" "pkr-ubuntu-jammy-1" {
  proxmox_url               = "${var.proxmox_api_url}"
  username                  = "${var.proxmox_api_token_id}"
  token                     = "${var.proxmox_api_token_secret}"
  insecure_skip_tls_verify  = false

  node                      = "proxmox1"
  vm_id                     = "90101"
  vm_name                   = "pkr-ubuntu-jammy-1"
  template_description      = "test"

  iso_file                  = "local:iso/ubuntu-22.04.3-live-server-amd64.iso"
  iso_storage_pool          = "local"
  unmount_iso               = true
  qemu_agent                = true

  scsi_controller           = "virtio-scsi-pci"

  cores                     = "2"
  sockets                   = "1"
  memory                    = "2048"

  cloud_init                = true
  cloud_init_storage_pool   = "local"

  vga {
    type                    = "virtio"
  }

  disks {
    disk_size               = "20G"
    format                  = "raw"
    storage_pool            = "local"
    type                    = "virtio"
  }

  network_adapters {
    model                   = "virtio"
    bridge                  = "vmbr0"
    firewall                = "false"
  }

  boot_command = [
    "<esc><wait>",
    "e<wait>",
    "<down><down><down><end>",
    "<bs><bs><bs><bs><wait>",
    "autoinstall ds=nocloud-net\\;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ ---<wait>",
    "<f10><wait>"
  ]

  boot                      = "c"
  boot_wait                 = "6s"
  communicator              = "ssh"

  http_directory            = "./http"
  http_port_min             = 8098
  http_port_max             = 8098

  ssh_username              = "${var.ssh_username}"
  ssh_password              = "${var.ssh_password}"

  # Raise the timeout, when installation takes longer
  ssh_timeout               = "30m"
  ssh_pty                   = true
  ssh_handshake_attempts    = 15
}

build {

  name    = "pkr-ubuntu-jammy-1"
  sources = [
      "source.proxmox-iso.pkr-ubuntu-jammy-1"
  ]

  # Waiting for Cloud-Init to finish
  provisioner "shell" {
    inline = ["cloud-init status --wait"]
  }

  provisioner "ansible" {
    playbook_file = "./template-proxmox.yml"
  }

  # Clean the VM Template
  provisioner "shell" {
    execute_command = "echo -e '<user>' | sudo -S -E bash '{{ .Path }}'"
    inline = [
      "echo 'Clean'",
      "sudo rm /etc/ssh/ssh_host_*",
      "sudo truncate -s 0 /etc/machine-id",
      "sudo apt -y autoremove --purge",
      "sudo apt -y clean",
      "sudo apt -y autoclean",
      "sudo cloud-init clean",
      "sudo rm -f /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg",
      "sudo rm -f /etc/netplan/00-installer-config.yaml",
      "sudo sync",
      "echo 'Done Stage: Provisioning the VM Template for Cloud-Init Integration in Proxmox'"
    ]
  }

  provisioner "file" {
    source      = "files/99-pve.cfg"
    destination = "/tmp/99-pve.cfg"
  }
  provisioner "shell" {
    inline = ["sudo cp /tmp/99-pve.cfg /etc/cloud/cloud.cfg.d/99-pve.cfg"]
  }
}

La seconde partie décrit les opérations de build en commençant par un rappel de la source, puis les opérations de provisionnement.

Le playbook ansible

---
- name: Secure Proxmox Template
  hosts: default
  become: true
  gather_facts: false
  roles:
    - role: stephrobert.motd
      vars:
        motd_banner: " {{ ansible_hostname }} "
    - role: stephrobert.sshd
      vars:
        sshd_allowagentforwarding: "yes"
        sshd_allowtcpforwarding: "yes"
        sshd_allowusers: bob

Passons à la construction du template, mais avant il faut autoriser le port 8098 sur la machine ou vous lancez la construction du template (dans mon ca la machine de rebonds) :

sudo ufw allow 8098

packer build -var "proxmox_api_token_secret=xxxxx-xxxx-xxxxx--xxxxx" .

Utilisation des templates Proxmox

Après le provisionnement, Packer arrête la VM et la convertit en template dans Proxmox. Ce template peut ensuite être utilisé pour déployer rapidement de nouvelles VMs configurées de manière identique, garantissant ainsi un déploiement rapide et conforme des services.

En suivant ces étapes, on peut efficacement automatiser la création de templates Proxmox, réduisant considérablement le temps et les efforts nécessaires pour déployer des environnements virtualisés tout en s'assurant de leur conformité avec les standards de sécurité et de conformité. Quelques exemples de templates ci-après.

HashiCorp Vault

Utiliser Packer et Ansible pour déployer HashiCorp Vault sur Proxmox permet de sécuriser les secrets et les credentials utilisés dans l'ensemble de l'infrastructure. En automatisant la création d'une image VM préconfigurée pour Vault, je m'assure que chaque instance déployée suit les meilleures pratiques de sécurité dès le départ. Cela inclut la configuration automatique du stockage backend, des politiques, et des accès API, réduisant ainsi les erreurs humaines et accélérant le déploiement.

Harbor

Harbor est un registre d'images Docker qui supporte la vulnerabilité scanning et les politiques de RBAC. En créant une image VM avec Packer intégrant Harbor, pré-configurée par Ansible pour s'intégrer à mon environnement sécurisé, je facilite la mise en place et la maintenance de mon propre registre d'images de conteneurs, essentiel pour la gestion des artefacts dans mes projets DevOps.

Nexus

Nexus Repository Manager sert de dépôt central pour gérer les artefacts et les dépendances. Grâce à Packer et Ansible, je déploie Nexus sur Proxmox avec une configuration qui optimise le stockage et sécurise l'accès aux artefacts. Cette approche me permet de centraliser la gestion des dépendances tout en garantissant leur disponibilité et leur intégrité.

GitLab et GitLab Runner

GitLab est au cœur de mon pipeline CI/CD, offrant à la fois gestion de code source, revue de code, et intégration continue. GitLab Runner est utilisé pour exécuter les jobs définis dans mes pipelines. En utilisant Packer pour créer des images VM de GitLab et GitLab Runner pré-configurées avec Ansible, je simplifie leur déploiement sur Proxmox, assurant une intégration et une automatisation fluides de mes pipelines CI/CD. Cela comprend la configuration automatique des runners, l'intégration avec des outils d'analyse de code, et la préparation des environnements de test.

Chacun de ces exemples illustre la puissance de l'automatisation et de la virtualisation dans un homelab DevOps. En utilisant Packer pour construire des images de VM, Ansible pour le provisioning, et Proxmox pour la gestion de la virtualisation, je peux déployer rapidement et efficacement une variété d'outils essentiels au DevOps, tout en maintenant une configuration cohérente, sécurisée, et optimisée. Cette approche réduit considérablement le temps et l'effort nécessaires pour gérer l'infrastructure, permettant une plus grande concentration sur l'innovation et l'amélioration continue.

Conclusion

En conclusion, l'automatisation de la création d'images de VM avec Packer et Ansible sur Proxmox représente une approche puissante pour améliorer l'efficacité, la cohérence et la sécurité dans un environnement DevOps, en particulier dans un homelab.

L'utilisation de Packer pour construire des images VM préconfigurées, combinée à la puissance d'Ansible pour le provisioning automatisé, simplifie le déploiement de services et d'applications. En tirant parti de Proxmox pour la gestion de la virtualisation, nous pouvons créer un environnement flexible et évolutif qui soutient le développement et le déploiement rapide de solutions logicielles.

À travers des exemples pratiques que nous verrons dans les prochains guides, comme la mise en place de services tels que HashiCorp Vault, Harbor, Nexus, GitLab, et GitLab Runner, nous verrons comment ces techniques peuvent être appliquées pour faciliter la gestion des VMs, renforcer la sécurité et soutenir les pipelines CI/CD dans un homelab DevOps.

En définitive, l'objectif de ce guide n'était pas seulement de vous montrer comment automatiser la création d'images VM, mais aussi de vous inspirer à explorer de nouvelles façons d'optimiser et de sécuriser votre infrastructure. L'automatisation est au cœur de l'efficacité en DevOps, et en maîtrisant ces outils, vous êtes bien équipé pour relever les défis futurs et tirer le meilleur parti de votre homelab DevOps.