feat: initial deployment

This commit is contained in:
Tine 2024-11-02 19:53:21 +01:00
parent cd1c623912
commit 589935c572
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
11 changed files with 483 additions and 2 deletions

7
.envrc Normal file
View file

@ -0,0 +1,7 @@
# Automatically sets up your devbox environment whenever you cd into this
# directory via our direnv integration:
eval "$(devbox generate direnv --print-envrc)"
# check out https://www.jetpack.io/devbox/docs/ide_configuration/direnv/
# for more details

42
.gitignore vendored Normal file
View file

@ -0,0 +1,42 @@
# ---> Terraform
# Local .terraform directories
**/.terraform/*
# .tfstate files
**/*.tfstate
**/*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
#*.tfvars
#*.tfvars.json
# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
# ENV
.env
admin.*config
# Downloaded ISO
iso

View file

@ -1,3 +1,16 @@
# network # ingress
Networking Handling all Ingress traffic
## Setting up
### 1. Add new device to terraform.tfvars.
### 2. Manually configure vmbr0 and use import to import it.
### 3. Deploy terraform and manually install OPNsense via console.
### 4. Manually configure Tailscale.
Ref: https://tailscale.com/kb/1097/install-opnsense
### 5. Done!

20
devbox.json Normal file
View file

@ -0,0 +1,20 @@
{
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
"packages": [
"tflint@latest",
"tenv@latest"
],
"env": {
"TENV_AUTO_INSTALL": "true"
},
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}

101
devbox.lock Normal file
View file

@ -0,0 +1,101 @@
{
"lockfile_version": "1",
"packages": {
"tenv@latest": {
"last_modified": "2024-08-18T12:44:29Z",
"resolved": "github:NixOS/nixpkgs/ff1c2669bbb4d0dd9e62cc94f0968cfa652ceec1#tenv",
"source": "devbox-search",
"version": "3.0.0",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/0zbz338z744cmpp0z2rmzygab4b8pili-tenv-3.0.0",
"default": true
}
],
"store_path": "/nix/store/0zbz338z744cmpp0z2rmzygab4b8pili-tenv-3.0.0"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/fiwf4p798kamjy6waaqn0nl6dvzrz6r0-tenv-3.0.0",
"default": true
}
],
"store_path": "/nix/store/fiwf4p798kamjy6waaqn0nl6dvzrz6r0-tenv-3.0.0"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/g87m0hmaqlb9gcg2c8ln1lx9fyzqx1m0-tenv-3.0.0",
"default": true
}
],
"store_path": "/nix/store/g87m0hmaqlb9gcg2c8ln1lx9fyzqx1m0-tenv-3.0.0"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/x22lfx74nns131xxmnhpnnn7gz6hfp1r-tenv-3.0.0",
"default": true
}
],
"store_path": "/nix/store/x22lfx74nns131xxmnhpnnn7gz6hfp1r-tenv-3.0.0"
}
}
},
"tflint@latest": {
"last_modified": "2024-08-18T12:44:29Z",
"resolved": "github:NixOS/nixpkgs/ff1c2669bbb4d0dd9e62cc94f0968cfa652ceec1#tflint",
"source": "devbox-search",
"version": "0.52.0",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/2kqp4ba1anc4c1vxm31criv2cnw7bm8i-tflint-0.52.0",
"default": true
}
],
"store_path": "/nix/store/2kqp4ba1anc4c1vxm31criv2cnw7bm8i-tflint-0.52.0"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/zq3wrj237i9v6jvjfiiglhqrxnn5yfbl-tflint-0.52.0",
"default": true
}
],
"store_path": "/nix/store/zq3wrj237i9v6jvjfiiglhqrxnn5yfbl-tflint-0.52.0"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/57xd6fdjgkhyi8p69bik9bhjz3nxz4gk-tflint-0.52.0",
"default": true
}
],
"store_path": "/nix/store/57xd6fdjgkhyi8p69bik9bhjz3nxz4gk-tflint-0.52.0"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/ldy3j1qq62nq1fm9q3rpmnd0glpzvfma-tflint-0.52.0",
"default": true
}
],
"store_path": "/nix/store/ldy3j1qq62nq1fm9q3rpmnd0glpzvfma-tflint-0.52.0"
}
}
}
}
}

22
justfile Normal file
View file

@ -0,0 +1,22 @@
# Always use devbox environment to run commands.
set shell := ["devbox", "run"]
# Load dotenv
set dotenv-load
default:
@just --list
lint:
@tofu fmt -check -recursive .
@tflint --recursive
deploy:
#!/usr/bin/env sh
cd {{justfile_directory()}}/terraform
tofu init
tofu apply
destroy:
#!/usr/bin/env sh
cd {{justfile_directory()}}/terraform
tofu destroy

View file

@ -0,0 +1,25 @@
# This file is maintained automatically by "tofu init".
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/bpg/proxmox" {
version = "0.61.1"
constraints = "0.61.1"
hashes = [
"h1:6kz2Rdjc8+TVq2aUxEQXLOwbb9OdhJJei0L1fC4K2R4=",
"zh:27d8b589a2dc1e0a5b0f8ab299b9f3704a2f0b69799d1d4d8845c68056986d1f",
"zh:46dfa6b33ddd7007a2144f38090457604eb56a59a303b37bb0ad1be5c84ddaca",
"zh:47a1b14a759393c5ecc76f2feb950677c418c910b8c677fde0dd3e4675c41579",
"zh:582e49d109d1c2b1f3b1268a7cbc43548f3c6d96a87c92a5428767097a5e383e",
"zh:5e98ad6afae5969a4c3ffb14c0484936550c66c8313d7686551c29b633ff32f2",
"zh:7b9e24b76f947ab8f1e571cf61beefc983b7d2aa1b85df35c4f015728fe37a38",
"zh:8255ca210f279a0f7b8ca2762df26d2ea1a01704298c5e3d5cf601bd39a743f0",
"zh:85d7655fdc95dedced9cf8105a0beeb0d7bc8f668c55f62019a7215a76d60300",
"zh:8aeea5a1d001b06baaf923b754e1a14d06c75eb8c8b87a7f65a3c8205fc8b079",
"zh:a9cfab6c06f613658c5fdd83742cd22c0eb7563778924b1407965ef8c36c1ce0",
"zh:ceaab67801d49a92eb5858b1ddae6df2569462e5ffbe31f9dbd79dcb684ea142",
"zh:dc25b506d5c55d1d78a335d3ebd03213c99b4b2a5859812349a955c2f746ff7e",
"zh:e04b477fd77a0d37a0bdb76a7cf69184dad9e7fbba9b4f3a378a8901b82b75e5",
"zh:f1e6838d9141557f73340df9b21fce5a82b41cc16ae36f063a920ccc36bc0758",
"zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597",
]
}

152
terraform/node.tf Normal file
View file

@ -0,0 +1,152 @@
locals {
domain = "network.tjo.cloud"
nodes = {
for k, v in var.nodes : k => merge(v, {
domain = local.domain
id = 700 + index(keys(var.nodes), k)
hash = sha1(v.host)
wan_mac_address = v.mac_address != null ? v.mac_address : "AA:BB:00:00:${format("%v:%v", substr(sha1(v.host), 0, 2), substr(sha1(v.host), 2, 2))}"
private_mac_address = "AA:BB:00:11:${format("%v:%v", substr(sha1(v.host), 0, 2), substr(sha1(v.host), 2, 2))}"
internal_mac_address = "AA:BB:00:22:${format("%v:%v", substr(sha1(v.host), 0, 2), substr(sha1(v.host), 2, 2))}"
})
}
}
resource "proxmox_virtual_environment_network_linux_bridge" "vmbr0" {
for_each = local.nodes
node_name = each.value.host
name = "vmbr0"
comment = "Main interface bridge for VMs."
address = each.value.address
gateway = each.value.gateway
ports = each.value.bridge_ports
}
import {
id = "jakku:vmbr0"
to = proxmox_virtual_environment_network_linux_bridge.vmbr0["jakku"]
}
import {
id = "batuu:vmbr0"
to = proxmox_virtual_environment_network_linux_bridge.vmbr0["batuu"]
}
import {
id = "nevaroo:vmbr0"
to = proxmox_virtual_environment_network_linux_bridge.vmbr0["nevaroo"]
}
moved {
from = proxmox_virtual_environment_network_linux_bridge.vmprivate
to = proxmox_virtual_environment_network_linux_bridge.vmbr1
}
moved {
from = proxmox_virtual_environment_network_linux_bridge.vminternal
to = proxmox_virtual_environment_network_linux_bridge.vmbr2
}
resource "proxmox_virtual_environment_network_linux_bridge" "vmbr1" {
for_each = local.nodes
node_name = each.value.host
name = "vmbr1"
comment = "Private network for VMs."
}
resource "proxmox_virtual_environment_network_linux_bridge" "vmbr2" {
for_each = local.nodes
node_name = each.value.host
name = "vmbr2"
comment = "Internal network for VMs."
}
resource "proxmox_virtual_environment_file" "iso" {
for_each = local.nodes
content_type = "iso"
datastore_id = each.value.iso_storage
node_name = each.value.host
source_file {
path = "${path.module}/../iso/OPNsense-24.7-dvd-amd64.iso"
}
}
resource "proxmox_virtual_environment_vm" "nodes" {
for_each = local.nodes
vm_id = each.value.id
name = "${each.value.host}.${each.value.domain}"
node_name = each.value.host
description = "OPNsense instance for ${each.value.host}."
tags = [each.value.domain]
stop_on_destroy = true
timeout_start_vm = 60
timeout_stop_vm = 60
timeout_shutdown_vm = 60
timeout_reboot = 60
timeout_create = 600
cpu {
cores = each.value.cores
type = "host"
}
memory {
dedicated = each.value.memory
}
bios = "ovmf"
efi_disk {
datastore_id = each.value.boot_storage
}
operating_system {
type = "l26"
}
agent {
enabled = false
}
network_device {
bridge = "vmbr0"
mac_address = each.value.wan_mac_address
}
network_device {
bridge = proxmox_virtual_environment_network_linux_bridge.vmbr1[each.key].name
mac_address = each.value.private_mac_address
}
network_device {
bridge = proxmox_virtual_environment_network_linux_bridge.vmbr2[each.key].name
mac_address = each.value.internal_mac_address
}
scsi_hardware = "virtio-scsi-single"
cdrom {
enabled = each.value.iso_enabled
file_id = proxmox_virtual_environment_file.iso[each.key].id
interface = "ide0"
}
disk {
interface = "scsi0"
datastore_id = each.value.boot_storage
size = 16
backup = true
cache = "none"
iothread = true
file_format = "raw"
}
}

40
terraform/terraform.tf Normal file
View file

@ -0,0 +1,40 @@
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "0.61.1"
}
}
required_version = "~> 1.7.3"
}
provider "proxmox" {
# FIXME: Traefik/NGINX breaks this! 500 ERROR
endpoint = "https://batuu.system.tjo.cloud:8006/api2/json"
insecure = true
api_token = var.proxmox_token
ssh {
agent = true
username = "root"
node {
name = "batuu"
address = "batuu.system.tjo.cloud"
port = 22
}
node {
name = "jakku"
address = "jakku.system.tjo.cloud"
port = 22
}
node {
name = "nevaroo"
address = "nevaroo.system.tjo.cloud"
port = 22
}
}
}

View file

@ -0,0 +1,36 @@
nodes = {
batuu = {
host = "batuu"
boot_storage = "local-nvme"
iso_storage = "local"
bridge_ports = ["enp1s0", "enp2s0"]
gateway = "192.168.1.1"
address = "192.168.1.161/24"
iso_enabled = false
}
jakku = {
host = "jakku"
boot_storage = "local-nvme"
iso_storage = "local"
bridge_ports = ["enp1s0", "enp2s0"]
gateway = "192.168.1.1"
address = "192.168.1.187/24"
iso_enabled = false
}
nevaroo = {
host = "nevaroo"
boot_storage = "local"
iso_storage = "local"
mac_address = "00:50:56:00:97:FD"
bridge_ports = ["eno1"]
gateway = "178.63.49.193"
address = "178.63.49.225/26"
iso_enabled = false
}
}

23
terraform/variables.tf Normal file
View file

@ -0,0 +1,23 @@
variable "nodes" {
type = map(object({
host = string
cores = optional(number, 1)
memory = optional(number, 512)
mac_address = optional(string)
bridge_ports = list(string)
gateway = string
address = string
iso_storage = string
boot_storage = string
iso_enabled = bool
}))
}
variable "proxmox_token" {
type = string
sensitive = true
}