Nadat ik afgelopen weekend de cursus “Deploying Resources to GCP with Terraform” te hebben voltooid, was het wel eens tijd om te kijken of dat ook werkt op mijn eigen proxmox testomgeving. Hoe kun je servers deployen via Terraform op ProxMox ? Hierbij de stappen die ik gezet heb.
CloudInit
Als eerste hebben we nodig een ProxMox server. Maar dat heb je al als het goed is.
Vervolgens hebben we een CloudInit image nodig. deze zorgt ervoor dat na de installatie er al een aantal dingen worden ingesteld zoals DNS, username en bijv. de ssh keys.
Als eerste maken we even een public key aan welke we kunnen gebruiken.
ssh-keygen -f cloudinit
We gaan er vanuit dat we een Ubuntu 20.04 LTS server willen gaan installeren. We voeren daarvoor de volgende commando’s uit op de proxmox server:
wget http://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img export VM_ID="5000" # Gebruik een hoog ID zodat we niet in conflict komen met VM ID's die we gaan uitrollen qm create $VM_ID --memory 2048 --net0 virtio,bridge=vmbr0 --sockets 1 --cores 2 --vcpu 2 -hotplug network,disk,cpu,memory --agent 1 --name cloud-init-ubuntu20 --ostype l26 qm importdisk $VM_ID focal-server-cloudimg-amd64.img local-lvm # Waarbij local-lvm een storage locatie is qm set $VM_ID --scsihw virtio-scsi-pci --virtio0 local-lvm:vm-$VM_ID-disk-0 # Waarbij local-lvm wederom de storage locatie is qm set $VM_ID --ide2 local-lvm:cloudinit # Wederom local-lvm is de storage locatie qm set $VM_ID --boot c --bootdisk virtio0 qm set $VM_ID --serial0 socket qm template $VM_ID rm focal-server-cloudimg-amd64.img
Als je nu naar de web interface van proxmox gaat zie je dat er een template aangemaakt is met nummer $VM_ID (5000) in ons geval.
Klik op deze template en klik daarna op Cloud-Init
Hierin kun je een aantal dingen instellen welke meegenomen worden bij het installeren van de server.
Je kunt bijv. de username opgeven. Als je daarbij ook de ssh public key opgeeft kun je connecten met de server nadat deze klaar is.
Deze installingen kunnen eventueel ook nog in Terraform geregeld worden.
Nu hebben we de cloudinit geregeld en kunnen we verder met het Terraform gedeelte.
Terraform
We installeren terraform op een device. Voor Ubuntu zetten we de volgende stappen
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" sudo apt-get update && sudo apt-get install terraform
Voor CentOS/RHEL/AlmaLinux gebruiken we deze stappen
sudo yum install yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo sudo yum -y install terraform
We maken een directory aan waarbij we alle terraform dingetjes gaan doen
mkdir terraform cd terraform
Om proxmox te kunnen gebruiken met Terraform hebben we de provider plugin nodig. Hiervoor maken we een bestand aan genaamd version.tf
vim version.tf
hierin kopieren we de volgende tekst
terraform { required_providers { proxmox = { source = "Telmate/proxmox" version = "2.6.8" } } required_version = ">= 0.14" }
Hiermee zorgen we dat terraform de Telmate proxmox plugin installeert.
vervolgens maken we een bestand aan var.tf
vim var.tf
en daarin plaatsen we de volgende tekst
variable "proxmox_host" { type = map default = { pm_api_url = "https://pve_host:8006/api2/json" pm_user = "root@pam" target_node = "pve1" } } variable "vmid" { default = 400 description = "Starting ID for the CTs" } variable "hostnames" { description = "VMs to be created" type = list(string) default = ["terra-test1", "terra-test2"] } variable "rootfs_size" { default = "2G" } variable "ips" { description = "IPs of the VMs, respective to the hostname order" type = list(string) default = ["10.10.10.100", "10.10.10.101"] } variable "ssh_keys" { type = map default = { pub = "./terraform/cloudinit.pub" priv = "./terraform/cloudinit" } } #variable "ssh_password" {} variable "user" { default = "terrauser" }
Hierin staan een aantal variabelen welke terraform en cloudinit kunnen gebruiken. Een aantal werkte er niet in mijn test, dus heb ik die in de main.tf geplaatst.
Dat bestand gaan we nu aanmaken.
vim main.tf
En daarin zetten we de volgende configuratie
provider "proxmox" { pm_api_url = "https://pve_host:8006/api2/json" pm_user = "root@pam" pm_password = "secretpassword" pm_tls_insecure = true } resource "proxmox_vm_qemu" "prox-vm" { count = length(var.hostnames) name = var.hostnames[count.index] target_node = var.proxmox_host["target_node"] vmid = var.vmid + count.index full_clone = true clone = "cloud-init-focal" cores = 2 sockets = 1 vcpus = 2 memory = 2048 balloon = 2048 boot = "c" bootdisk = "virtio0" scsihw = "virtio-scsi-pci" onboot = false agent = 1 cpu = "kvm64" numa = true hotplug = "network,disk,cpu,memory" network { bridge = "vmbr0" model = "virtio" } ipconfig0 = "ip=${var.ips[count.index]}/24,gw=${cidrhost(format("%s/24", var.ips[count.index]), 1)}" disk { #id = 0 type = "virtio" storage = "local-zfs" size = "5G" } os_type = "cloud-init-ubuntu20" #creates ssh connection to check when the CT is ready for ansible provisioning connection { host = var.ips[count.index] user = var.user private_key = file(var.ssh_keys["priv"]) agent = false timeout = "3m" }
Dit zijn vooral de instellingen voor het creeeren van de VM’s. Welke proxmox server je moet gebruiken, hoeveel geheugen, disc size, cpu, netwerk config.
Dit staat allemaal in deze file.
Wanneer alles ingesteld is gaan we terraform zijn werk laten doen.
terraform init terraform plan terraform apply
(of terraform apply -auto-approve om niet yes in te hoeven typen)
Vervolgens gaat terraform 2 nieuwe VM’s aanmaken, terra-test1 en terra-test2.
Wanneer het allemaal gelukt is kun je connecten via
ssh -i cloudinit terrauser@10.10.10.100 # -i is de variabele voor de key file
Als alles goed is gegaan kunnen we ook de net gecreeerde servers weer verwijderen.
Dit doe je dmv het commando
terraform destroy
Alles is nu weer verwijdert.
Ansible
Om ook Anisble te gebruiken maken we de volgende aanpassingen in main.tf
provisioner "remote-exec" { # Leave this here so we know when to start with Ansible local-exec inline = [ "echo 'Cool, we are ready for provisioning'"] } provisioner "local-exec" { working_dir = "../../ansible/" command = "ansible-playbook -u ${var.user} --key-file ${var.ssh_keys["priv"]} -i ${var.ips[count.index]}, provision.yaml" } provisioner "local-exec" { working_dir = "../../ansible/" command = "ansible-playbook -u ${var.user} --key-file ${var.ssh_keys["priv"]} -i ${var.ips[count.index]}, install-qemu-guest-agent.yaml" } }
Dit ga ik nog nader specificeren
Met dank aan https://vanmieghem.io/