Initial commit
This commit is contained in:
44
skills/terraform/references/proxmox/authentication.md
Normal file
44
skills/terraform/references/proxmox/authentication.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Proxmox Provider Authentication
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
proxmox = {
|
||||
source = "telmate/proxmox"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "proxmox" {
|
||||
pm_api_url = "https://proxmox.example.com:8006/api2/json"
|
||||
pm_api_token_id = "terraform@pve!mytoken"
|
||||
pm_api_token_secret = var.pm_api_token_secret
|
||||
pm_tls_insecure = false # true for self-signed certs
|
||||
pm_parallel = 4 # concurrent operations
|
||||
pm_timeout = 600 # API timeout seconds
|
||||
}
|
||||
```
|
||||
|
||||
## Create API Token
|
||||
|
||||
```bash
|
||||
pveum user add terraform@pve
|
||||
pveum aclmod / -user terraform@pve -role PVEAdmin
|
||||
pveum user token add terraform@pve mytoken
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
```bash
|
||||
export PM_API_TOKEN_ID="terraform@pve!mytoken"
|
||||
export PM_API_TOKEN_SECRET="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
```
|
||||
|
||||
## Official Resources
|
||||
|
||||
- [Provider Docs](https://registry.terraform.io/providers/Telmate/proxmox/latest/docs)
|
||||
- [GitHub](https://github.com/Telmate/terraform-provider-proxmox)
|
||||
- [Proxmox API](https://pve.proxmox.com/pve-docs/api-viewer/)
|
||||
86
skills/terraform/references/proxmox/gotchas.md
Normal file
86
skills/terraform/references/proxmox/gotchas.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Proxmox Provider Gotchas
|
||||
|
||||
Critical issues when using Telmate Proxmox provider with Terraform.
|
||||
|
||||
## 1. Cloud-Init Changes Not Tracked
|
||||
|
||||
Terraform does **not** detect changes to cloud-init snippet file contents.
|
||||
|
||||
```hcl
|
||||
# PROBLEM: Changing vendor-data.yml won't trigger replacement
|
||||
resource "proxmox_vm_qemu" "vm" {
|
||||
cicustom = "vendor=local:snippets/vendor-data.yml"
|
||||
}
|
||||
|
||||
# SOLUTION: Use replace_triggered_by
|
||||
resource "local_file" "vendor_data" {
|
||||
filename = "vendor-data.yml"
|
||||
content = templatefile("vendor-data.yml.tftpl", { ... })
|
||||
}
|
||||
|
||||
resource "proxmox_vm_qemu" "vm" {
|
||||
cicustom = "vendor=local:snippets/vendor-data.yml"
|
||||
|
||||
lifecycle {
|
||||
replace_triggered_by = [
|
||||
local_file.vendor_data.content_base64sha256
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Storage Type vs Storage Pool
|
||||
|
||||
Different concepts - don't confuse:
|
||||
|
||||
```hcl
|
||||
disks {
|
||||
scsi {
|
||||
scsi0 {
|
||||
disk {
|
||||
storage = "local-lvm" # Pool NAME (from Proxmox datacenter)
|
||||
size = "50G"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scsihw = "virtio-scsi-single" # Controller TYPE
|
||||
```
|
||||
|
||||
- **Storage pool** = Where data stored (local-lvm, ceph-pool, nfs-share)
|
||||
- **Disk type** = Interface (scsi, virtio, ide, sata)
|
||||
|
||||
## 3. Network Interface Naming
|
||||
|
||||
Proxmox VMs get predictable names by device order:
|
||||
|
||||
| NIC Order | Guest Name |
|
||||
|-----------|------------|
|
||||
| First | ens18 |
|
||||
| Second | ens19 |
|
||||
| Third | ens20 |
|
||||
|
||||
**NOT** eth0, eth1. Configure cloud-init netplan matching `ens*`.
|
||||
|
||||
## 4. API Token Expiration
|
||||
|
||||
Long operations (20+ VMs) can exceed token lifetime.
|
||||
|
||||
```hcl
|
||||
provider "proxmox" {
|
||||
pm_api_token_id = "terraform@pve!mytoken"
|
||||
pm_api_token_secret = var.pm_api_token_secret
|
||||
pm_timeout = 1200 # 20 minutes for large operations
|
||||
}
|
||||
```
|
||||
|
||||
Use API tokens (longer-lived) not passwords.
|
||||
|
||||
## 5. Full Clone vs Linked Clone
|
||||
|
||||
```hcl
|
||||
full_clone = true # Independent copy - safe, slower, more storage
|
||||
full_clone = false # References template - BREAKS if template modified
|
||||
```
|
||||
|
||||
**Always use `full_clone = true` for production.** Linked clones only for disposable test VMs.
|
||||
66
skills/terraform/references/proxmox/troubleshooting.md
Normal file
66
skills/terraform/references/proxmox/troubleshooting.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Proxmox Troubleshooting
|
||||
|
||||
## VM Creation Stuck
|
||||
|
||||
```
|
||||
Timeout waiting for VM to be created
|
||||
```
|
||||
|
||||
**Causes**: Template missing, storage full, network unreachable
|
||||
**Debug**: Check Proxmox task log in web UI
|
||||
|
||||
## Clone Failed
|
||||
|
||||
```
|
||||
VM template not found
|
||||
```
|
||||
|
||||
**Check**: `qm list | grep template-name`
|
||||
**Causes**: Template doesn't exist, wrong node, permission issue
|
||||
|
||||
## SSH Timeout
|
||||
|
||||
```
|
||||
Timeout waiting for SSH
|
||||
```
|
||||
|
||||
**Debug**:
|
||||
1. VM console in Proxmox UI
|
||||
2. `cloud-init status` on VM
|
||||
3. `ip addr` to verify network
|
||||
|
||||
**Causes**: Cloud-init failed, network misconfigured, firewall
|
||||
|
||||
## State Drift
|
||||
|
||||
```
|
||||
Plan shows changes for unchanged resources
|
||||
```
|
||||
|
||||
**Causes**: Manual changes in Proxmox UI, provider bug
|
||||
**Fix**:
|
||||
```bash
|
||||
terraform refresh
|
||||
terraform plan # Verify
|
||||
```
|
||||
|
||||
## API Errors
|
||||
|
||||
```
|
||||
500 Internal Server Error
|
||||
```
|
||||
|
||||
**Causes**: Invalid config, resource constraints, API timeout
|
||||
**Debug**: Check `/var/log/pveproxy/access.log` on Proxmox node
|
||||
|
||||
## Permission Denied
|
||||
|
||||
```
|
||||
Permission check failed
|
||||
```
|
||||
|
||||
**Fix**: Verify API token has required permissions:
|
||||
```bash
|
||||
pveum acl list
|
||||
pveum user permissions terraform@pve
|
||||
```
|
||||
86
skills/terraform/references/proxmox/vm-qemu.md
Normal file
86
skills/terraform/references/proxmox/vm-qemu.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# proxmox_vm_qemu Resource
|
||||
|
||||
## Basic VM from Template
|
||||
|
||||
```hcl
|
||||
resource "proxmox_vm_qemu" "vm" {
|
||||
name = "my-vm"
|
||||
target_node = "pve1"
|
||||
clone = "ubuntu-template"
|
||||
full_clone = true
|
||||
|
||||
cores = 4
|
||||
sockets = 1
|
||||
memory = 8192
|
||||
cpu = "host"
|
||||
|
||||
onboot = true
|
||||
agent = 1 # QEMU guest agent
|
||||
|
||||
scsihw = "virtio-scsi-single"
|
||||
disks {
|
||||
scsi {
|
||||
scsi0 {
|
||||
disk {
|
||||
storage = "local-lvm"
|
||||
size = "50G"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
network {
|
||||
bridge = "vmbr0"
|
||||
model = "virtio"
|
||||
}
|
||||
|
||||
# Cloud-init
|
||||
os_type = "cloud-init"
|
||||
ciuser = "ubuntu"
|
||||
sshkeys = var.ssh_public_key
|
||||
ipconfig0 = "ip=dhcp"
|
||||
# Static: ipconfig0 = "ip=192.168.1.10/24,gw=192.168.1.1"
|
||||
|
||||
# Custom cloud-init
|
||||
cicustom = "vendor=local:snippets/vendor-data.yml"
|
||||
}
|
||||
```
|
||||
|
||||
## Lifecycle Management
|
||||
|
||||
```hcl
|
||||
lifecycle {
|
||||
prevent_destroy = true # Block accidental deletion
|
||||
|
||||
ignore_changes = [
|
||||
network, # Ignore manual changes
|
||||
]
|
||||
|
||||
replace_triggered_by = [
|
||||
local_file.cloud_init.content_base64sha256
|
||||
]
|
||||
|
||||
create_before_destroy = true # Blue-green deployment
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple VMs with for_each
|
||||
|
||||
```hcl
|
||||
variable "vms" {
|
||||
type = map(object({
|
||||
node = string
|
||||
cores = number
|
||||
memory = number
|
||||
}))
|
||||
}
|
||||
|
||||
resource "proxmox_vm_qemu" "vm" {
|
||||
for_each = var.vms
|
||||
name = each.key
|
||||
target_node = each.value.node
|
||||
cores = each.value.cores
|
||||
memory = each.value.memory
|
||||
# ...
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user