| Adding Blocky and NAS selfhosted Incus configs. - infra - Terraform IoC for my … | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 18dc7341334c0ae572dd8e1fe37a9f5bfe91c598 | |
| parent d5730ddfc770cf4d3daaec8224f90d10eb986d4c | |
| Author: Jay Scott <[email protected]> | |
| Date: Thu, 18 Jul 2024 17:30:37 +0100 | |
| Adding Blocky and NAS selfhosted Incus configs. | |
| I am currently porting most of my selfhosted services over to Incus from | |
| K8 one at a time. The Terraform could easily be refactored but I shall | |
| do that at a later date once I have an idea of expectations. | |
| Diffstat: | |
| A local/.terraform.lock.hcl | 23 +++++++++++++++++++++++ | |
| A local/cloudinit/blocky-net.yaml | 6 ++++++ | |
| A local/cloudinit/blocky-user.yaml | 41 +++++++++++++++++++++++++++++… | |
| A local/cloudinit/nas-net.yaml | 6 ++++++ | |
| A local/cloudinit/nas-user.yaml | 35 +++++++++++++++++++++++++++++… | |
| A local/main.tf | 44 +++++++++++++++++++++++++++++… | |
| A local/terraform.tfvars | 22 ++++++++++++++++++++++ | |
| A local/variables.tf | 13 +++++++++++++ | |
| D terraform/.terraform.lock.hcl | 24 ------------------------ | |
| D terraform/checks.tf | 8 -------- | |
| D terraform/files/id_rsa.pub | 1 - | |
| D terraform/main.tf | 71 -----------------------------… | |
| D terraform/outputs.tf | 3 --- | |
| D terraform/terraform.tfvars | 48 -----------------------------… | |
| D terraform/user_data/boot.yml | 16 ---------------- | |
| D terraform/user_data/docker.yml | 25 ------------------------- | |
| D terraform/variables.tf | 25 ------------------------- | |
| 17 files changed, 190 insertions(+), 221 deletions(-) | |
| --- | |
| diff --git a/local/.terraform.lock.hcl b/local/.terraform.lock.hcl | |
| @@ -0,0 +1,23 @@ | |
| +# This file is maintained automatically by "tofu init". | |
| +# Manual edits may be lost in future updates. | |
| + | |
| +provider "registry.opentofu.org/lxc/incus" { | |
| + version = "0.1.2" | |
| + constraints = "0.1.2" | |
| + hashes = [ | |
| + "h1:tsoQEChWE++F07sxzmqZq79hTA1a1Wxs94UZGgH+90E=", | |
| + "zh:0f7996e7ba9b81eca2372b1afe93120fdece292466e8b5133ce9e1ffc732012d", | |
| + "zh:536db13c42b1809bbe9e5ac25e4e99263403add754525854a8cfbd58559ea216", | |
| + "zh:5b31043a99d278ff29b755ae1ce24675cbf17bbcdffc2e09dc55d9ba086c78a0", | |
| + "zh:79a3b47fb979e287b7a3c91fb079718304e379ff04aa3b05eb005afa1f5a8b9c", | |
| + "zh:85ac7e469d60386561f35ef5217c281c4dd4686d341f9f21a35a1a75f326ae22", | |
| + "zh:85c81e4a982bc0ef2eb5d88bb3a70c28f305c88b97d028d5bc392082d130919b", | |
| + "zh:8f2978706aa86a05e0f647c7003edfe58e90efc1cca9b56c4666cff642f375f3", | |
| + "zh:a70970fdeb0efa4e32a6f63a7f995fbe59e961577497ecd3e3f5fd8de6897cad", | |
| + "zh:abed445784eb47cebb9772ad2fc76993e2d31df87335042f8216f9c982eedf99", | |
| + "zh:b226508cc60697939c3f28de1b25cd233b91546541b294ec9e019c16c190f3d9", | |
| + "zh:b6fa368791dec8fa417c779dfd9b56540543c9cf9cd039517332a7998834adbd", | |
| + "zh:c681633d8cd6e8d4c71f21b22b58b6a4e02e9191b66a197ab7a26dcd45599675", | |
| + "zh:e63f8b466d0c50cac2c62aaade44babc25c4c4d1c0ec422ebbd235ae5e3ec6d3", | |
| + ] | |
| +} | |
| diff --git a/local/cloudinit/blocky-net.yaml b/local/cloudinit/blocky-net.yaml | |
| @@ -0,0 +1,6 @@ | |
| +version: 2 | |
| +ethernets: | |
| + eth0: | |
| + addresses: | |
| + - 192.168.2.10/24 | |
| + gateway4: 192.168.2.1 | |
| diff --git a/local/cloudinit/blocky-user.yaml b/local/cloudinit/blocky-user.yaml | |
| @@ -0,0 +1,41 @@ | |
| +#cloud-config | |
| +package_upgrade: true | |
| +hostname: blocky.jay.scot | |
| +timezone: Europe/London | |
| +manage_resolv_conf: true | |
| +resolv_conf: | |
| + nameservers: ['192.168.2.10', '1.1.1.1'] | |
| +packages: | |
| + - blocky | |
| +runcmd: | |
| + - rc-service blocky start | |
| +write_files: | |
| + - path: /etc/blocky/config.yml | |
| + permissions: '0644' | |
| + defer: true | |
| + content: | | |
| + upstreams: | |
| + groups: | |
| + default: | |
| + - https://dns.quad9.net/dns-query | |
| + - https://anycast.uncensoreddns.org/dns-query | |
| + | |
| + blocking: | |
| + blackLists: | |
| + ads: | |
| + - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts | |
| + clientGroupsBlock: | |
| + default: | |
| + - ads | |
| + | |
| + ports: | |
| + dns: 53 | |
| + | |
| + customDNS: | |
| + customTTL: 5m | |
| + filterUnmappedTypes: true | |
| + mapping: | |
| + blocky.jay.scot: 192.168.2.10 | |
| + git.jay.scot: 192.168.2.12 | |
| + nas.jay.scot: 192.168.2.14 | |
| + jellyfin.jay.scot: 192.168.2.15 | |
| diff --git a/local/cloudinit/nas-net.yaml b/local/cloudinit/nas-net.yaml | |
| @@ -0,0 +1,6 @@ | |
| +version: 2 | |
| +ethernets: | |
| + eth0: | |
| + addresses: | |
| + - 192.168.2.14/24 | |
| + gateway4: 192.168.2.1 | |
| diff --git a/local/cloudinit/nas-user.yaml b/local/cloudinit/nas-user.yaml | |
| @@ -0,0 +1,35 @@ | |
| +#cloud-config | |
| +package_upgrade: true | |
| +hostname: nas.jay.scot | |
| +timezone: Europe/London | |
| +manage_resolv_conf: true | |
| + | |
| +resolv_conf: | |
| + nameservers: ['192.168.2.10', '1.1.1.1'] | |
| + | |
| +packages: | |
| + - samba | |
| + | |
| +users: | |
| + - name: samba | |
| + group: users | |
| + passwd: $6$WNXusbujTtdH5X3z$43RgrNloS.Qz9nVoN5jIiaSpzgrur9KpRwfiQP.3rVMOPV… | |
| + | |
| +write_files: | |
| + - path: /etc/samba/smb.conf | |
| + permissions: '0644' | |
| + defer: true | |
| + content: | | |
| + [global] | |
| + allow insecure wide links = yes | |
| + workgroup = WORKGROUP | |
| + dos charset = cp866 | |
| + unix charset = utf-8 | |
| + force user = samba | |
| + | |
| + [storage] | |
| + follow symlinks = yes | |
| + wide links = yes | |
| + browseable = yes | |
| + writeable = yes | |
| + path = /share | |
| diff --git a/local/main.tf b/local/main.tf | |
| @@ -0,0 +1,44 @@ | |
| +terraform { | |
| + required_providers { | |
| + incus = { | |
| + source = "lxc/incus" | |
| + version = "0.1.2" | |
| + } | |
| + } | |
| +} | |
| + | |
| +provider "incus" { | |
| + generate_client_certificates = true | |
| + accept_remote_certificate = true | |
| + | |
| + remote { | |
| + name = "incus-server-1" | |
| + scheme = "https" | |
| + address = "192.168.1.148" | |
| + token = "eyJjbGllbnRfbmFtZSI6InRlcnJhZm9ybSIsImZpbmdlcnByaW50IjoiOTVmMDI… | |
| + default = true | |
| + } | |
| +} | |
| + | |
| +resource "incus_instance" "main" { | |
| + for_each = var.nodes | |
| + | |
| + name = each.key | |
| + image = each.value.image | |
| + | |
| + config = { | |
| + "cloud-init.user-data" = file(each.value.cloudinit_userdata) | |
| + "cloud-init.network-config" = file(each.value.cloudinit_network) | |
| + } | |
| + | |
| + dynamic "device" { | |
| + for_each = each.value.devices | |
| + | |
| + content { | |
| + name = device.key | |
| + type = device.value.type | |
| + properties = device.value.properties | |
| + } | |
| + | |
| + } | |
| +} | |
| diff --git a/local/terraform.tfvars b/local/terraform.tfvars | |
| @@ -0,0 +1,22 @@ | |
| +nodes = { | |
| + blocky = { | |
| + image = "images:alpine/3.20/cloud" | |
| + cloudinit_userdata = "./cloudinit/blocky-user.yaml" | |
| + cloudinit_network = "./cloudinit/blocky-net.yaml" | |
| + } | |
| + nas = { | |
| + image = "images:alpine/3.20/cloud" | |
| + cloudinit_userdata = "./cloudinit/nas-user.yaml" | |
| + cloudinit_network = "./cloudinit/nas-net.yaml" | |
| + devices = { | |
| + storage = { | |
| + type = "disk" | |
| + properties = { | |
| + path = "/share" | |
| + source = "/srv" | |
| + shift = true | |
| + } | |
| + } | |
| + } | |
| + } | |
| +} | |
| diff --git a/local/variables.tf b/local/variables.tf | |
| @@ -0,0 +1,13 @@ | |
| +variable "nodes" { | |
| + description = "Configuration settings for each required node." | |
| + type = map(object({ | |
| + image = string | |
| + cloudinit_userdata = string | |
| + cloudinit_network = string | |
| + devices = optional(map(object({ | |
| + type = string | |
| + properties = map(any) | |
| + })), {}) | |
| + })) | |
| + default = {} | |
| +} | |
| diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl | |
| @@ -1,24 +0,0 @@ | |
| -# This file is maintained automatically by "terraform init". | |
| -# Manual edits may be lost in future updates. | |
| - | |
| -provider "registry.terraform.io/hetznercloud/hcloud" { | |
| - version = "1.45.0" | |
| - constraints = "1.45.0" | |
| - hashes = [ | |
| - "h1:BEE0B6hv1ZAmTLIO12uqIm7s3oSjmGzZLm6OzudlxAw=", | |
| - "zh:1c4b44a698cfaca215bdbadaf92669dd23533210c3cbf32895fbf4ff7acf6c24", | |
| - "zh:2915f8385559694e5097d8d0df16358200e9f0d9efb80559e9ea0bd072d792b9", | |
| - "zh:3a6b37b0bba50d263bd3dba26185bde13c825e59b6b301ab3f9f45686a21456b", | |
| - "zh:3e3910fa22a3a8d73d1aed38cc479c3e1958e9168b5f4a7d0da6cf03c2dfc155", | |
| - "zh:3f8d7d09e5c93162a1e9e6c89acac0799fb55765b44b7d1d020763c814263c57", | |
| - "zh:40bc5e94bff495440e1b4f797165d7f0dcee2282a86a61b158f47fe4bc57e9fb", | |
| - "zh:473f51d464b897d0e8e3d5ca2eb175b37e2f7ce03c8b26f47cc35885cf620946", | |
| - "zh:6fdd4bf71c19cfad78d7e1d2336be873eb8567a139d53e672e78ebcbc36a4d7d", | |
| - "zh:9e08638cbfc90d69f1c21ee34191db077d58d040cf7a9eed07a1dc335d463e97", | |
| - "zh:b1ed5ea81bc6d2c88efdefaeb244322874508d90d8217ac2e3541445254bdadc", | |
| - "zh:ced05776c27d550d15d4a71360243740ecb4ea1e65e67229fb2273a27353b00c", | |
| - "zh:da79b8a1a982a1d365ea206a2654e8b5003aeba9ccdc9c8751bb6ee3f40d8c49", | |
| - "zh:fabbad25bab09dd74f2b819992ab99b939c642374d6ca080b18d6e2a91d8d487", | |
| - "zh:fb0e083d2925f289999dc561ef1c2f84a9e0ab11388c40162ca8b470f50f71f5", | |
| - ] | |
| -} | |
| diff --git a/terraform/checks.tf b/terraform/checks.tf | |
| @@ -1,8 +0,0 @@ | |
| -check "server_status" { | |
| - assert { | |
| - condition = alltrue([ | |
| - for k, v in var.nodes : hcloud_server.this[k].status == "running" | |
| - ]) | |
| - error_message = "Server status check failed." | |
| - } | |
| -} | |
| diff --git a/terraform/files/id_rsa.pub b/terraform/files/id_rsa.pub | |
| @@ -1 +0,0 @@ | |
| -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCRWnkYAChsjuT/T/IoENtm8OT18tPereaw6OOqm… | |
| diff --git a/terraform/main.tf b/terraform/main.tf | |
| @@ -1,71 +0,0 @@ | |
| -terraform { | |
| - required_version = ">=1.7.0" | |
| - required_providers { | |
| - hcloud = { | |
| - source = "hetznercloud/hcloud" | |
| - version = "1.45.0" | |
| - } | |
| - } | |
| - cloud { | |
| - } | |
| -} | |
| - | |
| -resource "hcloud_ssh_key" "this" { | |
| - for_each = var.public_ssh_keys | |
| - | |
| - name = each.key | |
| - public_key = file(each.value) | |
| -} | |
| - | |
| - | |
| -resource "hcloud_firewall" "this" { | |
| - for_each = var.firewall_rules | |
| - | |
| - name = each.key | |
| - | |
| - dynamic "rule" { | |
| - for_each = each.value.rules | |
| - | |
| - content { | |
| - description = rule.key | |
| - direction = rule.value.direction | |
| - protocol = rule.value.protocol | |
| - source_ips = rule.value.source_ips | |
| - port = rule.value.port | |
| - } | |
| - } | |
| -} | |
| - | |
| - | |
| -resource "hcloud_server" "this" { | |
| - for_each = var.nodes | |
| - | |
| - name = each.key | |
| - image = each.value.image | |
| - server_type = each.value.server_type | |
| - location = each.value.location | |
| - labels = each.value.labels | |
| - ssh_keys = [hcloud_ssh_key.this[each.value.public_key].id] | |
| - user_data = file(each.value.user_data) | |
| - firewall_ids = [hcloud_firewall.this[each.key].id] | |
| - | |
| - public_net { | |
| - ipv4_enabled = each.value.ipv4 | |
| - ipv6_enabled = each.value.ipv6 | |
| - } | |
| - | |
| - lifecycle { | |
| - postcondition { | |
| - condition = self.status == "running" | |
| - error_message = "Instance must be running." | |
| - } | |
| - } | |
| -} | |
| - | |
| -resource "hcloud_rdns" "this" { | |
| - for_each = hcloud_server.this | |
| - | |
| - server_id = each.value.id | |
| - ip_address = each.value.ipv4_address | |
| - dns_ptr = var.nodes[each.key].reverse_dns | |
| -} | |
| diff --git a/terraform/outputs.tf b/terraform/outputs.tf | |
| @@ -1,3 +0,0 @@ | |
| -output "public_ip_address" { | |
| - value = { for name, server in hcloud_server.this : name => server.ipv4_addre… | |
| -} | |
| diff --git a/terraform/terraform.tfvars b/terraform/terraform.tfvars | |
| @@ -1,48 +0,0 @@ | |
| -public_ssh_keys = { | |
| - main = "./files/id_rsa.pub" | |
| -} | |
| - | |
| -firewall_rules = { | |
| - "docker-1" = { | |
| - rules = { | |
| - gopher = { | |
| - direction = "in" | |
| - protocol = "tcp" | |
| - source_ips = ["0.0.0.0/0", "::/0"] | |
| - port = "70" | |
| - } | |
| - ssh = { | |
| - direction = "in" | |
| - protocol = "tcp" | |
| - source_ips = ["0.0.0.0/0", "::/0"] | |
| - port = "22" | |
| - } | |
| - fingerd = { | |
| - direction = "in" | |
| - protocol = "tcp" | |
| - source_ips = ["0.0.0.0/0", "::/0"] | |
| - port = "79" | |
| - } | |
| - } | |
| - } | |
| - | |
| -} | |
| - | |
| -nodes = { | |
| - "docker-1" = { | |
| - image = "debian-12" | |
| - location = "hel1", | |
| - server_type = "cx11", | |
| - reverse_dns = "jay.scot" | |
| - user_data = "user_data/docker.yml" | |
| - public_key = "main" | |
| - ipv4 = true | |
| - ipv6 = true | |
| - labels = { | |
| - gopher = "true" | |
| - docker = "true" | |
| - finger = "true" | |
| - } | |
| - } | |
| - | |
| -} | |
| diff --git a/terraform/user_data/boot.yml b/terraform/user_data/boot.yml | |
| @@ -1,16 +0,0 @@ | |
| -#cloud-config | |
| - | |
| -# disable ssh password authentication | |
| -ssh_pwauth: false | |
| - | |
| -# TODO: add in a ansible pull on boot at somepoint. | |
| -# add an ansible user | |
| -users: | |
| - - name: ansible | |
| - gecos: Ansible User | |
| - groups: users,wheel | |
| - sudo: ALL=(ALL) NOPASSWD:ALL | |
| - shell: /bin/bash | |
| - lock_passwd: true | |
| - ssh_authorized_keys: | |
| - - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCRWnkYAChsjuT/T/IoENtm8OT18tPerea… | |
| diff --git a/terraform/user_data/docker.yml b/terraform/user_data/docker.yml | |
| @@ -1,25 +0,0 @@ | |
| -#cloud-config | |
| - | |
| -# disable ssh password authentication | |
| -ssh_pwauth: false | |
| - | |
| -package_update: true | |
| - | |
| -packages: | |
| - - htop | |
| - - vim | |
| - - lynx | |
| - - finger | |
| - - unattended-upgrades | |
| - - apparmor-utils | |
| - - docker.io | |
| - | |
| -users: | |
| - - name: jay | |
| - gecos: Jay Scott | |
| - groups: users,wheel,docker | |
| - sudo: ALL=(ALL) NOPASSWD:ALL | |
| - shell: /bin/bash | |
| - lock_passwd: true | |
| - ssh_authorized_keys: | |
| - - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCRWnkYAChsjuT/T/IoENtm8OT18tPerea… | |
| diff --git a/terraform/variables.tf b/terraform/variables.tf | |
| @@ -1,25 +0,0 @@ | |
| - | |
| -variable "public_ssh_keys" { | |
| - description = "Public SSH key location to attach to instance." | |
| - type = map(any) | |
| -} | |
| - | |
| -variable "firewall_rules" { | |
| - description = "Firewall configuration settings." | |
| - type = map(any) | |
| -} | |
| - | |
| -variable "nodes" { | |
| - description = "Configuration settings for each required node." | |
| - type = map(object({ | |
| - image = string | |
| - location = string | |
| - server_type = string | |
| - reverse_dns = string | |
| - user_data = string | |
| - public_key = string | |
| - labels = map(any) | |
| - ipv4 = bool | |
| - ipv6 = bool | |
| - })) | |
| -} |