Getting started
In this tutorial you prepare a fresh Proxmox VE node so OpenTofu can manage it, then use this repository to create a virtual machine. By the end you will have:
- A dedicated
terraform@pveuser with an API token. - A local shell configured to talk to Proxmox and to the Cloudflare R2 state bucket.
- A VM created from the
terraform/proxmox/vmconfiguration.
Before you begin
Section titled “Before you begin”You need:
-
Root access to a Proxmox VE node.
-
Access keys for the
homelab-tfstateR2 bucket (see Remote state on Cloudflare R2). -
An SSH key pair.
-
A clone of the repository:
Terminal window git clone https://github.com/Brsalcedom/homelab-iac.gitcd homelab-iac
1. Create the Terraform user on Proxmox
Section titled “1. Create the Terraform user on Proxmox”On the Proxmox host, as root, create a user, a role and an API token:
# Create the Terraform userpveum user add terraform@pve --password 'ChangeMeStrong!'
# Create a role with the permissions used by the VM and LXC configurationspveum role add Terraform --privs "VM.Audit VM.Allocate VM.Clone VM.PowerMgmt VM.Config.Disk VM.Config.CPU VM.Config.Memory VM.Config.Network VM.Config.HWType VM.Config.Options VM.Config.CDROM VM.Config.Cloudinit Sys.Modify Datastore.AllocateSpace Datastore.Allocate Datastore.Audit SDN.Use"
# Grant the role at the root pathpveum acl modify / --roles Terraform --users terraform@pve
# Create an API tokenpveum user token add terraform@pve iac --privsep 0The token secret is printed only once. Copy it now.
Check that everything was created:
pveum user listpveum role listpveum acl listpveum user token list terraform@pveYou can see why each privilege is needed in Proxmox permissions.
2. Allow SSH uploads of cloud-init snippets
Section titled “2. Allow SSH uploads of cloud-init snippets”The VM configuration uploads a cloud-init user-data snippet, which the Proxmox API cannot do. The bpg/proxmox provider falls back to SSH for that, so on the Proxmox node authorize your public key for root and enable snippets on the local storage:
mkdir -p ~/.ssh && chmod 700 ~/.sshecho "<contents of your public key>" >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keys
pvesm set local --content backup,iso,vztmpl,snippets3. Create the VM template
Section titled “3. Create the VM template”The VMs are cloned from a Rocky Linux cloud-init template with ID 8000. Follow Create the Rocky Linux template and come back when the template exists.
4. Configure your shell
Section titled “4. Configure your shell”Export the Proxmox and R2 credentials on your workstation.
Bash
export PROXMOX_VE_ENDPOINT="https://<proxmox-ip>:8006/api2/json"export PROXMOX_VE_API_TOKEN="terraform@pve!iac=<TOKEN_SECRET>"export PROXMOX_VE_SSH_USERNAME="root"export PROXMOX_VE_SSH_PRIVATE_KEY="$(cat ~/.ssh/id_ed25519)"export AWS_ACCESS_KEY_ID="<R2_ACCESS_KEY>"export AWS_SECRET_ACCESS_KEY="<R2_SECRET_KEY>"export TF_VAR_ssh_authorized_keys='["ssh-ed25519 AAAA..."]'PowerShell
$env:PROXMOX_VE_ENDPOINT="https://<proxmox-ip>:8006/api2/json"$env:PROXMOX_VE_API_TOKEN="terraform@pve!iac=<TOKEN_SECRET>"$env:PROXMOX_VE_SSH_USERNAME="root"$env:PROXMOX_VE_SSH_PRIVATE_KEY=Get-Content -Raw ~\.ssh\id_ed25519$env:AWS_ACCESS_KEY_ID="<R2_ACCESS_KEY>"$env:AWS_SECRET_ACCESS_KEY="<R2_SECRET_KEY>"$env:TF_VAR_ssh_authorized_keys='["ssh-ed25519 AAAA..."]'5. Plan and apply
Section titled “5. Plan and apply”cd terraform/proxmox/vmtofu inittofu planThe plan lists the VMs defined in locals.tf. If it looks right, apply it:
tofu apply6. Log in to the VM
Section titled “6. Log in to the VM”Once the apply finishes, connect with the default rocky user:
ssh rocky@<vm-ip>Next steps
Section titled “Next steps”- Add your own machine: Deploy VMs.
- Create LXC containers: Deploy LXC containers.
- Build the Kubernetes cluster: Install K3s on Hyperion.