Configure Garage object storage on garage01 with S3 API, Vault secrets for RPC secret and admin token, and Caddy reverse proxy for HTTPS access at s3.home.2rjus.net via internal ACME CA. Includes flake entry, VM definition, and Vault policy for the host. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
207 lines
5.5 KiB
HCL
207 lines
5.5 KiB
HCL
# VM Definitions
|
|
# Define all VMs to deploy in the locals.vms map below
|
|
# Omit fields to use defaults from variables.tf
|
|
|
|
locals {
|
|
# Define VMs here
|
|
# Each VM can override defaults by specifying values
|
|
# Omit "ip" field for DHCP, include it for static IP
|
|
vms = {
|
|
# Example DHCP VM (uncomment to deploy):
|
|
# "example-dhcp-vm" = {
|
|
# cpu_cores = 2
|
|
# memory = 2048
|
|
# disk_size = "20G"
|
|
# }
|
|
|
|
# Example Static IP VM (uncomment to deploy):
|
|
# "example-static-vm" = {
|
|
# ip = "10.69.13.50/24"
|
|
# cpu_cores = 4
|
|
# memory = 4096
|
|
# disk_size = "50G"
|
|
# }
|
|
|
|
# Example Test VM with custom git branch (for testing pipeline changes):
|
|
# "test-vm" = {
|
|
# ip = "10.69.13.100/24"
|
|
# flake_branch = "test-pipeline" # Bootstrap from this branch instead of master
|
|
# }
|
|
|
|
# Example Minimal VM using all defaults (uncomment to deploy):
|
|
# "minimal-vm" = {}
|
|
# "bootstrap-verify-test" = {}
|
|
"vault01" = {
|
|
ip = "10.69.13.19/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "20G"
|
|
flake_branch = "vault-setup" # Bootstrap from this branch instead of master
|
|
}
|
|
"testvm01" = {
|
|
ip = "10.69.13.20/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "20G"
|
|
flake_branch = "improve-bootstrap-visibility"
|
|
vault_wrapped_token = "s.l5q88wzXfEcr5SMDHmO6o96b"
|
|
}
|
|
"testvm02" = {
|
|
ip = "10.69.13.21/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "20G"
|
|
}
|
|
"testvm03" = {
|
|
ip = "10.69.13.22/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "20G"
|
|
}
|
|
"ns2" = {
|
|
ip = "10.69.13.6/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "20G"
|
|
vault_wrapped_token = "s.3nran1e1Uim4B1OomIWCoS4T"
|
|
}
|
|
"ns1" = {
|
|
ip = "10.69.13.5/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "20G"
|
|
vault_wrapped_token = "s.b6ge0KMtNQctdKkvm0RNxGdt"
|
|
}
|
|
"kanidm01" = {
|
|
ip = "10.69.13.23/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "20G"
|
|
vault_wrapped_token = "s.OOqjEECeIV7dNgCS6jNmyY3K"
|
|
}
|
|
"monitoring02" = {
|
|
ip = "10.69.13.24/24"
|
|
cpu_cores = 4
|
|
memory = 4096
|
|
disk_size = "60G"
|
|
vault_wrapped_token = "s.uXpdoGxHXpWvTsGbHkZuq1jF"
|
|
}
|
|
"nix-cache02" = {
|
|
ip = "10.69.13.25/24"
|
|
cpu_cores = 8
|
|
memory = 20480
|
|
disk_size = "200G"
|
|
vault_wrapped_token = "s.C5EuHFyULACEqZgsLqMC3cJB"
|
|
}
|
|
"garage01" = {
|
|
ip = "10.69.13.26/24"
|
|
cpu_cores = 2
|
|
memory = 2048
|
|
disk_size = "30G"
|
|
vault_wrapped_token = "s.dtMKPT35AIrbyEiHf9c2UcsB"
|
|
}
|
|
}
|
|
|
|
# Compute VM configurations with defaults applied
|
|
vm_configs = {
|
|
for name, vm in local.vms : name => {
|
|
target_node = lookup(vm, "target_node", var.default_target_node)
|
|
template_name = lookup(vm, "template_name", var.default_template_name)
|
|
cpu_cores = lookup(vm, "cpu_cores", var.default_cpu_cores)
|
|
memory = lookup(vm, "memory", var.default_memory)
|
|
disk_size = lookup(vm, "disk_size", var.default_disk_size)
|
|
storage = lookup(vm, "storage", var.default_storage)
|
|
bridge = lookup(vm, "bridge", var.default_bridge)
|
|
vlan_tag = lookup(vm, "vlan_tag", var.default_vlan_tag)
|
|
ssh_public_key = lookup(vm, "ssh_public_key", var.default_ssh_public_key)
|
|
nameservers = lookup(vm, "nameservers", var.default_nameservers)
|
|
search_domain = lookup(vm, "search_domain", var.default_search_domain)
|
|
# Network configuration - detect DHCP vs static
|
|
ip = lookup(vm, "ip", null)
|
|
gateway = lookup(vm, "gateway", var.default_gateway)
|
|
# Branch configuration for bootstrap (optional, uses master if not set)
|
|
flake_branch = lookup(vm, "flake_branch", null)
|
|
# Vault configuration (optional, for automatic secret provisioning)
|
|
vault_wrapped_token = lookup(vm, "vault_wrapped_token", null)
|
|
}
|
|
}
|
|
}
|
|
|
|
# Deploy all VMs using for_each
|
|
resource "proxmox_vm_qemu" "vm" {
|
|
for_each = local.vm_configs
|
|
|
|
name = each.key
|
|
target_node = each.value.target_node
|
|
|
|
# Clone from template
|
|
clone = each.value.template_name
|
|
full_clone = true
|
|
|
|
# Boot configuration
|
|
boot = "order=virtio0"
|
|
scsihw = "virtio-scsi-single"
|
|
|
|
# VM settings
|
|
cpu {
|
|
cores = each.value.cpu_cores
|
|
}
|
|
memory = each.value.memory
|
|
|
|
# Network
|
|
network {
|
|
id = 0
|
|
model = "virtio"
|
|
bridge = each.value.bridge
|
|
tag = each.value.vlan_tag
|
|
}
|
|
|
|
# Disk settings
|
|
disks {
|
|
virtio {
|
|
virtio0 {
|
|
disk {
|
|
size = each.value.disk_size
|
|
storage = each.value.storage
|
|
}
|
|
}
|
|
}
|
|
ide {
|
|
ide2 {
|
|
# Reference the custom cloud-init disk created in cloud-init.tf
|
|
cdrom {
|
|
iso = proxmox_cloud_init_disk.ci[each.key].id
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# TPM device
|
|
tpm_state {
|
|
storage = each.value.storage
|
|
}
|
|
|
|
# Start on boot
|
|
start_at_node_boot = true
|
|
|
|
# Agent
|
|
agent = 1
|
|
|
|
# Skip IPv6 since we don't use it
|
|
skip_ipv6 = true
|
|
|
|
# RNG device for better entropy
|
|
rng {
|
|
source = "/dev/urandom"
|
|
period = 1000
|
|
}
|
|
|
|
# Lifecycle configuration
|
|
lifecycle {
|
|
ignore_changes = [
|
|
clone, # Template name can change without recreating VMs
|
|
startup_shutdown, # Proxmox sets defaults (-1) that we don't need to manage
|
|
]
|
|
}
|
|
}
|