Files
softwarefactory/infrastructure-admin/main.tf
2025-09-03 07:34:33 +02:00

335 lines
7.2 KiB
HCL

terraform {
required_providers {
proxmox = {
source = "Telmate/proxmox"
version = "3.0.2-rc04"
}
random = {
source = "hashicorp/random"
version = "3.7.2"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.38.0"
}
helm = {
source = "hashicorp/helm"
version = "3.0.2"
}
}
}
provider "proxmox" {
pm_api_url = var.proxmox_url
pm_user = var.proxmox_user
pm_password = var.proxmox_password
pm_tls_insecure = var.proxmox_tls_insecure
}
# ----------------------
# Generate k3s token
# ----------------------
resource "random_password" "k3s_token" {
length = 32
special = false
}
# ----------------------
# Controller VM
# ----------------------
resource "proxmox_vm_qemu" "controller" {
name = "k3s-controller"
target_node = var.target_nodes["controller"]
clone = var.template_id
full_clone = true
cpu {
cores = 2
sockets = 1
}
memory = 1024
scsihw = "virtio-scsi-pci"
disk {
slot = "scsi0"
size = "20G"
storage = var.storage
type = "disk"
}
network {
id = 0
model = "virtio"
bridge = var.bridge
}
ipconfig0 = "ip=${var.controller_ip}/${var.netmask},gw=${var.gateway}"
ciuser = "ubuntu"
sshkeys = var.ssh_public_key
cicustom = <<EOT
#cloud-config
package_update: true
packages:
- curl
runcmd:
- |
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --cluster-init --token=${random_password.k3s_token.result} --write-kubeconfig-mode=644" sh -
EOT
}
# ----------------------
# Worker 1 VM
# ----------------------
resource "proxmox_vm_qemu" "worker1" {
name = "k3s-worker1"
target_node = var.target_nodes["worker1"]
clone = var.template_id
full_clone = true
cpu {
cores = 2
sockets = 1
}
memory = 1024
scsihw = "virtio-scsi-pci"
disk {
slot = "scsi0"
size = "20G"
storage = var.storage
type = "disk"
}
network {
id = 0
model = "virtio"
bridge = var.bridge
}
ipconfig0 = "ip=${var.worker1_ip}/${var.netmask},gw=${var.gateway}"
ciuser = "ubuntu"
sshkeys = var.ssh_public_key
cicustom = <<EOT
#cloud-config
package_update: true
packages:
- curl
runcmd:
- |
curl -sfL https://${var.controller_ip}:6443 | K3S_URL=https://${var.controller_ip}:6443 K3S_TOKEN=${random_password.k3s_token.result} sh -
EOT
}
# ----------------------
# Worker 2 VM
# ----------------------
resource "proxmox_vm_qemu" "worker2" {
name = "k3s-worker2"
target_node = var.target_nodes["worker2"]
clone = var.template_id
full_clone = true
cpu {
cores = 2
sockets = 1
}
memory = 1024
scsihw = "virtio-scsi-pci"
disk {
slot = "scsi0"
size = "20G"
storage = var.storage
type = "disk"
}
network {
id = 0
model = "virtio"
bridge = var.bridge
}
ipconfig0 = "ip=${var.worker2_ip}/${var.netmask},gw=${var.gateway}"
ciuser = "ubuntu"
sshkeys = var.ssh_public_key
cicustom = <<EOT
#cloud-config
package_update: true
packages:
- curl
runcmd:
- |
curl -sfL https://${var.controller_ip}:6443 | K3S_URL=https://${var.controller_ip}:6443 K3S_TOKEN=${random_password.k3s_token.result} sh -
EOT
}
# ----------------------
# Kubernetes & Helm Providers (after cluster is ready)
# ----------------------
provider "kubernetes" {
config_path = "~/.kube/config"
}
provider "helm" {
kubernetes = {
config_path = "~/.kube/config"
}
}
# ----------------------
# Namespaces
# ----------------------
resource "kubernetes_namespace" "infra" {
metadata {
name = "infra"
}
}
resource "kubernetes_namespace" "devops" {
metadata {
name = "devops"
}
}
resource "kubernetes_namespace" "monitoring" {
metadata {
name = "monitoring"
}
}
# ----------------------
# Ingress
# ----------------------
resource "helm_release" "nginx_ingress" {
name = "nginx-ingress"
namespace = kubernetes_namespace.infra.metadata[0].name
repository = "https://kubernetes.github.io/ingress-nginx"
chart = "ingress-nginx"
version = "4.10.0"
}
# ----------------------
# cert-manager
# ----------------------
resource "helm_release" "cert_manager" {
name = "cert-manager"
namespace = kubernetes_namespace.infra.metadata[0].name
repository = "https://charts.jetstack.io"
chart = "cert-manager"
version = "v1.15.1"
values = [<<EOT
installCRDs: true
EOT
]
depends_on = [helm_release.nginx_ingress]
}
# ----------------------
# CoreDNS authoritative for lab.local
# ----------------------
resource "helm_release" "coredns" {
name = "coredns-ext"
namespace = kubernetes_namespace.infra.metadata[0].name
repository = "https://coredns.github.io/helm"
chart = "coredns"
version = "1.30.0"
values = [file("${path.module}/values/coredns-values.yaml")]
}
# ----------------------
# NTP Deployment
# ----------------------
resource "kubernetes_deployment" "ntp" {
metadata {
name = "ntp-server"
namespace = kubernetes_namespace.infra.metadata[0].name
}
spec {
replicas = 1
selector {
match_labels = {
app = "ntp"
}
}
template {
metadata {
labels = {
app = "ntp"
}
}
spec {
container {
name = "ntp"
image = "cturra/ntp:latest"
port {
container_port = 123
protocol = "UDP"
}
}
}
}
}
}
resource "kubernetes_service" "ntp" {
metadata {
name = "ntp-service"
namespace = kubernetes_namespace.infra.metadata[0].name
}
spec {
selector = {
app = "ntp"
}
port {
port = 123
target_port = 123
protocol = "UDP"
}
type = "ClusterIP"
}
}
# ----------------------
# GitLab Helm Release
# ----------------------
resource "helm_release" "gitlab" {
name = "gitlab"
namespace = kubernetes_namespace.devops.metadata[0].name
repository = "https://charts.gitlab.io/"
chart = "gitlab"
version = "7.7.0"
values = [file("${path.module}/values/gitlab-values.yaml")]
depends_on = [helm_release.nginx_ingress, helm_release.cert_manager]
}
# ----------------------
# Logging Stack
# ----------------------
resource "helm_release" "loki" {
name = "loki"
namespace = kubernetes_namespace.monitoring.metadata[0].name
repository = "https://grafana.github.io/helm-charts"
chart = "loki"
version = "5.41.4"
values = [file("${path.module}/values/loki-values.yaml")]
}
resource "helm_release" "promtail" {
name = "promtail"
namespace = kubernetes_namespace.monitoring.metadata[0].name
repository = "https://grafana.github.io/helm-charts"
chart = "promtail"
version = "6.15.5"
values = [file("${path.module}/values/promtail-values.yaml")]
depends_on = [helm_release.loki]
}
resource "helm_release" "grafana" {
name = "grafana"
namespace = kubernetes_namespace.monitoring.metadata[0].name
repository = "https://grafana.github.io/helm-charts"
chart = "grafana"
version = "7.3.9"
values = [file("${path.module}/values/grafana-values.yaml")]
depends_on = [helm_release.loki]
}