feat: initial deployment
This commit is contained in:
parent
cd1c623912
commit
589935c572
11 changed files with 483 additions and 2 deletions
7
.envrc
Normal file
7
.envrc
Normal 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
42
.gitignore
vendored
Normal 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
|
17
README.md
17
README.md
|
@ -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
20
devbox.json
Normal 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
101
devbox.lock
Normal 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
22
justfile
Normal 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
|
25
terraform/.terraform.lock.hcl
Normal file
25
terraform/.terraform.lock.hcl
Normal 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
152
terraform/node.tf
Normal 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
40
terraform/terraform.tf
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
terraform/terraform.tfvars
Normal file
36
terraform/terraform.tfvars
Normal 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
23
terraform/variables.tf
Normal 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
|
||||||
|
}
|
Loading…
Reference in a new issue