Add terraform for infra
This commit is contained in:
2
.gitlab/.gitlab-ci.yml
Normal file
2
.gitlab/.gitlab-ci.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
include:
|
||||||
|
- local: infra/.gitlab/.gitlab-ci.yml
|
||||||
94
infra/.gitlab/.gitlab-ci.yml
Normal file
94
infra/.gitlab/.gitlab-ci.yml
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
stages:
|
||||||
|
- plan
|
||||||
|
- apply
|
||||||
|
- destroy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
WORKDIR: $CI_PROJECT_DIR/infra
|
||||||
|
GITLAB_TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/infra
|
||||||
|
|
||||||
|
image:
|
||||||
|
name: registry.internal.durp.info/opentofu/opentofu:latest
|
||||||
|
entrypoint: [""]
|
||||||
|
|
||||||
|
.tf-init:
|
||||||
|
before_script:
|
||||||
|
- cd $WORKDIR
|
||||||
|
- |
|
||||||
|
tofu init -reconfigure -backend-config="address=${GITLAB_TF_ADDRESS}" \
|
||||||
|
-backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock" \
|
||||||
|
-backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock" \
|
||||||
|
-backend-config="username=gitlab-ci-token" \
|
||||||
|
-backend-config="password=${CI_JOB_TOKEN}" \
|
||||||
|
-backend-config="lock_method=POST" \
|
||||||
|
-backend-config="unlock_method=DELETE" \
|
||||||
|
-backend-config="retry_wait_min=5"
|
||||||
|
|
||||||
|
format:
|
||||||
|
stage: .pre
|
||||||
|
allow_failure: false
|
||||||
|
script:
|
||||||
|
- cd $WORKDIR
|
||||||
|
- tofu fmt -diff -check -write=false
|
||||||
|
rules:
|
||||||
|
- changes:
|
||||||
|
- .tf
|
||||||
|
|
||||||
|
validate:
|
||||||
|
stage: .pre
|
||||||
|
allow_failure: false
|
||||||
|
extends: .tf-init
|
||||||
|
script:
|
||||||
|
- tofu validate
|
||||||
|
rules:
|
||||||
|
- changes:
|
||||||
|
- .tf
|
||||||
|
|
||||||
|
plan-infrastructure:
|
||||||
|
stage: plan
|
||||||
|
variables:
|
||||||
|
PLAN: plan.tfplan
|
||||||
|
JSON_PLAN_FILE: tfplan.json
|
||||||
|
ENVIRONMENT_NAME: infra
|
||||||
|
allow_failure: false
|
||||||
|
extends: .tf-init
|
||||||
|
script:
|
||||||
|
- apk add --update curl jq
|
||||||
|
- alias convert_report="jq -r '([.resource_changes[].change.actions?]|flatten)|{\"create\":(map(select(.==\"create\"))|length),\"update\":(map(select(.==\"update\"))|length),\"delete\":(map(select(.==\"delete\"))|length)}'"
|
||||||
|
- tofu plan -out=$PLAN $ARGUMENTS
|
||||||
|
- tofu show --json $PLAN | jq -r '([.resource_changes[].change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > $JSON_PLAN_FILE
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
terraform: $WORKDIR/$JSON_PLAN_FILE
|
||||||
|
needs: ["validate","format"]
|
||||||
|
rules:
|
||||||
|
- changes:
|
||||||
|
- .tf
|
||||||
|
|
||||||
|
apply-infrastructure:
|
||||||
|
stage: apply
|
||||||
|
variables:
|
||||||
|
ENVIRONMENT_NAME: infra
|
||||||
|
allow_failure: false
|
||||||
|
extends: .tf-init
|
||||||
|
script:
|
||||||
|
- tofu apply -auto-approve $ARGUMENTS
|
||||||
|
rules:
|
||||||
|
- changes:
|
||||||
|
- .tf
|
||||||
|
when: manual
|
||||||
|
needs: ["plan-infrastructure"]
|
||||||
|
|
||||||
|
destroy-infrastructure:
|
||||||
|
stage: destroy
|
||||||
|
variables:
|
||||||
|
ENVIRONMENT_NAME: infra
|
||||||
|
allow_failure: false
|
||||||
|
extends: .tf-init
|
||||||
|
script:
|
||||||
|
- tofu destory -auto-approve $ARGUMENTS
|
||||||
|
rules:
|
||||||
|
- changes:
|
||||||
|
- .tf
|
||||||
|
when: manual
|
||||||
|
needs: ["plan-infrastructure"]
|
||||||
12
infra/authentik/Chart.yaml
Normal file
12
infra/authentik/Chart.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: authentik
|
||||||
|
description: A Helm chart for Kubernetes
|
||||||
|
type: application
|
||||||
|
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "1.16.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- name: authentik
|
||||||
|
repository: https://charts.goauthentik.io
|
||||||
|
version: 2024.8.3
|
||||||
42
infra/authentik/templates/ingress.yaml
Normal file
42
infra/authentik/templates/ingress.yaml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: authentik-ingress
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`authentik.durp.info`) && PathPrefix(`/`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: authentik-server
|
||||||
|
port: 80
|
||||||
|
tls:
|
||||||
|
secretName: authentik-tls
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: authentik-tls
|
||||||
|
spec:
|
||||||
|
secretName: authentik-tls
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-production
|
||||||
|
kind: ClusterIssuer
|
||||||
|
commonName: "authentik.durp.info"
|
||||||
|
dnsNames:
|
||||||
|
- "authentik.durp.info"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
kind: Service
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: authentik-external-dns
|
||||||
|
annotations:
|
||||||
|
external-dns.alpha.kubernetes.io/hostname: authentik.durp.info
|
||||||
|
spec:
|
||||||
|
type: ExternalName
|
||||||
|
externalName: durp.info
|
||||||
28
infra/authentik/templates/secrets.yaml
Normal file
28
infra/authentik/templates/secrets.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
apiVersion: external-secrets.io/v1beta1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: authentik-secret
|
||||||
|
spec:
|
||||||
|
secretStoreRef:
|
||||||
|
name: vault
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
target:
|
||||||
|
name: db-pass
|
||||||
|
data:
|
||||||
|
- secretKey: dbpass
|
||||||
|
remoteRef:
|
||||||
|
key: secrets/authentik/database
|
||||||
|
property: dbpass
|
||||||
|
- secretKey: secretkey
|
||||||
|
remoteRef:
|
||||||
|
key: secrets/authentik/database
|
||||||
|
property: secretkey
|
||||||
|
- secretKey: postgresql-postgres-password
|
||||||
|
remoteRef:
|
||||||
|
key: secrets/authentik/database
|
||||||
|
property: dbpass
|
||||||
|
- secretKey: postgresql-password
|
||||||
|
remoteRef:
|
||||||
|
key: secrets/authentik/database
|
||||||
|
property: dbpass
|
||||||
|
|
||||||
56
infra/authentik/values.yaml
Normal file
56
infra/authentik/values.yaml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
authentik:
|
||||||
|
global:
|
||||||
|
env:
|
||||||
|
- name: AUTHENTIK_POSTGRESQL__PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: db-pass
|
||||||
|
key: dbpass
|
||||||
|
- name: AUTHENTIK_SECRET_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: db-pass
|
||||||
|
key: secretkey
|
||||||
|
revisionHistoryLimit: 1
|
||||||
|
image:
|
||||||
|
repository: registry.durp.info/goauthentik/server
|
||||||
|
pullPolicy: Always
|
||||||
|
authentik:
|
||||||
|
outposts:
|
||||||
|
container_image_base: registry.durp.info/goauthentik/%(type)s:%(version)s
|
||||||
|
postgresql:
|
||||||
|
host: '{{ .Release.Name }}-postgresql-hl'
|
||||||
|
name: "authentik"
|
||||||
|
user: "authentik"
|
||||||
|
port: 5432
|
||||||
|
server:
|
||||||
|
name: server
|
||||||
|
replicas: 3
|
||||||
|
worker:
|
||||||
|
replicas: 3
|
||||||
|
postgresql:
|
||||||
|
enabled: true
|
||||||
|
image:
|
||||||
|
registry: registry.durp.info
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
pullPolicy: Always
|
||||||
|
postgresqlUsername: "authentik"
|
||||||
|
postgresqlDatabase: "authentik"
|
||||||
|
existingSecret: db-pass
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
storageClass: longhorn
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteMany
|
||||||
|
redis:
|
||||||
|
enabled: true
|
||||||
|
master:
|
||||||
|
persistence:
|
||||||
|
enabled: false
|
||||||
|
image:
|
||||||
|
registry: registry.durp.info
|
||||||
|
repository: bitnami/redis
|
||||||
|
pullPolicy: Always
|
||||||
|
architecture: standalone
|
||||||
|
auth:
|
||||||
|
enabled: false
|
||||||
149
infra/terraform/main.tf
Normal file
149
infra/terraform/main.tf
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
terraform {
|
||||||
|
backend "http" {}
|
||||||
|
required_providers {
|
||||||
|
proxmox = {
|
||||||
|
source = "Telmate/proxmox"
|
||||||
|
version = "3.0.1-rc6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "proxmox" {
|
||||||
|
pm_parallel = 1
|
||||||
|
pm_tls_insecure = true
|
||||||
|
pm_api_url = var.pm_api_url
|
||||||
|
pm_user = var.pm_user
|
||||||
|
pm_password = var.pm_password
|
||||||
|
pm_debug = false
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
sshkeys = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDEphzWgwUZnvL6E5luKLt3WO0HK7Kh63arSMoNl5gmjzXyhG1DDW0OKfoIl0T+JZw/ZjQ7iii6tmSLFRk6nuYCldqe5GVcFxvTzX4/xGEioAyG0IiUGKy6s+9xzO8QXF0EtSNPH0nfHNKcCjgwWAzM+Lt6gW0Vqs+aU5ICuDiEchmvYPz+rBaVldJVTG7m3ogKJ2aIF7HU/pCPp5l0E9gMOw7s0ABijuc3KXLEWCYgL39jIST6pFH9ceRLmu8Xy5zXHAkkEEauY/e6ld0hlzLadiUD7zYJMdDcm0oRvenYcUlaUl9gS0569IpfsJsjCejuqOxCKzTHPJDOT0f9TbIqPXkGq3s9oEJGpQW+Z8g41BqRpjBCdBk+yv39bzKxlwlumDwqgx1WP8xxKavAWYNqNRG7sBhoWwtxYEOhKXoLNjBaeDRnO5OY5AQJvONWpuByyz0R/gTh4bOFVD+Y8WWlKbT4zfhnN70XvapRsbZiaGhJBPwByAMGg6XxSbC6xtbyligVGCEjCXbTLkeKq1w0DuItY+FBGO3J2k90OiciTVSeyiVz9J/Y03UB0gHdsMCoVNrj+9QWfrTLDhM7D5YrXUt5nj2LQTcbtf49zoQXWxUhozlg42E/FJU/Yla7y55qWizAEVyP2/Ks/PHrF679k59HNd2IJ/aicA9QnmWtLQ== ansible"
|
||||||
|
template = "Debian12-Template"
|
||||||
|
storage = "cache-domains"
|
||||||
|
emulatessd = true
|
||||||
|
format = "raw"
|
||||||
|
dnsserver = "192.168.12.1"
|
||||||
|
tags = "postgres"
|
||||||
|
vlan = 12
|
||||||
|
postgres = {
|
||||||
|
count = 3
|
||||||
|
name = ["postgres-01", "postgres-02", "postgres-03"]
|
||||||
|
cores = 2
|
||||||
|
memory = "1024"
|
||||||
|
drive = 20
|
||||||
|
node = ["mothership", "overlord", "vanguard"]
|
||||||
|
ip = ["31", "32", "33"]
|
||||||
|
}
|
||||||
|
postgres = {
|
||||||
|
count = 3
|
||||||
|
name = ["postgres-01", "postgres-02", "postgres-03"]
|
||||||
|
cores = 4
|
||||||
|
memory = "4096"
|
||||||
|
drive = 40
|
||||||
|
node = ["mothership", "overlord", "vanguard"]
|
||||||
|
ip = ["34", "35", "36"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "proxmox_vm_qemu" "postgres" {
|
||||||
|
count = local.postgres.count
|
||||||
|
ciuser = "administrator"
|
||||||
|
vmid = "${local.vlan}${local.postgres.ip[count.index]}"
|
||||||
|
name = local.postgres.name[count.index]
|
||||||
|
target_node = local.postgres.node[count.index]
|
||||||
|
clone = local.template
|
||||||
|
tags = local.tags
|
||||||
|
qemu_os = "l26"
|
||||||
|
full_clone = true
|
||||||
|
os_type = "cloud-init"
|
||||||
|
agent = 1
|
||||||
|
cores = local.postgres.cores
|
||||||
|
sockets = 1
|
||||||
|
cpu_type = "host"
|
||||||
|
memory = local.postgres.memory
|
||||||
|
scsihw = "virtio-scsi-pci"
|
||||||
|
#bootdisk = "scsi0"
|
||||||
|
boot = "order=virtio0"
|
||||||
|
onboot = true
|
||||||
|
sshkeys = local.sshkeys
|
||||||
|
disks {
|
||||||
|
ide {
|
||||||
|
ide2 {
|
||||||
|
cloudinit {
|
||||||
|
storage = local.storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtio {
|
||||||
|
virtio0 {
|
||||||
|
disk {
|
||||||
|
size = local.postgres.drive
|
||||||
|
format = local.format
|
||||||
|
storage = local.storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
network {
|
||||||
|
id = 0
|
||||||
|
model = "virtio"
|
||||||
|
bridge = "vmbr0"
|
||||||
|
tag = local.vlan
|
||||||
|
}
|
||||||
|
#Cloud Init Settings
|
||||||
|
ipconfig0 = "ip=192.168.${local.vlan}.${local.postgres.ip[count.index]}/24,gw=192.168.${local.vlan}.1"
|
||||||
|
searchdomain = "durp.loc"
|
||||||
|
nameserver = local.dnsserver
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "proxmox_vm_qemu" "postgres" {
|
||||||
|
count = local.postgres.count
|
||||||
|
ciuser = "administrator"
|
||||||
|
vmid = "${local.vlan}${local.postgres.ip[count.index]}"
|
||||||
|
name = local.postgres.name[count.index]
|
||||||
|
target_node = local.postgres.node[count.index]
|
||||||
|
clone = local.template
|
||||||
|
tags = local.tags
|
||||||
|
qemu_os = "l26"
|
||||||
|
full_clone = true
|
||||||
|
os_type = "cloud-init"
|
||||||
|
agent = 1
|
||||||
|
cores = local.postgres.cores
|
||||||
|
sockets = 1
|
||||||
|
cpu_type = "host"
|
||||||
|
memory = local.postgres.memory
|
||||||
|
scsihw = "virtio-scsi-pci"
|
||||||
|
#bootdisk = "scsi0"
|
||||||
|
boot = "order=virtio0"
|
||||||
|
onboot = true
|
||||||
|
sshkeys = local.sshkeys
|
||||||
|
disks {
|
||||||
|
ide {
|
||||||
|
ide2 {
|
||||||
|
cloudinit {
|
||||||
|
storage = local.storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtio {
|
||||||
|
virtio0 {
|
||||||
|
disk {
|
||||||
|
size = local.postgres.drive
|
||||||
|
format = local.format
|
||||||
|
storage = local.storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
network {
|
||||||
|
id = 0
|
||||||
|
model = "virtio"
|
||||||
|
bridge = "vmbr0"
|
||||||
|
tag = local.vlan
|
||||||
|
}
|
||||||
|
#Cloud Init Settings
|
||||||
|
ipconfig0 = "ip=192.168.${local.vlan}.${local.postgres.ip[count.index]}/24,gw=192.168.${local.vlan}.1"
|
||||||
|
searchdomain = "durp.loc"
|
||||||
|
nameserver = local.dnsserver
|
||||||
|
}
|
||||||
14
infra/terraform/variables.tf
Normal file
14
infra/terraform/variables.tf
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
variable "pm_api_url" {
|
||||||
|
description = "API URL to Proxmox provider"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pm_password" {
|
||||||
|
description = "Passowrd to Proxmox provider"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pm_user" {
|
||||||
|
description = "UIsername to Proxmox provider"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user