initial upload
This commit is contained in:
5
terraform/.gitignore
vendored
Normal file
5
terraform/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Terraform
|
||||
.terraform/
|
||||
.terraform.lock.hcl
|
||||
terraform.tfstate*
|
||||
terraform.tfvars
|
||||
16
terraform/data.tf
Normal file
16
terraform/data.tf
Normal file
@@ -0,0 +1,16 @@
|
||||
# Expects secrets at specific paths in Vault KV v2 (mount point 'secret/')
|
||||
|
||||
data "vault_generic_secret" "proxmox" {
|
||||
count = var.use_vault ? 1 : 0
|
||||
path = "secret/infrastructure/proxmox"
|
||||
}
|
||||
|
||||
data "vault_generic_secret" "opnsense" {
|
||||
count = var.use_vault ? 1 : 0
|
||||
path = "secret/infrastructure/opnsense"
|
||||
}
|
||||
|
||||
data "vault_generic_secret" "vm_creds" {
|
||||
count = var.use_vault ? 1 : 0
|
||||
path = "secret/infrastructure/vm-credentials"
|
||||
}
|
||||
25
terraform/locals.tf
Normal file
25
terraform/locals.tf
Normal file
@@ -0,0 +1,25 @@
|
||||
locals {
|
||||
# SSH Public Key for Provisioning
|
||||
ssh_key = var.use_vault ? data.vault_generic_secret.vm_creds[0].data["ssh_public_key"] : var.ssh_public_key
|
||||
|
||||
# CI Credentials
|
||||
ci_user = var.use_vault ? data.vault_generic_secret.vm_creds[0].data["ci_user"] : var.ci_user
|
||||
ci_password = var.use_vault ? data.vault_generic_secret.vm_creds[0].data["ci_password"] : var.ci_password
|
||||
|
||||
vms = {
|
||||
# VLAN 30: Docker
|
||||
"vm-docker-mailcow-300" = { id = 300, cores = 4, memory = 8192, vlan = 30, tags = "docker,mailcow", ip = "10.100.30.10", gw = "10.100.30.1" }
|
||||
"vm-docker-apps-301" = { id = 301, cores = 2, memory = 4096, vlan = 30, tags = "docker,apps", ip = "10.100.30.11", gw = "10.100.30.1" }
|
||||
"vm-docker-traefik-302" = { id = 302, cores = 1, memory = 2048, vlan = 30, tags = "docker,ingress", ip = "10.100.30.12", gw = "10.100.30.1" }
|
||||
|
||||
# VLAN 40: K3s
|
||||
"vm-k3s-master-400" = { id = 400, cores = 2, memory = 4096, vlan = 40, tags = "k3s,master", ip = "10.100.40.10", gw = "10.100.40.1" }
|
||||
"vm-k3s-worker-401" = { id = 401, cores = 2, memory = 4096, vlan = 40, tags = "k3s,worker", ip = "10.100.40.11", gw = "10.100.40.1" }
|
||||
"vm-k3s-worker-402" = { id = 402, cores = 2, memory = 4096, vlan = 40, tags = "k3s,worker", ip = "10.100.40.12", gw = "10.100.40.1" }
|
||||
"vm-k3s-worker-403" = { id = 403, cores = 2, memory = 4096, vlan = 40, tags = "k3s,worker", ip = "10.100.40.13", gw = "10.100.40.1" }
|
||||
|
||||
# VLAN 90: Bastion
|
||||
"vm-bastion-900" = { id = 900, cores = 1, memory = 2048, vlan = 90, tags = "bastion", ip = "10.100.90.10", gw = "10.100.90.1" }
|
||||
"vm-bastion-901" = { id = 901, cores = 1, memory = 2048, vlan = 90, tags = "bastion", ip = "10.100.90.11", gw = "10.100.90.1" }
|
||||
}
|
||||
}
|
||||
79
terraform/main.tf
Normal file
79
terraform/main.tf
Normal file
@@ -0,0 +1,79 @@
|
||||
resource "proxmox_vm_qemu" "vm_deployment" {
|
||||
for_each = local.vms
|
||||
|
||||
target_node = var.pm_node
|
||||
|
||||
name = "${each.key}.stabify.de"
|
||||
vmid = each.value.id
|
||||
|
||||
description = "Managed by Terraform. VLAN: ${each.value.vlan} Role: ${each.value.tags} IP: ${each.value.ip}"
|
||||
clone = var.template_name
|
||||
full_clone = true
|
||||
agent = 1
|
||||
|
||||
start_at_node_boot = true
|
||||
define_connection_info = false
|
||||
|
||||
cpu {
|
||||
cores = each.value.cores
|
||||
sockets = 1
|
||||
}
|
||||
|
||||
memory = each.value.memory
|
||||
balloon = 0
|
||||
scsihw = "virtio-scsi-pci"
|
||||
boot = "order=scsi0;net0"
|
||||
|
||||
serial {
|
||||
id = 0
|
||||
type = "socket"
|
||||
}
|
||||
|
||||
disk {
|
||||
slot = "scsi0"
|
||||
size = "32G"
|
||||
type = "disk"
|
||||
storage = "local-lvm"
|
||||
iothread = true
|
||||
}
|
||||
|
||||
disk {
|
||||
slot = "ide2"
|
||||
type = "cloudinit"
|
||||
storage = "local-lvm"
|
||||
}
|
||||
|
||||
network {
|
||||
id = 0
|
||||
model = "virtio"
|
||||
bridge = "vmbr1"
|
||||
tag = each.value.vlan
|
||||
}
|
||||
|
||||
os_type = "cloud-init"
|
||||
|
||||
searchdomain = "stabify.de"
|
||||
nameserver = each.value.gw
|
||||
|
||||
ciuser = local.ci_user
|
||||
cipassword = local.ci_password
|
||||
sshkeys = local.ssh_key
|
||||
|
||||
ipconfig0 = "ip=${each.value.ip}/24,gw=${each.value.gw}"
|
||||
|
||||
tags = each.value.tags
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [ network ]
|
||||
}
|
||||
}
|
||||
|
||||
resource "opnsense_unbound_host_override" "dns_entries" {
|
||||
for_each = local.vms
|
||||
|
||||
enabled = true
|
||||
hostname = each.key
|
||||
domain = "stabify.de"
|
||||
description = "Managed by Terraform: ${each.value.tags}"
|
||||
server = each.value.ip
|
||||
}
|
||||
20
terraform/providers.tf
Normal file
20
terraform/providers.tf
Normal file
@@ -0,0 +1,20 @@
|
||||
provider "vault" {
|
||||
# Configuration via VAULT_ADDR and VAULT_TOKEN env vars
|
||||
}
|
||||
|
||||
provider "proxmox" {
|
||||
pm_tls_insecure = true
|
||||
pm_api_url = var.proxmox_api_url
|
||||
|
||||
# Logic: If use_vault is true, verify vault data exists, otherwise use vars
|
||||
pm_api_token_id = var.use_vault ? data.vault_generic_secret.proxmox[0].data["api_token_id"] : var.proxmox_api_token_id
|
||||
pm_api_token_secret = var.use_vault ? data.vault_generic_secret.proxmox[0].data["api_token_secret"] : var.proxmox_api_token_secret
|
||||
}
|
||||
|
||||
provider "opnsense" {
|
||||
uri = var.use_vault ? data.vault_generic_secret.opnsense[0].data["uri"] : var.opnsense_uri
|
||||
allow_insecure = true
|
||||
|
||||
api_key = var.use_vault ? data.vault_generic_secret.opnsense[0].data["api_key"] : var.opnsense_api_key
|
||||
api_secret = var.use_vault ? data.vault_generic_secret.opnsense[0].data["api_secret"] : var.opnsense_api_secret
|
||||
}
|
||||
67
terraform/variables.tf
Normal file
67
terraform/variables.tf
Normal file
@@ -0,0 +1,67 @@
|
||||
variable "use_vault" {
|
||||
type = bool
|
||||
default = true
|
||||
description = "Set to false to bypass Vault and use local variables (Bootstrap Mode)"
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_id" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "proxmox_api_token_secret" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "opnsense_api_key" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "opnsense_api_secret" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ci_user" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ci_password" {
|
||||
type = string
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "proxmox_api_url" {
|
||||
type = string
|
||||
default = "https://10.100.0.2:8006/api2/json"
|
||||
}
|
||||
|
||||
variable "pm_node" {
|
||||
type = string
|
||||
default = "hzfsn-pve-01"
|
||||
}
|
||||
|
||||
variable "template_name" {
|
||||
type = string
|
||||
default = "ubuntu-2404-ci"
|
||||
description = "Name des Cloud-Init Templates auf dem Node"
|
||||
}
|
||||
|
||||
variable "opnsense_uri" {
|
||||
type = string
|
||||
description = "URI to OPNsense API"
|
||||
default = null
|
||||
}
|
||||
26
terraform/versions.tf
Normal file
26
terraform/versions.tf
Normal file
@@ -0,0 +1,26 @@
|
||||
terraform {
|
||||
required_version = ">= 1.5.0"
|
||||
|
||||
# Enterprise: Remote State Management (Placeholder)
|
||||
# backend "s3" {
|
||||
# bucket = "terraform-state"
|
||||
# key = "prod/infrastructure.tfstate"
|
||||
# region = "eu-central-1"
|
||||
# }
|
||||
|
||||
required_providers {
|
||||
proxmox = {
|
||||
source = "telmate/proxmox"
|
||||
version = "3.0.2-rc07" # Pinned as requested
|
||||
}
|
||||
opnsense = {
|
||||
source = "browningluke/opnsense"
|
||||
version = "0.16.1"
|
||||
}
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "~> 3.24.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user