Compare commits
12 Commits
48bdaf28ec
...
master
Author | SHA1 | Date | |
---|---|---|---|
81698be718 | |||
31a11ac255 | |||
ab3427fd82 | |||
0536e9252a | |||
e6ed17b127 | |||
fb2526154b | |||
b7a7daef3b | |||
c5559fbb38 | |||
30e36beb93 | |||
e65da68f2d | |||
6c1ac8d96c | |||
f35163b5cd |
58
.github/workflows/infra-build.yml
vendored
58
.github/workflows/infra-build.yml
vendored
@@ -1,58 +0,0 @@
|
|||||||
name: Build Infra (Opentofu)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
opentofu:
|
|
||||||
name: Opentofu Build
|
|
||||||
runs-on: self-hosted
|
|
||||||
container:
|
|
||||||
image: node:20-bullseye
|
|
||||||
|
|
||||||
env:
|
|
||||||
PG_CONN_STR: ${{ secrets.PG_CONN_STR }} # available to all steps
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v5
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Generate Dynamic Vars (Secrets)
|
|
||||||
run: |
|
|
||||||
cat <<EOF > terraform.auto.tfvars
|
|
||||||
ci_user = "${{ secrets.CI_USER }}"
|
|
||||||
ci_password = "${{ secrets.CI_PASSWORD }}"
|
|
||||||
proxmox_api_url = "${{ secrets.PVE_API_URL }}"
|
|
||||||
proxmox_api_token_id = "${{ secrets.PVE_API_TOKEN_ID }}"
|
|
||||||
proxmox_api_token_secret = "${{ secrets.PVE_API_TOKEN_SECRET }}"
|
|
||||||
ssh_key = "${{ secrets.SSH_PRIVATE_KEY }}"
|
|
||||||
passphrase = "${{ secrets.SSH_PASSPHRASE }}"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- name: Setup Opentofu
|
|
||||||
uses: opentofu/setup-opentofu@v1
|
|
||||||
|
|
||||||
- name: Format vars file
|
|
||||||
run: tofu fmt terraform.auto.tfvars
|
|
||||||
|
|
||||||
- name: Opentofu Init
|
|
||||||
run: tofu init
|
|
||||||
|
|
||||||
- name: Opentofu Format Check
|
|
||||||
run: tofu fmt -check -recursive
|
|
||||||
|
|
||||||
- name: Opentofu Validate
|
|
||||||
run: tofu validate
|
|
||||||
|
|
||||||
- name: Opentofu Plan
|
|
||||||
id: plan
|
|
||||||
run: |
|
|
||||||
tofu plan -out=tfplan -detailed-exitcode
|
|
||||||
|
|
||||||
- name: Opentofu Apply
|
|
||||||
if: success()
|
|
||||||
run: tofu apply -auto-approve tfplan
|
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,6 +5,9 @@
|
|||||||
*.tfstate
|
*.tfstate
|
||||||
*.tfstate.*
|
*.tfstate.*
|
||||||
|
|
||||||
|
# var files
|
||||||
|
*.tfvars
|
||||||
|
|
||||||
# Crash log files
|
# Crash log files
|
||||||
crash.log
|
crash.log
|
||||||
crash.*.log
|
crash.*.log
|
||||||
|
@@ -1,17 +1,16 @@
|
|||||||
resource "proxmox_lxc" "omada" {
|
resource "proxmox_lxc" "omada" {
|
||||||
depends_on = [
|
|
||||||
proxmox_vm_qemu.dev-docker
|
|
||||||
]
|
|
||||||
target_node = "pve"
|
target_node = "pve"
|
||||||
vmid = "200"
|
vmid = "201"
|
||||||
hostname = "omada"
|
hostname = "omada"
|
||||||
ostemplate = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst"
|
ostemplate = "local:vztmpl/debian-13-standard_13.1-1_amd64.tar.zst"
|
||||||
password = var.ci_password
|
password = var.ci_password
|
||||||
unprivileged = false
|
unprivileged = false
|
||||||
ostype = "debian"
|
ostype = "debian"
|
||||||
onboot = true
|
onboot = true
|
||||||
start = true
|
start = true
|
||||||
startup = "order=1000"
|
startup = "order=1000"
|
||||||
|
tags = "docker;container;appliance"
|
||||||
|
|
||||||
|
|
||||||
ssh_public_keys = <<EOF
|
ssh_public_keys = <<EOF
|
||||||
@@ -32,11 +31,29 @@ resource "proxmox_lxc" "omada" {
|
|||||||
mount = "nfs;cifs"
|
mount = "nfs;cifs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind Mount Point
|
||||||
|
mountpoint {
|
||||||
|
key = "1"
|
||||||
|
slot = 1
|
||||||
|
//storage = "/mnt/lxc/omada"
|
||||||
|
volume = "/mnt/lxc/omada"
|
||||||
|
size = "1G"
|
||||||
|
mp = "/data"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
network {
|
network {
|
||||||
name = "eth0"
|
name = "eth0"
|
||||||
bridge = "vmbr0"
|
bridge = "vmbr0"
|
||||||
ip = "10.10.40.2/24"
|
ip = "10.10.40.2/24"
|
||||||
gw = "10.10.40.1"
|
gw = "10.10.40.1"
|
||||||
tag = 40
|
tag = 40
|
||||||
|
ip6 = "auto"
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
ignore_changes = [
|
||||||
|
mountpoint,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,14 +4,14 @@ resource "proxmox_vm_qemu" "dev-docker" {
|
|||||||
target_node = "pve"
|
target_node = "pve"
|
||||||
vmid = "400"
|
vmid = "400"
|
||||||
name = "dev-docker"
|
name = "dev-docker"
|
||||||
tags = null
|
tags = "linux;vm;docker"
|
||||||
|
|
||||||
# VM Advanced General Settings
|
# VM Advanced General Settings
|
||||||
onboot = true
|
onboot = true
|
||||||
scsihw = "virtio-scsi-single"
|
scsihw = "virtio-scsi-single"
|
||||||
|
|
||||||
# VM OS Settings
|
# VM OS Settings
|
||||||
clone = "debian-12-generic-amd64"
|
clone = "debian-13-generic-amd64"
|
||||||
clone_wait = 120
|
clone_wait = 120
|
||||||
timeouts {
|
timeouts {
|
||||||
create = "1h"
|
create = "1h"
|
34
CHANGELOG.md
Normal file
34
CHANGELOG.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial setup of OpenTofu project structure
|
||||||
|
- Providers for Proxmox, Omada, GitHub
|
||||||
|
- PostgreSQL backend support
|
||||||
|
- GitHub Actions CI/CD workflow with `init`, `fmt`, `validate`, `plan`, and `apply`
|
||||||
|
- Secure secrets handling via `terraform.auto.tfvars`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.1.0] - 2025-09-27
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- First working pipeline applying infrastructure automatically on `main`
|
||||||
|
- Docker VM definition (`docker.tf`)
|
||||||
|
- GitHub repo/org configuration (`github.tf`)
|
||||||
|
- Omada networking definitions (`omada.tf`)
|
||||||
|
- Provider and backend config (`provider.tf`)
|
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 Matthew McKinnon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
50
README.md
Normal file
50
README.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|

|
||||||
|
|
||||||
|
[](https://github.com/comprofix/opentofu-homelab/actions)
|
||||||
|
|
||||||
|
## 📖 Overview
|
||||||
|
|
||||||
|
Infrastructure as Code (IaC) for the Comprofix homelab using [OpenTofu](https://opentofu.org/).
|
||||||
|
|
||||||
|
This repository provisions and manages resources such as the Proxmox VMs and LXC containers used in the Comprofix Homelab
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Features
|
||||||
|
|
||||||
|
- Declarative infrastructure management with OpenTofu
|
||||||
|
- Remote state stored in PostgreSQL backend
|
||||||
|
- Secure injection of secrets into `terraform.auto.tfvars`
|
||||||
|
- Supports Proxmox VM provisioning and Omada configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Workflow
|
||||||
|
|
||||||
|
1. Checkout repo
|
||||||
|
2. Generate `terraform.auto.tfvars`
|
||||||
|
3. Run `tofu init`, `tofu fmt`, `tofu validate`
|
||||||
|
4. Execute `tofu plan`
|
||||||
|
5. If successful, run `tofu apply`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 Usage
|
||||||
|
|
||||||
|
Local testing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Initialize
|
||||||
|
tofu init
|
||||||
|
|
||||||
|
# Format configs
|
||||||
|
tofu fmt -recursive
|
||||||
|
|
||||||
|
# Validate configs
|
||||||
|
tofu validate
|
||||||
|
|
||||||
|
# Plan changes
|
||||||
|
PG_CONN_STR="postgres://..." tofu plan
|
||||||
|
|
||||||
|
# Apply changes
|
||||||
|
PG_CONN_STR="postgres://..." tofu apply
|
44
github.tf
44
github.tf
@@ -1,44 +0,0 @@
|
|||||||
resource "proxmox_lxc" "ghshr" {
|
|
||||||
|
|
||||||
depends_on = [
|
|
||||||
proxmox_vm_qemu.dev-docker
|
|
||||||
]
|
|
||||||
|
|
||||||
target_node = "pve"
|
|
||||||
vmid = "201"
|
|
||||||
hostname = "ghshr"
|
|
||||||
ostemplate = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst"
|
|
||||||
password = var.ci_password
|
|
||||||
unprivileged = false
|
|
||||||
ostype = "debian"
|
|
||||||
onboot = true
|
|
||||||
start = true
|
|
||||||
startup = "order=1000"
|
|
||||||
|
|
||||||
|
|
||||||
ssh_public_keys = <<EOF
|
|
||||||
${var.ssh_key}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
memory = "4096"
|
|
||||||
swap = "512"
|
|
||||||
|
|
||||||
rootfs {
|
|
||||||
storage = "local"
|
|
||||||
size = "8G"
|
|
||||||
}
|
|
||||||
|
|
||||||
features {
|
|
||||||
fuse = true
|
|
||||||
nesting = true
|
|
||||||
mount = "nfs;cifs"
|
|
||||||
}
|
|
||||||
|
|
||||||
network {
|
|
||||||
name = "eth0"
|
|
||||||
bridge = "vmbr0"
|
|
||||||
ip = "10.10.10.8/24"
|
|
||||||
gw = "10.10.10.1"
|
|
||||||
tag = 10
|
|
||||||
}
|
|
||||||
}
|
|
29
prepareEnvs.sh
Normal file
29
prepareEnvs.sh
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
bw config server https://vault.comprofix.com
|
||||||
|
bw login
|
||||||
|
export BW_SESSION=$(bw unlock --raw)
|
||||||
|
bw sync
|
||||||
|
|
||||||
|
echo "Please wait while we prepare terraform.auto.tfvars"
|
||||||
|
|
||||||
|
proxmox_api_url=$(bw get --session $BW_SESSION uri proxmox_api)
|
||||||
|
proxmox_api_token_id=$(bw get --session $BW_SESSION username f295a859-154a-482d-8129-c6ec6e06131e)
|
||||||
|
proxmox_api_token_secret=$(bw get --session $BW_SESSION password f295a859-154a-482d-8129-c6ec6e06131e)
|
||||||
|
ci_user=$(bw get --session $BW_SESSION username ci_details)
|
||||||
|
ci_password=$(bw get --session $BW_SESSION password ci_details)
|
||||||
|
ssh_key=$(bw get --session $BW_SESSION notes ssh_public_key_main)
|
||||||
|
passphrase=$(bw get --session $BW_SESSION password state_passphrase)
|
||||||
|
|
||||||
|
echo 'proxmox_api_url = "'$proxmox_api_url'"' > terraform.auto.tfvars
|
||||||
|
echo 'proxmox_api_token_id = "'$proxmox_api_token_id'"' >> terraform.auto.tfvars
|
||||||
|
echo 'proxmox_api_token_secret = "'$proxmox_api_token_secret'"' >> terraform.auto.tfvars
|
||||||
|
echo 'ci_user = "'$ci_user'"' >> terraform.auto.tfvars
|
||||||
|
echo 'ci_password = "'$ci_password'"' >> terraform.auto.tfvars
|
||||||
|
echo 'ssh_key = "'$ssh_key'"' >> terraform.auto.tfvars
|
||||||
|
echo 'passphrase = "'$passphrase'"' >> terraform.auto.tfvars
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -11,7 +11,9 @@ terraform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backend "pg" {}
|
backend "pg" {
|
||||||
|
schema_name = "homelab-infra"
|
||||||
|
}
|
||||||
encryption {
|
encryption {
|
||||||
key_provider "pbkdf2" "mykey" {
|
key_provider "pbkdf2" "mykey" {
|
||||||
passphrase = var.passphrase
|
passphrase = var.passphrase
|
||||||
|
Reference in New Issue
Block a user