4.8 KiB
4.8 KiB
Terraform
Basic Proxmox setup
Add TerraformProv role
pveum role add TerraformProv -privs "Datastore.Allocate Datastore.AllocateSpace Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Console VM.Migrate VM.Monitor VM.PowerMgmt SDN.Use"
Add terraform-prov user
pveum user add terraform-prov@pve --password <password>
Set terraform-prov user TerraformProv role
pveum aclmod / -user terraform-prov@pve -role TerraformProv
Create proxmox token for terraform API
pveum user token add terraform-prov@pve terraform -expire 0 -privsep 0 -comment "Terraform token"
Client Setup
Add environment variable
cp terraform.tfvars.example
fill with your secrets (do no push this file)
Usefull commands
opentofu.tofu init
opentofu.tofu plan
opentofu.tofu apply
opentofu.tofu destroy
tofu apply -target module.<module-name>
On WSL
ssh agent could be off
if ssh-add -L gives
Could not open a connection to your authentication agent.
start and configure ssh agent
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519
Add new service
Create base module
mkdir modules/apps/<module-hostname>
Example
modules/apps/bookshelf/
├── cloud-init
│ └── service.yaml
├── lib
│ ├── scripts
│ │ ├── env.sh
│ └── services
├── main.tf
├── output.tf
├── variables.tf
├── .env.example
└── .env
main.tf
module "vm" {
source = "../../vm"
name = var.name
hostname = var.hostname
domain = var.domain
vm_id = var.vm_id
node_name = var.node_name
vm_ip_address = var.vm_ip_address
template_id = var.template_id
cores = var.cores
memory = var.memory
disk_size = var.disk_size
ssh_public_key = var.ssh_public_key
proxmox_host_ip = var.proxmox_host_ip
cloudinit_config = templatefile(
"${path.module}/cloud-init/service.yaml",
{
hostname = var.hostname
domain = var.domain
ssh_key = var.ssh_public_key
proxmox_host_ip = var.proxmox_host_ip
environment-setup-script = indent(6, file("${path.module}/lib/scripts/env.sh"))
env-file-content = indent(6, file("${path.module}/.env"))
}
)
}
Add inside templatefile object scripts content to upload with cloud-init.
variables.tf
variable "name" {
type = string
}
variable "vm_id" {
type = number
}
variable "node_name" {
type = string
default = "mop"
}
variable "cores" {
type = number
default = 2
}
variable "memory" {
type = number
default = 2048
}
variable "balloon" {
description = "Minimum vm memory, using ballooning devide to reach Proxmox node memory target."
type = number
default = 1024
}
variable "template_id" {
type = number
}
variable "ssh_public_key" {
type = string
description = "Public SSH key for cloud-init user"
}
variable "hostname" {
description = "VM hostname"
type = string
default = "test"
}
variable "domain" {
description = "VM domain"
type = string
default = ""
}
variable "disk_size" {
type = number
default = 10
}
variable "proxmox_host_ip" {
type = string
}
variable "vm_ip_address" {
type = string
}
output.tf
output "traefik_service" {
value = [{
domain = var.domain
name = var.name
host = "${var.hostname}"
ip = var.vm_ip_address
port = 80
}]
}
This output supports multiple service for one vm.
cloud-init/service.yaml
#cloud-config
hostname: ${hostname}
local-hostname: ${hostname}
fqdn: ${hostname}.${domain}
manage_etc_hosts: true
users:
- default
- name: ${hostname}
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ${ssh_key}
disable_root: true
package_update: true
package_upgrade: false
packages:
- git
- nfs-common
mounts:
- [ "192.168.1.12:/main/backups", "/backups", "nfs", "defaults,_netdev,x-systemd.requires=network-online.target", "0", "0" ]
write_files:
- path: /opt/bookshelf/env.sh
permissions: "0644"
content: |
${environment-setup-script}
- path: /opt/bookshelf/bookshelf.env
permissions: "0644"
content: |
${env-file-content}
runcmd:
- ls /
final_message: |
Base system ready for ${hostname}