====== Terraform & Proxmox ====== Le 2023-12-21 ===== Avant-Propos ===== **Terraform** est un outil **IAC** (Infrastructure As Code) développé par //Hashicorps//. Il permet grâce à une syntaxe déclarative relativement simple de créer une infrastructure dans le //cloud// ou en //on-premise//. Terraform dispose de nombreux fournisseurs (providers) adaptés aux principaux environnements du marché (kubernetes, Azure, AWS, GCP, Openstack, Vsphere, Proxmox, ...). Il est habituellement utilisé pour créer des VM ensuite configurées par des **playbooks** **Ansible** Des changements de licence récents concernant Terraform ont conduit à la création de la fondation **Opentofu** (https://opentofu.org) visant à créer un outil disposant d'une licence moins restrictive et compatible avec Terraform ... cf le site de //Stéphane Robert// : * https://blog.stephane-robert.info/docs/infra-as-code/provisionnement/terraform/introduction ===== Installation de Terraform ===== Sur une Debian 12 Bookworm, la dernière version est la **1.6.6** (au 21/12/2023) sudo apt install software-properties-common curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main" sudo apt update sudo apt install terraform ... terraform --version Terraform v1.6.6 on linux_amd64 ===== Mise en oeuvre de Terraform avec le provider BPG/Proxmox ===== L'objectif est ici d'utiliser **Terraform** pour déployer automatiquement des VM KVM sur un serveur **Proxmox 8**. 4 étapes : **init**, **plan**, **apply**, **destroy** {{:terraform-cycle.png?400|}} Les commandes de base **Terraform** : * **init** : Prépare le répertoire pour Terraform * **validate** : vérifie la validité de la configuration * **plan** : montre les changements requis par la configuration * **apply** : crée ou met à jour l'infrastructure * **destroy** : détruit l'infrastructure précédemment créée ==== 1 - init ==== mkdir infra-prj && cd infra-prj touch provider.tf main.tf vars.tf le fichier **provider.tf** (minimal) - On utilise ici le provider **BPG/Proxmox** (maintenu depuis la version 0.42.0 et compatible avec Proxmox 8.1) cf : * https://github.com/bpg/terraform-provider-proxmox * https://blog.stephane-robert.info/docs/virtualiser/type1/proxmox/terraform/#cr%C3%A9ation-de-la-vm et plus particulièrement : * https://github.com/bpg/terraform-provider-proxmox/tree/main/howtos * https://github.com/bpg/terraform-provider-proxmox/blob/main/docs/resources/virtual_environment_vm.md terraform { required_providers { proxmox = { source = "bpg/proxmox" version = "0.43" } } } provider "proxmox" { endpoint = "https://192.168.1.100:8006/" username = "root@pam" password = "monmotdepasse" # api_token = "terraform@pve!terraform=7625e302-463c-468c-bff5-a06b9763f50e" insecure = true ssh { agent = true username = "root" node { name = "pve" address = "192.168.1.100" } } } On initialise le répertoire projet avec **terraform init**: # terraform init Initializing the backend... Initializing provider plugins... - Finding telmate/proxmox versions matching "2.9.11"... - Installing telmate/proxmox v2.9.11... - Installed telmate/proxmox v2.9.11 (self-signed, key ID A9EBBE091B35AFCE) Partner and community providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary. ==== 2 - Validate ==== le fichier **main.tf** : il décrit les ressources (VMs, conteneurs, ...) à créer : resource "proxmox_virtual_environment_vm" "debian_vm" { count = 2 name = "test-debian${count.index+1}" node_name = "pve" initialization { ip_config { ipv4 { address = "dhcp" # ou encore address = "192.168.1.100/24" } } user_account { # do not use this in production, configure your own ssh key instead! username = "debian" keys = ["ssh-rsa AAAAB.....UKNwqgOCcE= paul@host"] #password = "password" } } memory { dedicated = 1024 } network_device { bridge = "vmbr0" model = "virtio" } lifecycle { ignore_changes = [ network_device, # on conserve l'adresse MAC pour éviter de régénérer la VM ] } operating_system { type = "l26" } disk { datastore_id = "local-lvm" file_id = proxmox_virtual_environment_file.debian_cloud_image.id interface = "virtio0" iothread = true discard = "on" size = 6 } } resource "proxmox_virtual_environment_file" "debian_cloud_image" { content_type = "iso" datastore_id = "local" node_name = "pve" source_file { # you may download this image locally on your workstation and then use the local path instead of the remote URL path = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2" # path = "/var/www/html/debian-12-genericcloud-amd64.qcow2" # chemin local file_name = "debian-12-genericcloud-amd64.img" } } resource "random_password" "debian_vm_password" { length = 16 override_special = "_%@" special = true } resource "tls_private_key" "debian_vm_key" { algorithm = "RSA" rsa_bits = 2048 } output "debian_vm_public_key" { value = tls_private_key.debian_vm_key.public_key_openssh } } Pour valider la configuration du fichier: terraform validate Pour afficher les changements qui seront réalisés : terraform plan ==== 3. Apply ==== Pour lancer : terraform apply .... Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes ... On peut alors vérifier l'existence des 2 VMs et s'y connecter après avoir récupéré leur adresse IP (connexion console puis ''ip a'') ==== 4. Modification des ressources puis plan ==== * éditer le fichier **main.tf** pour changer la mémoire allouée aux VMs : 1024 => 512 * on peut alors relancer ''terraform plan'' qu affiche uniquement les modifications à effectuer ==== 5. On termine par apply ==== * la commande ''terraform apply'' lance les modifications en suspens et change la mémoire allouée à 512 Mo. ==== 6. Epilogue : on conclut avec un playbook ansible ==== * on peut alors lancer un playbook **ansible** (pour installer Apache par exemple) pour terminer la configuration des VM ...