-
Notifications
You must be signed in to change notification settings - Fork 73
Add Proxmox-Vm template #329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
DevelopmentCats
merged 7 commits into
coder:main
from
m4rrypro:feat/add-proxmox-template
Aug 19, 2025
Merged
Changes from 3 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
30ed0f2
Add Proxmox-Vm template
m4rrypro b2cac92
Update Proxmox Terraform config: restore SSH for file uploads, clean …
m4rrypro f564b48
Fix Formatting
m4rrypro 061c77b
Apply suggestions from code review
m4rrypro 29864ee
Prevnt coder agent service from being killed by OOM killer
m4rrypro 5c0c307
Fix Formatting
m4rrypro 063455f
Fixup
m4rrypro File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--- | ||
display_name: "Muhammad Uamir Ali" | ||
bio: "Cloud Engineer | Infrastructure as code, Kubernetes | SRE" | ||
github: "m4rrypro" | ||
avatar: "./.images/avatar.jpeg" | ||
linkedin: "https://www.linkedin.com/in/m4rry" | ||
support_email: "[email protected]" | ||
status: "community" | ||
--- | ||
|
||
# Muhammad Umair Ali | ||
|
||
Cloud Engineer | Infrastructure as code, Kubernetes | SRE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
--- | ||
display_name: Proxmox (Cloud‑Init) | ||
description: Provision Ubuntu VMs on Proxmox as Coder workspaces | ||
m4rrypro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
icon: ../../../../.icons/proxmox.svg | ||
verified: false | ||
tags: [proxmox, vm, cloud-init, qemu] | ||
--- | ||
|
||
# Proxmox Cloud‑Init Template for Coder | ||
m4rrypro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
Provision Ubuntu LTS VMs on Proxmox as [Coder workspaces](https://coder.com/docs/workspaces). The template clones a cloud‑init base image, injects user‑data via Snippets, and runs the Coder agent under the workspace owner's Linux user. | ||
m4rrypro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
## Prerequisites | ||
|
||
- Proxmox VE 8/9 with reachable node(s) | ||
- Coder v2.25+ (VMs must have outbound HTTPS to Coder) | ||
- Proxmox API token with access to nodes and storages | ||
- Storage with "Snippets" content enabled | ||
- Ubuntu cloud‑init image/template on Proxmox | ||
m4rrypro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
- Latest images: https://cloud-images.ubuntu.com/ ([source](https://cloud-images.ubuntu.com/)) | ||
|
||
## Prepare a Proxmox Cloud‑Init Template (once) | ||
|
||
Run on the Proxmox node. This uses a RELEASE variable so you always pull a current image. | ||
|
||
```bash | ||
# Choose a release (e.g., jammy or noble) | ||
RELEASE=jammy | ||
IMG_URL="https://cloud-images.ubuntu.com/${RELEASE}/current/${RELEASE}-server-cloudimg-amd64.img" | ||
IMG_PATH="/var/lib/vz/template/iso/${RELEASE}-server-cloudimg-amd64.img" | ||
|
||
# Download cloud image | ||
wget "$IMG_URL" -O "$IMG_PATH" | ||
|
||
# Create base VM (example ID 999), enable QGA, correct boot order | ||
NAME="ubuntu-${RELEASE}-cloudinit" | ||
qm create 999 --name "$NAME" --memory 4096 --cores 2 \ | ||
--net0 virtio,bridge=vmbr0 --agent enabled=1 | ||
qm set 999 --scsihw virtio-scsi-pci | ||
qm importdisk 999 "$IMG_PATH" local-lvm | ||
qm set 999 --scsi0 local-lvm:vm-999-disk-0 | ||
qm set 999 --ide2 local-lvm:cloudinit | ||
qm set 999 --serial0 socket --vga serial0 | ||
qm set 999 --boot 'order=scsi0;ide2;net0' | ||
|
||
# Enable Snippets on storage 'local' (one‑time) | ||
pvesm set local --content snippets,vztmpl,backup,iso | ||
|
||
# Convert to template | ||
qm template 999 | ||
``` | ||
|
||
Verify: | ||
|
||
```bash | ||
qm config 999 | grep -E 'template:|agent:|boot:|ide2:|scsi0:' | ||
``` | ||
|
||
### Why this works | ||
|
||
- Real bootable root disk + correct boot order eliminates iPXE boot‑failed loops | ||
- QEMU Guest Agent (QGA) enabled lets Proxmox report guest IPs for automation | ||
- Snippets + user_data_file_id provide reliable cloud‑init user‑data with `bpg/proxmox` | ||
|
||
m4rrypro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
### Enable Snippets via GUI | ||
|
||
- Datacenter → Storage → select `local` → Edit → Content → check "Snippets" → OK | ||
- Ensure `/var/lib/vz/snippets/` exists on the node for snippet files | ||
- Template page → Cloud‑Init → Snippet Storage: `local` → File: your yml → Apply | ||
|
||
## Configure this template | ||
|
||
Edit `terraform.tfvars` with your environment: | ||
|
||
```hcl | ||
# Proxmox API | ||
proxmox_api_url = "https://<PVE_HOST>:8006/api2/json" | ||
proxmox_api_token_id = "<USER@REALM>!<TOKEN>" | ||
proxmox_api_token_secret = "<SECRET>" | ||
|
||
# SSH to the node (for snippet upload) | ||
proxmox_host = "<PVE_HOST>" | ||
proxmox_password = "<NODE_ROOT_OR_SUDO_PASSWORD>" | ||
proxmox_ssh_user = "root" | ||
|
||
# Infra defaults | ||
proxmox_node = "pve" | ||
disk_storage = "local-lvm" | ||
snippet_storage = "local" | ||
bridge = "vmbr0" | ||
vlan = 0 | ||
clone_template_vmid = 999 | ||
``` | ||
|
||
### Variables (terraform.tfvars) | ||
|
||
- These values are standard Terraform variables that the template reads at apply time. | ||
- Place secrets (e.g., `proxmox_api_token_secret`, `proxmox_password`) in `terraform.tfvars` or inject with environment variables using `TF_VAR_*` (e.g., `TF_VAR_proxmox_api_token_secret`). | ||
- You can also override with `-var`/`-var-file` if you run Terraform directly. With Coder, the repo's `terraform.tfvars` is bundled when pushing the template. | ||
|
||
Variables expected: | ||
|
||
- `proxmox_api_url`, `proxmox_api_token_id`, `proxmox_api_token_secret` (sensitive) | ||
- `proxmox_host`, `proxmox_password` (sensitive), `proxmox_ssh_user` | ||
- `proxmox_node`, `disk_storage`, `snippet_storage`, `bridge`, `vlan`, `clone_template_vmid` | ||
- Coder parameters: `cpu_cores`, `memory_mb`, `disk_size_gb` | ||
|
||
## Proxmox API Token (GUI/CLI) | ||
|
||
Docs: https://pve.proxmox.com/wiki/User_Management#pveum_tokens | ||
|
||
GUI: | ||
|
||
1. (Optional) Create automation user: Datacenter → Permissions → Users → Add (e.g., `terraform@pve`) | ||
2. Permissions: Datacenter → Permissions → Add → User Permission | ||
- Path: `/` (or narrower covering your nodes/storages) | ||
- Role: `PVEVMAdmin` + `PVEStorageAdmin` (or `PVEAdmin` for simplicity) | ||
3. Token: Datacenter → Permissions → API Tokens → Add → copy Token ID and Secret | ||
4. Test: | ||
|
||
```bash | ||
curl -k -H "Authorization: PVEAPIToken=<USER@REALM>!<TOKEN>=<SECRET>" \ | ||
https:// < PVE_HOST > :8006/api2/json/version | ||
``` | ||
|
||
CLI: | ||
|
||
```bash | ||
pveum user add terraform@pve --comment 'Terraform automation user' | ||
pveum aclmod / -user terraform@pve -role PVEAdmin | ||
pveum user token add terraform@pve terraform --privsep 0 | ||
``` | ||
|
||
## Use | ||
|
||
```bash | ||
# From this directory | ||
coder templates push --yes proxmox-cloudinit --directory . | cat | ||
``` | ||
|
||
Create a workspace from the template in the Coder UI. First boot usually takes 60–120s while cloud‑init runs. | ||
|
||
## How it works | ||
|
||
- Uploads rendered cloud‑init user‑data to `<storage>:snippets/<vm>.yml` via the provider's `proxmox_virtual_environment_file` | ||
- VM config: `virtio-scsi-pci`, boot order `scsi0, ide2, net0`, QGA enabled | ||
- Linux user equals Coder workspace owner (sanitized). To avoid collisions, reserved names (`admin`, `root`, etc.) get a suffix (e.g., `admin1`). User is created with `primary_group: adm`, `groups: [sudo]`, `no_user_group: true` | ||
- systemd service runs as that user: | ||
- `coder-agent.service` | ||
|
||
## Troubleshooting quick hits | ||
|
||
- iPXE boot loop: ensure template has bootable root disk and boot order `scsi0,ide2,net0` | ||
- QGA not responding: install/enable QGA in template; allow 60–120s on first boot | ||
- Snippet upload errors: storage must include `Snippets`; token needs Datastore permissions; path format `<storage>:snippets/<file>` handled by provider | ||
- Permissions errors: ensure the token's role covers the target node(s) and storages | ||
- Verify snippet/QGA: `qm config <vmid> | egrep 'cicustom|ide2|ciuser'` | ||
|
||
## References | ||
|
||
- Ubuntu Cloud Images (latest): https://cloud-images.ubuntu.com/ ([source](https://cloud-images.ubuntu.com/)) | ||
- Proxmox qm(1) manual: https://pve.proxmox.com/pve-docs/qm.1.html | ||
- Proxmox Cloud‑Init Support: https://pve.proxmox.com/wiki/Cloud-Init_Support | ||
- Terraform Proxmox provider (bpg): `bpg/proxmox` on the Terraform Registry | ||
- Coder – Best practices & templates: | ||
- https://coder.com/docs/tutorials/best-practices/speed-up-templates | ||
- https://coder.com/docs/tutorials/template-from-scratch |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.