Compare commits
10 Commits
106971b94d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b2ad44932 | |||
| 836a57cd76 | |||
| 940ecb3946 | |||
| 7b6fcce11f | |||
| 27e45bb257 | |||
| ef777e6373 | |||
| 3ccba290b1 | |||
| 13690e6c60 | |||
| dc4ade7ed1 | |||
| ac41e3448e |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -37,3 +37,6 @@ override.tf.json
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# Claude specific ingores
|
||||
.claude
|
||||
CLAUDE.md
|
||||
45
README.md
45
README.md
@@ -1,3 +1,46 @@
|
||||
# ProxmoxInfra
|
||||
|
||||
Here lives the terraform infrastructure files. This has been added after setting up most of my proxmox. This means that its not all encompassing
|
||||
Terraform infrastructure-as-code for a homelab Proxmox environment. This repo was started after the Proxmox host was manually provisioned — existing resources are not managed here. Only new resources going forward are managed by Terraform.
|
||||
|
||||
## Stack
|
||||
|
||||
- Provider: `bpg/proxmox`
|
||||
- Terraform >= 1.0
|
||||
- Target: single-node Proxmox VE homelab (`nonprod-pve`)
|
||||
- Upstream network: Firewalla Gold → Switch → Proxmox
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
environments/
|
||||
nonprod/ # Nonprod environment root module
|
||||
modules/
|
||||
networking/ # Internal bridge segments
|
||||
```
|
||||
|
||||
## Network Architecture
|
||||
|
||||
All workload VMs and containers are isolated on internal bridges with no physical NIC. Inter-segment traffic routes exclusively through a firewall VM (OPNsense — see To Do).
|
||||
|
||||
| Bridge | CIDR | Purpose |
|
||||
|--------|------|---------|
|
||||
| vmbr0 | 192.168.68.0/24 | Existing uplink — Proxmox management + OPNsense WAN |
|
||||
| management | 10.10.10.0/24 | Admin access. Proxmox host holds 10.10.10.1. |
|
||||
| services | 10.10.20.0/24 | General workload VMs and containers. |
|
||||
| dmz | 10.10.30.0/24 | Externally exposed workloads. |
|
||||
| isolated | 10.10.40.0/24 | Lab and test. No outbound access by default. |
|
||||
|
||||
## Completed
|
||||
|
||||
- [x] Terraform connected to nonprod Proxmox host
|
||||
- [x] Environment/module repo structure established
|
||||
- [x] Internal network segments created (`management`, `services`, `dmz`, `isolated`)
|
||||
- [x] Proxmox host assigned IP on management bridge (`10.10.10.1/24`)
|
||||
|
||||
## To Do
|
||||
|
||||
- [ ] Download and upload OPNsense ISO to Proxmox
|
||||
- [ ] Create OPNsense VM module with one NIC per bridge segment
|
||||
- [ ] Configure OPNsense via Ansible (`ansibleguy.opnsense`) — interfaces, DHCP, firewall rules, NAT
|
||||
- [ ] Create Windows VM on services bridge
|
||||
- [ ] Introduce remote state backend (S3-compatible or Terraform Cloud)
|
||||
|
||||
24
environments/nonprod/.terraform.lock.hcl
generated
Normal file
24
environments/nonprod/.terraform.lock.hcl
generated
Normal file
@@ -0,0 +1,24 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/bpg/proxmox" {
|
||||
version = "0.101.1"
|
||||
constraints = "~> 0.73"
|
||||
hashes = [
|
||||
"h1:2MjGiI3uWXkZXOvoLNYq3Mji/cnJCugdzcZAdmYZ4JI=",
|
||||
"zh:0b2f899c59727b9d5ebc6324944653172e7d4f27fae2670dc10fb717f0dc085a",
|
||||
"zh:0dfb5f212aef8d5b9372ba89fe08c2404311dc7842d216585f55cae4634e1aa6",
|
||||
"zh:430c1096c801f615932d8e5ceba5cf1c46fb19c602733b12537292f0379d9875",
|
||||
"zh:6b2de9a0cfe3939372bb1c4115be81a8f470b2f1f27ff4a47e92bbc1cd16308e",
|
||||
"zh:6e32494c0e46754946e481473189bd14e9982fb4ab25938d9d8b7125f85ed09b",
|
||||
"zh:98f847d3b67e551443cb81f96e59cb320f3a5c4bf45ac4a7194eb395f950774d",
|
||||
"zh:a55dc4a1cdee600a867205cae89c57b36184f63d1fdf16945854ed2a5098012f",
|
||||
"zh:a80b4777d9cb3c2fd545ecaa0d0f8315363b1a50801638c2866701c50b097710",
|
||||
"zh:b0512be4d006abcbf91f2a8784ebc11055d3890bc119cf221373b6e820bc9cbb",
|
||||
"zh:c0207c88fa879aac82a624b10099bfd31b7760ece82fa60fe943e65cc1e7add7",
|
||||
"zh:c6e722112a1cee87ee621e7dec1cb9a8d2a64ba71d7ae021e1e9456dfb6584d8",
|
||||
"zh:e0bbca20173fe9051f53b7c211cc5f52552a3c8fe766aca34b7b1880d57a5ec7",
|
||||
"zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597",
|
||||
"zh:f5d7b772797b17fd61d199136e98281b5ca2472732cd97703a28b288cd6eefa4",
|
||||
]
|
||||
}
|
||||
15
environments/nonprod/main.tf
Normal file
15
environments/nonprod/main.tf
Normal file
@@ -0,0 +1,15 @@
|
||||
data "proxmox_virtual_environment_nodes" "vm_nodes" {}
|
||||
|
||||
output "data_proxmox_virtual_environment_nodes" {
|
||||
value = {
|
||||
names = data.proxmox_virtual_environment_nodes.vm_nodes.names
|
||||
cpu_count = data.proxmox_virtual_environment_nodes.vm_nodes.cpu_count
|
||||
online = data.proxmox_virtual_environment_nodes.vm_nodes.online
|
||||
}
|
||||
}
|
||||
|
||||
module "networking" {
|
||||
source = "../../modules/networking"
|
||||
|
||||
proxmox_node_name = var.proxmox_node_name
|
||||
}
|
||||
7
environments/nonprod/providers.tf
Normal file
7
environments/nonprod/providers.tf
Normal file
@@ -0,0 +1,7 @@
|
||||
provider "proxmox" {
|
||||
endpoint = var.proxmox_endpoint
|
||||
api_token = var.proxmox_api_token
|
||||
|
||||
# Set to true if using a self-signed certificate (common on home labs)
|
||||
insecure = var.proxmox_insecure
|
||||
}
|
||||
10
environments/nonprod/terraform.tf
Normal file
10
environments/nonprod/terraform.tf
Normal file
@@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_version = ">= 1.0"
|
||||
|
||||
required_providers {
|
||||
proxmox = {
|
||||
source = "bpg/proxmox"
|
||||
version = "~> 0.73"
|
||||
}
|
||||
}
|
||||
}
|
||||
21
environments/nonprod/variables.tf
Normal file
21
environments/nonprod/variables.tf
Normal file
@@ -0,0 +1,21 @@
|
||||
variable "proxmox_endpoint" {
|
||||
description = "URL of the Proxmox API endpoint, e.g. https://192.168.1.10:8006/"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "proxmox_api_token" {
|
||||
description = "Proxmox API token in the form user@realm!token-id=secret, e.g. terraform@pve!api-token-name=<SECRET>"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_insecure" {
|
||||
description = "Skip TLS certificate verification (set true for self-signed certs)"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "proxmox_node_name" {
|
||||
description = "Name of the Proxmox node to manage resources on"
|
||||
type = string
|
||||
}
|
||||
35
modules/networking/README.md
Normal file
35
modules/networking/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Module: networking
|
||||
|
||||
Creates the internal Linux bridge network segments on a Proxmox node. These bridges are purely virtual — no physical NIC is attached. All inter-segment traffic is routed through a firewall VM (OPNsense).
|
||||
|
||||
## Segments
|
||||
|
||||
| Bridge | CIDR | Purpose |
|
||||
|--------|------|---------|
|
||||
| management | 10.10.10.0/24 | Proxmox API access and admin tools. Proxmox host holds 10.10.10.1. |
|
||||
| services | 10.10.20.0/24 | General workload VMs and containers. |
|
||||
| dmz | 10.10.30.0/24 | Externally exposed workloads (e.g. web servers). |
|
||||
| isolated | 10.10.40.0/24 | Lab and test workloads. No outbound access by default. |
|
||||
|
||||
The Proxmox host has no IP on services, dmz, or isolated — VMs on those segments have no direct path to the hypervisor.
|
||||
|
||||
## Usage
|
||||
|
||||
```hcl
|
||||
module "networking" {
|
||||
source = "../../modules/networking"
|
||||
|
||||
proxmox_node_name = "pve"
|
||||
}
|
||||
```
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Type | Description |
|
||||
|------|------|-------------|
|
||||
| proxmox_node_name | string | Name of the Proxmox node to create bridges on. |
|
||||
|
||||
## Notes
|
||||
|
||||
- After apply, Proxmox automatically reloads the network configuration — no manual intervention required.
|
||||
- `Sys.Modify` must be granted to the Terraform API token role to manage node network interfaces.
|
||||
29
modules/networking/main.tf
Normal file
29
modules/networking/main.tf
Normal file
@@ -0,0 +1,29 @@
|
||||
resource "proxmox_network_linux_bridge" "management" {
|
||||
node_name = var.proxmox_node_name
|
||||
name = "management"
|
||||
|
||||
address = "10.10.10.1/24"
|
||||
|
||||
comment = "Terraform managed Linux bridge for Proxmox API access and admin tools"
|
||||
}
|
||||
|
||||
resource "proxmox_network_linux_bridge" "services" {
|
||||
node_name = var.proxmox_node_name
|
||||
name = "services"
|
||||
|
||||
comment = "Terraform managed Linux bridge for general workload VMs and containers"
|
||||
}
|
||||
|
||||
resource "proxmox_network_linux_bridge" "dmz" {
|
||||
node_name = var.proxmox_node_name
|
||||
name = "dmz"
|
||||
|
||||
comment = "Terraform managed Linux bridge for externally exposed VMs and containers (e.g. web servers)"
|
||||
}
|
||||
|
||||
resource "proxmox_network_linux_bridge" "isolated" {
|
||||
node_name = var.proxmox_node_name
|
||||
name = "isolated"
|
||||
|
||||
comment = "Terraform managed Linux bridge for Lab/test VMs and containers with no external connectivity"
|
||||
}
|
||||
7
modules/networking/terraform.tf
Normal file
7
modules/networking/terraform.tf
Normal file
@@ -0,0 +1,7 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
proxmox = {
|
||||
source = "bpg/proxmox"
|
||||
}
|
||||
}
|
||||
}
|
||||
4
modules/networking/variables.tf
Normal file
4
modules/networking/variables.tf
Normal file
@@ -0,0 +1,4 @@
|
||||
variable "proxmox_node_name" {
|
||||
description = "Name of the Proxmox node to manage resources on"
|
||||
type = string
|
||||
}
|
||||
Reference in New Issue
Block a user