From 66c3d67e18844b02191030caafef98584e45ce60 Mon Sep 17 00:00:00 2001 From: pyrschtjag Date: Mon, 29 Jun 2026 16:48:13 +0000 Subject: [PATCH] initial commit of infrastructure --- .gitignore | 2 + main.tf | 132 +++++++++++++++++++++++++++ variables.tf | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 379 insertions(+) create mode 100644 .gitignore create mode 100644 main.tf create mode 100644 variables.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..380d6c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.tfvars +terraform diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..ad9fc6e --- /dev/null +++ b/main.tf @@ -0,0 +1,132 @@ +terraform { + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "0.111.0" + } + } +# backend "http" { +# address = "https://gitea.oyacoi.ru/api/packages/pyrschtjag/terraform/state/proxmox" +# lock_address = "https://gitea.oyacoi.ru/api/packages/pyrschtjag/terraform/state/proxmox/lock" +# unlock_address = "https://gitea.oyacoi.ru/api/packages/pyrschtjag/terraform/state/proxmox/lock" +# lock_method = "POST" +# unlock_method = "DELETE" +# } +} + +provider "proxmox" { + endpoint = "https://firebat.lan:8006/" + api_token = var.proxmox_api_token + insecure = true +} + +locals { + processed_containers = { + for k, v in var.containers : k => { + vmid = v.vmid + tags = (floor(v.vmid / 100) == 10) ? "general" : (floor(v.vmid / 100) == 11) ? "services" : "games" + vlan = floor(v.vmid / 100) % 100 + ip = "10.${floor(v.vmid / 100) % 100}.0.${v.vmid % 100}" + gw = "10.${floor(v.vmid / 100) % 100}.0.1" + nameserver = "10.${floor(v.vmid / 100) % 100}.0.1" + memory = v.memory + swap = v.swap + cores = v.cores + size = v.size + started = v.started + start_on_boot = v.start_on_boot + unprivileged = v.unprivileged + features = v.features + mount_point = v.mount_point + device_passthrough = v.device_passthrough + operating_system = v.operating_system + } + } +} + +resource "proxmox_virtual_environment_container" "all_containers" { + for_each = local.processed_containers + + node_name = "firebat" + vm_id = each.value.vmid + + initialization { + hostname = each.key + ip_config { + ipv4 { + address = "${each.value.ip}/24" + gateway = each.value.gw + } + } + dns { + servers = [each.value.nameserver] + domain = "lan" + } + } + + cpu { + #architecture = "amd64" + cores = each.value.cores + #limit = 0 + } + + memory { + dedicated = each.value.memory + swap = each.value.swap + } + + network_interface { + name = "eth0" + bridge = "vmbr0" + vlan_id = each.value.vlan + firewall = true + } + + disk { + datastore_id = "local-zfs" + size = each.value.size + } + + features { + fuse = each.value.features.fuse + keyctl = each.value.features.keyctl + mknod = each.value.features.mknod + nesting = each.value.features.nesting + mount = each.value.features.mount + } + + console { + enabled = null + tty_count = null + type = null + } + + dynamic "mount_point" { + for_each = each.value.mount_point + content { + volume = mount_point.value.volume + path = mount_point.value.path + } + } + + dynamic "device_passthrough" { + for_each = each.value.device_passthrough + content { + path = device_passthrough.value.path + gid = device_passthrough.value.gid + uid = device_passthrough.value.uid + mode = device_passthrough.value.mode + deny_write = device_passthrough.value.deny_write + } + } + + operating_system { + type = each.value.operating_system.type + template_file_id = each.value.operating_system.template_file_id + } + + unprivileged = each.value.unprivileged + started = each.value.started + start_on_boot = each.value.start_on_boot + tags = [each.value.tags] +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..c6ee7c9 --- /dev/null +++ b/variables.tf @@ -0,0 +1,245 @@ +variable "proxmox_api_token" { + type = string + sensitive = true +} + +variable "containers" { + type = map(object({ + vmid = number + memory = optional(number, 128) + swap = optional(number, 64) + cores = optional(number, 1) + size = optional(number, 1) + started = optional(bool, true) + start_on_boot = optional(bool, true) + unprivileged = optional(bool, true) + features = optional(object({ + fuse = optional(bool, false) + keyctl = optional(bool, false) + mknod = optional(bool, false) + nesting = optional(bool, true) + mount = optional(list(string), []) + }), { + fuse = false + keyctl = false + mknod = false + nesting = true + mount = [] + }) + mount_point = optional(list(object({ + volume = string + path = string + })), []) + device_passthrough = optional(list(object({ + path = string + gid = optional(number, 0) + uid = optional(number, 0) + mode = optional(string, "0660") + deny_write = optional(bool, false) + })), []) + operating_system = optional(object({ + type = optional(string, "alpine") + template_file_id = optional(string, "") + }), { + type = "alpine" + template_file_id = "" + }) + })) + + default = { + "nginx" = { + vmid = 1002 + cores = 2 + memory = 256 + swap = 64 + } + "pgsql" = { + vmid = 1003 + cores = 2 + memory = 512 + swap = 256 + size = 16 + } + "nfs" = { + vmid = 1004 + unprivileged = false + features = { + mount = ["nfs"] + } + mount_point = [ + { volume = "/mnt/media1", path = "/mnt/media1" }, + { volume = "/mnt/media2", path = "/mnt/media2" } + ] + } + "ntfy" = { + vmid = 1005 + cores = 2 + } + "zabbix" = { + vmid = 1006 + memory = 256 + swap = 128 + } + "smb" = { + vmid = 1007 + mount_point = [ + { volume = "/mnt/media1", path = "/mnt/media1" }, + { volume = "/mnt/media2", path = "/mnt/media2" } + ] + } + "vaultwarden" = { + vmid = 1102 + cores = 2 + } + "gitea" = { + vmid = 1103 + memory = 512 + swap = 256 + size = 8 + } + "radicale" = { + vmid = 1104 + } + "slskd" = { + vmid = 1105 + memory = 256 + swap = 128 + size = 2 + mount_point = [ + { volume = "/mnt/media1", path = "/mnt/media1" }, + { volume = "/mnt/media2", path = "/mnt/media2" } + ] + } + "asf" = { + vmid = 1106 + memory = 256 + swap = 128 + size = 2 + } + "rtorrent" = { + vmid = 1107 + memory = 1024 + swap = 512 + cores = 2 + mount_point = [ + { volume = "/mnt/media1", path = "/mnt/media1" }, + { volume = "/mnt/media2", path = "/mnt/media2" } + ] + } + "jellyfin" = { + vmid = 1108 + memory = 4096 + swap = 2048 + cores = 8 + size = 10 + mount_point = [ + { volume = "/mnt/media1", path = "/mnt/media1" }, + { volume = "/mnt/media2", path = "/mnt/media2" } + ] + } + "prosody" = { + vmid = 1109 + memory = 512 + swap = 256 + size = 12 + } + "coturn" = { + vmid = 1110 + memory = 512 + swap = 256 + } + "rclone" = { + vmid = 1111 + memory = 512 + swap = 256 + mount_point = [ + { volume = "/var/lib/vz/dump/", path = "/mnt/backup/proxmox" }, + { volume = "/mnt/media1/backup/", path = "/mnt/backup/bananawrt" } + ] + } + "obs" = { + vmid = 1112 + memory = 2048 + swap = 1024 + cores = 4 + size = 5 + start_on_boot = false + started = false + device_passthrough = [ + #{ path = "/dev/dri/card0", gid = 983, uid = 0, mode = "0660" }, + #{ path = "/dev/dri/renderD128", gid = 987, uid = 0, mode = "0660" }, + #{ path = "/dev/video0", gid = 983, uid = 0, mode = "0660" }, + #{ path = "/dev/video1", gid = 983, uid = 0, mode = "0660" }, + #{ path = "/dev/video3", gid = 983, uid = 0, mode = "0660" }, + #{ path = "/dev/video4", gid = 983, uid = 0, mode = "0660" }, + #{ path = "/dev/snd/controlC2", gid = 995, uid = 0, mode = "0660" }, + #{ path = "/dev/snd/controlC3", gid = 995, uid = 0, mode = "0660" }, + #{ path = "/dev/snd/controlC4", gid = 995, uid = 0, mode = "0660" }, + #{ path = "/dev/snd/pcmC2D0c", gid = 995, uid = 0, mode = "0660" }, + #{ path = "/dev/snd/pcmC3D0c", gid = 995, uid = 0, mode = "0660" }, + #{ path = "/dev/snd/pcmC4D0c", gid = 995, uid = 0, mode = "0660" }, + #{ path = "/dev/snd/pcmC4D0p", gid = 995, uid = 0, mode = "0660" } + ] + operating_system = { + type = "archlinux" + } + } + "torrserver" = { + vmid = 1113 + memory = 2048 + swap = 1024 + cores = 1 + } + "prowlarr" = { + vmid = 1114 + memory = 512 + swap = 256 + } + "bylampa" = { + vmid = 1115 + memory = 512 + swap = 256 + } + "flaresolverr" = { + vmid = 1116 + memory = 1024 + swap = 512 + cores = 2 + size = 2 + } + "gitearunner" = { + vmid = 1117 + memory = 1024 + swap = 512 + cores = 2 + operating_system = { + type = "alpine" + template_file_id = "local:vztmpl/alpine-3.23-default_20260116_amd64.tar.xz" + } + } + "ps3netsrv" = { + vmid = 1202 + mount_point = [ + { volume = "/mnt/media1", path = "/mnt/media1" }, + { volume = "/mnt/media2", path = "/mnt/media2" } + ] + } + "mcsmanager" = { + vmid = 1203 + memory = 6144 + swap = 3072 + cores = 8 + size = 20 + } + "steamcmd" = { + vmid = 1204 + memory = 6144 + swap = 3072 + cores = 8 + size = 32 + operating_system = { + type = "debian" + } + } + } +}