Add coder/proxmox-vm/main.tf
This commit is contained in:
283
coder/proxmox-vm/main.tf
Normal file
283
coder/proxmox-vm/main.tf
Normal file
@@ -0,0 +1,283 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
}
|
||||
proxmox = {
|
||||
source = "bpg/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "coder" {}
|
||||
|
||||
provider "proxmox" {
|
||||
endpoint = var.proxmox_api_url
|
||||
api_token = "${var.proxmox_api_token_id}=${var.proxmox_api_token_secret}"
|
||||
insecure = true
|
||||
|
||||
# SSH is needed for file uploads to Proxmox
|
||||
ssh {
|
||||
username = var.proxmox_ssh_user
|
||||
password = var.proxmox_password
|
||||
|
||||
node {
|
||||
name = var.proxmox_node
|
||||
address = var.proxmox_host
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "proxmox_api_url" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
|
||||
variable "proxmox_host" {
|
||||
description = "Proxmox node IP or DNS for SSH"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "proxmox_password" {
|
||||
description = "Proxmox password (used for SSH)"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_ssh_user" {
|
||||
description = "SSH username on Proxmox node"
|
||||
type = string
|
||||
default = "root"
|
||||
}
|
||||
|
||||
variable "proxmox_node" {
|
||||
description = "Target Proxmox node"
|
||||
type = string
|
||||
default = "pve"
|
||||
}
|
||||
variable "disk_storage" {
|
||||
description = "Disk storage (e.g., local-lvm)"
|
||||
type = string
|
||||
default = "local-lvm"
|
||||
}
|
||||
|
||||
variable "snippet_storage" {
|
||||
description = "Storage with Snippets content"
|
||||
type = string
|
||||
default = "local"
|
||||
}
|
||||
|
||||
variable "bridge" {
|
||||
description = "Bridge (e.g., vmbr0)"
|
||||
type = string
|
||||
default = "vmbr0"
|
||||
}
|
||||
|
||||
variable "vlan" {
|
||||
description = "VLAN tag (0 none)"
|
||||
type = number
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "clone_template_vmid" {
|
||||
description = "VMID of the cloud-init base template to clone"
|
||||
type = number
|
||||
}
|
||||
|
||||
data "coder_workspace" "me" {}
|
||||
data "coder_workspace_owner" "me" {}
|
||||
|
||||
data "coder_parameter" "cpu_cores" {
|
||||
name = "cpu_cores"
|
||||
display_name = "CPU Cores"
|
||||
type = "number"
|
||||
default = 2
|
||||
mutable = true
|
||||
}
|
||||
|
||||
data "coder_parameter" "memory_mb" {
|
||||
name = "memory_mb"
|
||||
display_name = "Memory (MB)"
|
||||
type = "number"
|
||||
default = 4096
|
||||
mutable = true
|
||||
}
|
||||
|
||||
data "coder_parameter" "disk_size_gb" {
|
||||
name = "disk_size_gb"
|
||||
display_name = "Disk Size (GB)"
|
||||
type = "number"
|
||||
default = 20
|
||||
mutable = true
|
||||
validation {
|
||||
min = 10
|
||||
max = 100
|
||||
monotonic = "increasing"
|
||||
}
|
||||
}
|
||||
|
||||
resource "coder_agent" "dev" {
|
||||
arch = "amd64"
|
||||
os = "linux"
|
||||
|
||||
env = {
|
||||
GIT_AUTHOR_NAME = data.coder_workspace_owner.me.name
|
||||
GIT_AUTHOR_EMAIL = data.coder_workspace_owner.me.email
|
||||
}
|
||||
|
||||
startup_script_behavior = "non-blocking"
|
||||
startup_script = <<-EOT
|
||||
set -e
|
||||
# Add any startup scripts here
|
||||
EOT
|
||||
|
||||
metadata {
|
||||
display_name = "CPU Usage"
|
||||
key = "cpu_usage"
|
||||
script = "coder stat cpu"
|
||||
interval = 10
|
||||
timeout = 1
|
||||
order = 1
|
||||
}
|
||||
|
||||
metadata {
|
||||
display_name = "RAM Usage"
|
||||
key = "ram_usage"
|
||||
script = "coder stat mem"
|
||||
interval = 10
|
||||
timeout = 1
|
||||
order = 2
|
||||
}
|
||||
|
||||
metadata {
|
||||
display_name = "Disk Usage"
|
||||
key = "disk_usage"
|
||||
script = "coder stat disk"
|
||||
interval = 600
|
||||
timeout = 30
|
||||
order = 3
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
hostname = lower(data.coder_workspace.me.name)
|
||||
vm_name = "coder-${lower(data.coder_workspace_owner.me.name)}-${local.hostname}"
|
||||
snippet_filename = "${local.vm_name}.yml"
|
||||
base_user = replace(replace(replace(lower(data.coder_workspace_owner.me.name), " ", "-"), "/", "-"), "@", "-") # to avoid special characters in the username
|
||||
linux_user = contains(["root", "admin", "daemon", "bin", "sys"], local.base_user) ? "${local.base_user}1" : local.base_user # to avoid conflict with system users
|
||||
|
||||
rendered_user_data = templatefile("${path.module}/cloud-init/user-data.tftpl", {
|
||||
coder_token = coder_agent.dev.token
|
||||
coder_init_script_b64 = base64encode(coder_agent.dev.init_script)
|
||||
hostname = local.vm_name
|
||||
linux_user = local.linux_user
|
||||
})
|
||||
}
|
||||
|
||||
resource "proxmox_virtual_environment_file" "cloud_init_user_data" {
|
||||
content_type = "snippets"
|
||||
datastore_id = var.snippet_storage
|
||||
node_name = var.proxmox_node
|
||||
|
||||
source_raw {
|
||||
data = local.rendered_user_data
|
||||
file_name = local.snippet_filename
|
||||
}
|
||||
}
|
||||
|
||||
resource "proxmox_virtual_environment_vm" "workspace" {
|
||||
name = local.vm_name
|
||||
node_name = var.proxmox_node
|
||||
|
||||
clone {
|
||||
node_name = var.proxmox_node
|
||||
vm_id = var.clone_template_vmid
|
||||
full = false
|
||||
retries = 5
|
||||
}
|
||||
|
||||
agent {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
on_boot = true
|
||||
started = true
|
||||
|
||||
startup {
|
||||
order = 1
|
||||
}
|
||||
|
||||
scsi_hardware = "virtio-scsi-pci"
|
||||
boot_order = ["scsi0", "ide2"]
|
||||
|
||||
memory {
|
||||
dedicated = data.coder_parameter.memory_mb.value
|
||||
}
|
||||
|
||||
cpu {
|
||||
cores = data.coder_parameter.cpu_cores.value
|
||||
sockets = 1
|
||||
type = "host"
|
||||
}
|
||||
|
||||
network_device {
|
||||
bridge = var.bridge
|
||||
model = "virtio"
|
||||
vlan_id = var.vlan == 0 ? null : var.vlan
|
||||
}
|
||||
|
||||
vga {
|
||||
type = "serial0"
|
||||
}
|
||||
|
||||
serial_device {
|
||||
device = "socket"
|
||||
}
|
||||
|
||||
disk {
|
||||
interface = "scsi0"
|
||||
datastore_id = var.disk_storage
|
||||
size = data.coder_parameter.disk_size_gb.value
|
||||
}
|
||||
|
||||
initialization {
|
||||
type = "nocloud"
|
||||
datastore_id = var.disk_storage
|
||||
|
||||
user_data_file_id = proxmox_virtual_environment_file.cloud_init_user_data.id
|
||||
|
||||
ip_config {
|
||||
ipv4 {
|
||||
address = "dhcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tags = ["coder", "workspace", local.vm_name]
|
||||
|
||||
depends_on = [proxmox_virtual_environment_file.cloud_init_user_data]
|
||||
}
|
||||
|
||||
module "code-server" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/code-server/coder"
|
||||
version = "1.3.1"
|
||||
agent_id = coder_agent.dev.id
|
||||
}
|
||||
|
||||
module "cursor" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/cursor/coder"
|
||||
version = "1.3.0"
|
||||
agent_id = coder_agent.dev.id
|
||||
}
|
||||
Reference in New Issue
Block a user