diff --git a/.gitignore b/.gitignore index 146575e..1531c20 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ override.tf.json .terraformrc terraform.rc +# Ignore .envrc +.envrc diff --git a/README.md b/README.md index 90a1652..d9b2e16 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,21 @@ -# tofu +# Init vars -Terraform config for Home \ No newline at end of file +```bash +# Proxmox related +export PROXMOX_VE_ENDPOINT= +export PROXMOX_VE_USERNAME= +export PROXMOX_VE_PASSWORD= +# OVH related +export OVH_APPLICATION_KEY= +export OVH_APPLICATION_SECRET= +export OVH_CONSUMER_KEY= +# Home related to store tfstate +export TF_VAR_HOME=${HOME} +``` + +# Use + +```bash +tofu init +tofu apply +``` diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..6207687 --- /dev/null +++ b/main.tf @@ -0,0 +1,247 @@ +terraform { + backend "local" { + path = "${var.HOME}/Nextcloud/tofu/terraform.tfstate" + } +} + +module "lxc_haproxy" { + source = "./proxmox_lxc_container" + server_name = "haproxy" + server_desc = "* HAProxy (point de terminaison TLS IPv4)" + ip_suffix = 2 +} + +module "lxc_bt" { + source = "./proxmox_lxc_container" + server_name = "bt" + server_desc = "* Transmission\n* Sonarr\n* Jackett" + ip_suffix = 3 + memory_dedicated = 1024 + unprivileged = false + disk = [{ + size = "150G" + path = "/var/lib/transmission-daemon" + }] + features = { + nesting = true + keyctl = null + fuse = null + mount = ["nfs"] + } +} + +module "lxc_mail" { + source = "./proxmox_lxc_container" + server_name = "mail" + server_desc = "* Postfix\n* Postgrey\n* Dovecot\n* Spamassassin\n* OpenDKIM\n* OpenDMARC" + ip_suffix = 4 + start_on_boot = true + memory_dedicated = 512 + disk = [{ + size = "10G" + path = "/home" + }] +} + +module "lxc_web1" { + source = "./proxmox_lxc_container" + server_name = "web1" + server_desc = "Serveur libertus :\n* Shaarli\n* FreshRSS\n* Nextcloud\n* Blog\n* Roundcube\n* Firefly3\n* Repo\n* Koillection" + ip_suffix = 5 + start_on_boot = true + cpu_cores = 2 + memory_dedicated = 2048 + disk = [{ + size = "10G" + path = "/srv" + }] +} + +module "lxc_web2" { + source = "./proxmox_lxc_container" + server_name = "web2" + server_desc = "* Wordpress\n* phpBB" + ip_suffix = 6 + start_on_boot = true + cpu_cores = 2 + memory_dedicated = 4096 + disk = [{ + size = "60G" + path = "/srv" + }] +} + +module "lxc_voice1" { + source = "./proxmox_lxc_container" + server_name = "voice1" + server_desc = "* Mumble" + ip_suffix = 7 + cpu_cores = 2 + memory_dedicated = 512 +} + +module "lxc_syslog" { + source = "./proxmox_lxc_container" + server_name = "syslog" + server_desc = "* syslog-ng" + ip_suffix = 8 + disk = [{ + size = "20G" + path = "/srv" + }] +} + +module "lxc_voice3" { + source = "./proxmox_lxc_container" + server_name = "voice3" + server_desc = "* Icecast2" + ip_suffix = 9 +} + +module "lxc_jabber" { + source = "./proxmox_lxc_container" + server_name = "jabber" + server_desc = "* Prosody" + ip_suffix = 10 +} + +module "lxc_garage1" { + source = "./proxmox_lxc_container" + server_name = "garage1" + server_desc = "* Nextcloud storage\n* Mastodon storage\n* Peertube storage" + ip_suffix = 11 + memory_dedicated = 1024 + start_on_boot = true + disk = [{ + size = "400G" + path = "/var/lib/private" + }] +} + +module "lxc_munin" { + source = "./proxmox_lxc_container" + server_name = "munin" + server_desc = "* munin" + ip_suffix = 12 +} + +module "lxc_unifi" { + source = "./proxmox_lxc_container" + server_name = "unifi" + server_desc = "* unifi server" + ip_suffix = "13" + memory_dedicated = 2048 +} + +module "lxc_ftp" { + source = "./proxmox_lxc_container" + server_name = "ftp" + server_desc = "* FTP pour les caméras" + ip_suffix = "14" + disk = [{ + size = "60G" + path = "/srv" + }] +} + +module "lxc_dom" { + source = "./proxmox_lxc_container" + server_name = "dom" + server_desc = "* Jeedom\n* Z-wave USB" + ip_suffix = "15" + memory_dedicated = 512 + start_on_boot = true + debian_tmpl = "local:vztmpl/debian-11-standard_11.7-1_amd64.tar.zst" +} + +module "lxc_git1" { + source = "./proxmox_lxc_container" + server_name = "git1" + server_desc = "* Gitea" + ip_suffix = "16" + memory_dedicated = 1024 + cpu_cores = 2 + features = { + nesting = true + keyctl = true + fuse = true + mount = null + } + disk = [{ + size = "10G" + path = "/srv" + }] +} + +module "lxc_web3" { + source = "./proxmox_lxc_container" + server_name = "web3" + server_desc = "* Wordpress Sebi" + ip_suffix = "17" + memory_dedicated = 4096 + start_on_boot = true + disk = [{ + size = "10G" + path = "/srv" + }] +} + +module "lxc_vlt1" { + source = "./proxmox_lxc_container" + server_name = "vlt1" + server_desc = "* Vaultwarden" + ip_suffix = "18" +} + +module "lxc_masto1" { + source = "./proxmox_lxc_container" + server_name = "masto1" + server_desc = "* Mastodon" + ip_suffix = 19 + cpu_cores = 2 + memory_dedicated = 4096 + disk = [{ + size = "20G" + path = "/srv" + }] +} + +module "lxc_pt1" { + source = "./proxmox_lxc_container" + server_name = "pt1" + server_desc = "* PeerTube" + ip_suffix = 20 + cpu_cores = 2 + memory_dedicated = 2048 + disk = [{ + size = "20G" + path = "/srv" + }] +} + +module "lxc_es1" { + source = "./proxmox_lxc_container" + server_name = "es1" + server_desc = "Elastic Search" + ip_suffix = 21 + memory_dedicated = 1024 + start_on_boot = true + disk = [{ + size = "10G" + path = "/srv" + }] +} + +module "lxc_git2" { + source = "./proxmox_lxc_container" + server_name = "git2" + server_desc = "Kata/dojo act_runner/Ansible" + ip_suffix = 22 + memory_dedicated = 1024 + features = { + nesting = true + keyctl = true + fuse = true + mount = null + } +} diff --git a/providers.tf b/providers.tf new file mode 100644 index 0000000..6dc603e --- /dev/null +++ b/providers.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + ovh = { + source = "ovh/ovh" + version = "1.6.0" + } + proxmox = { + source = "bpg/proxmox" + version = "0.71.0" + } + } +} + +provider "ovh" { + endpoint = "ovh-eu" +} + +provider "proxmox" { + insecure = "true" +} diff --git a/proxmox_lxc_container/locals.tf b/proxmox_lxc_container/locals.tf new file mode 100644 index 0000000..8d2e825 --- /dev/null +++ b/proxmox_lxc_container/locals.tf @@ -0,0 +1,10 @@ +locals { + ssh_key = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILxJNQPyVqQG1C5xEMuyUF9AzZd8s5J7k0kZ7qzn9a0P cveret@HLD5CD4424T4V", + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDjHhcQS8S9k/GX9TyD2F6/jOWwSvoYDIXetLOi0Nm2t mortal@baybay-ponay.mateu.be" + ] + public_ipv4_addr = "82.66.135.228" + private_ipv4_prefix = "10.233.212" + public_ipv6_prefix = "2a01:e0a:9bd:2811" + infra_related_domain = "mateu.be" +} diff --git a/proxmox_lxc_container/main.tf b/proxmox_lxc_container/main.tf new file mode 100644 index 0000000..45ca11d --- /dev/null +++ b/proxmox_lxc_container/main.tf @@ -0,0 +1,88 @@ +# Add a record to a sub-domain +resource "ovh_domain_zone_record" "record_v4" { + zone = local.infra_related_domain + subdomain = "${var.server_name}.dmz" + fieldtype = "A" + target = local.public_ipv4_addr +} + +resource "ovh_domain_zone_record" "record_v6" { + zone = local.infra_related_domain + subdomain = "${var.server_name}.dmz" + fieldtype = "AAAA" + target = "${local.public_ipv6_prefix}::${var.ip_suffix}" +} + +resource "proxmox_virtual_environment_container" "container" { + node_name = "serenor" + description = var.server_desc + + unprivileged = var.unprivileged + start_on_boot = var.start_on_boot + + features { + nesting = var.features.nesting + fuse = var.features.fuse + keyctl = var.features.keyctl + mount = var.features.mount + } + + cpu { + cores = "${var.cpu_cores}" + } + + memory { + dedicated = "${var.memory_dedicated}" + swap = "512" + } + + initialization { + hostname = var.server_name + ip_config { + ipv4 { + address = "${local.private_ipv4_prefix}.${var.ip_suffix}/26" + gateway = "${local.private_ipv4_prefix}.1" + } + ipv6 { + address = "${local.public_ipv6_prefix}::${var.ip_suffix}/64" + gateway = "${local.public_ipv6_prefix}::1" + } + } + + user_account { + keys = local.ssh_key + password = random_password.container_password.result + } + } + + disk { + datastore_id = "local-zfs" + size = 8 + } + + network_interface { + name = "eth0" + firewall = true + } + + operating_system { + template_file_id = var.debian_tmpl + type = "debian" + } + + dynamic "mount_point" { + for_each = var.disk + iterator = mydisk + content { + volume = "local-zfs" + size = mydisk.value.size + path = mydisk.value.path + } + } +} + +resource "random_password" "container_password" { + length = 16 + override_special = "_%@" + special = true +} diff --git a/proxmox_lxc_container/outputs.tf b/proxmox_lxc_container/outputs.tf new file mode 100644 index 0000000..6901f66 --- /dev/null +++ b/proxmox_lxc_container/outputs.tf @@ -0,0 +1,4 @@ +output "container_password" { + value = random_password.container_password.result + sensitive = true +} diff --git a/proxmox_lxc_container/providers.tf b/proxmox_lxc_container/providers.tf new file mode 100644 index 0000000..1f728e8 --- /dev/null +++ b/proxmox_lxc_container/providers.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + ovh = { + source = "ovh/ovh" + version = "1.6.0" + } + proxmox = { + source = "bpg/proxmox" + version = "0.71.0" + } + } +} diff --git a/proxmox_lxc_container/variables.tf b/proxmox_lxc_container/variables.tf new file mode 100644 index 0000000..8246745 --- /dev/null +++ b/proxmox_lxc_container/variables.tf @@ -0,0 +1,71 @@ +variable "cpu_cores" { + description = "Number of CPUs for the server" + type = number + default = 1 +} + +variable "start_on_boot" { + description = "Shall the VM start at boot?" + type= bool + default = false +} + +variable "memory_dedicated" { + description = "RAM quantity" + type = number + default = 256 +} + +variable "server_name" { + description = "Name of the server" + type = string +} + +variable "server_desc" { + description = "Description of the server" + type = string +} + +variable "features" { + description = "Proxmox Container Features" + type = object({ + nesting = bool + fuse = bool + keyctl = bool + mount = list(string) + }) + default = { + nesting = true + fuse = null + keyctl = null + mount = null + } +} + +variable "unprivileged" { + description = "Unprivileged LXC container" + type = bool + default = true +} + +variable "ip_suffix" { + description = "IP suffix" + type = number +} + +variable "disk" { + description = "Size and type of disk" + type = list(object({ + path = string + size = string + })) + default = [] +} + +variable "debian_tmpl" { + description = "Debian template to use" + type = string + default = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" + ## other possible value + # "local:vztmpl/debian-11-standard_11.7-1_amd64.tar.zst" +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..7f3a2cd --- /dev/null +++ b/variables.tf @@ -0,0 +1,3 @@ +variable "HOME" { + type = string +}