[ci skip] Move Terraform modules into stack directories

Move all 88 service modules (66 individual + 22 platform) from
modules/kubernetes/<service>/ into their corresponding stack directories:

- Service stacks: stacks/<service>/module/
- Platform stack: stacks/platform/modules/<service>/

This collocates module source code with its Terragrunt definition.
Only shared utility modules remain in modules/kubernetes/:
ingress_factory, setup_tls_secret, dockerhub_secret, oauth-proxy.

All cross-references to shared modules updated to use correct
relative paths. Verified with terragrunt run --all -- plan:
0 adds, 0 destroys across all 68 stacks.
This commit is contained in:
Viktor Barzin 2026-02-22 14:38:14 +00:00
parent 73cb696f12
commit e225e81ebf
No known key found for this signature in database
GPG key ID: 0EB088298288D958
614 changed files with 12075 additions and 352 deletions

59
stacks/actualbudget/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,59 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/random" {
version = "3.8.1"
hashes = [
"h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=",
"zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4",
"zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae",
"zh:229665ddf060aa0ed315597908483eee5b818a17d09b6417a0f52fd9405c4f57",
"zh:2469d2e48f28076254a2a3fc327f184914566d9e40c5780b8d96ebf7205f8bc0",
"zh:37d7eb334d9561f335e748280f5535a384a88675af9a9eac439d4cfd663bcb66",
"zh:741101426a2f2c52dee37122f0f4a2f2d6af6d852cb1db634480a86398fa3511",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:a902473f08ef8df62cfe6116bd6c157070a93f66622384300de235a533e9d4a9",
"zh:b85c511a23e57a2147355932b3b6dce2a11e856b941165793a0c3d7578d94d05",
"zh:c5172226d18eaac95b1daac80172287b69d4ce32750c82ad77fa0768be4ea4b8",
"zh:dab4434dba34aad569b0bc243c2d3f3ff86dd7740def373f2a49816bd2ff819b",
"zh:f49fd62aa8c5525a5c17abd51e27ca5e213881d58882fd42fec4a545b53c9699",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/actualbudget/terraform.tfstate"
}
}

View file

@ -12,8 +12,8 @@ locals {
}
module "actualbudget" {
source = "../../modules/kubernetes/actualbudget"
tls_secret_name = var.tls_secret_name
tier = local.tiers.edge
credentials = var.actualbudget_credentials
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.edge
credentials = var.actualbudget_credentials
}

View file

@ -0,0 +1,213 @@
variable "tls_secret_name" {}
variable "name" {}
variable "tag" {
default = "latest"
}
variable "tier" { type = string }
variable "sync_id" {
type = string
default = null # If not passed, we won't run banksync
}
variable "budget_encryption_password" {
type = string
default = null # If not passed, we won't run banksync ;known after initial installation
}
resource "kubernetes_deployment" "actualbudget" {
metadata {
name = "actualbudget-${var.name}"
namespace = "actualbudget"
labels = {
app = "actualbudget-${var.name}"
tier = var.tier
}
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "actualbudget-${var.name}"
}
}
template {
metadata {
annotations = {
"diun.enable" = "false" # daily updates; pretty noisy
"diun.include_tags" = "^${var.tag}$"
}
labels = {
app = "actualbudget-${var.name}"
}
}
spec {
container {
image = "actualbudget/actual-server:${var.tag}"
name = "actualbudget"
port {
container_port = 5006
}
volume_mount {
name = "data"
mount_path = "/data"
}
}
volume {
name = "data"
nfs {
path = "/mnt/main/actualbudget/${var.name}"
server = "10.0.10.15"
}
}
}
}
}
}
resource "kubernetes_service" "actualbudget" {
metadata {
name = "budget-${var.name}"
namespace = "actualbudget"
labels = {
app = "actualbudget-${var.name}"
}
}
spec {
selector = {
app = "actualbudget-${var.name}"
}
port {
name = "http"
port = 80
target_port = 5006
}
}
}
module "ingress" {
source = "../../../../modules/kubernetes/ingress_factory"
namespace = "actualbudget"
name = "budget-${var.name}"
tls_secret_name = var.tls_secret_name
rybbit_site_id = "3e6b6b68088a"
}
resource "random_string" "api-key" {
length = 32
lower = true
}
resource "kubernetes_deployment" "actualbudget-http-api" {
count = var.budget_encryption_password != null ? 1 : 0
metadata {
name = "actualbudget-http-api-${var.name}"
namespace = "actualbudget"
labels = {
app = "actualbudget-http-api-${var.name}"
tier = var.tier
}
}
spec {
replicas = 1
strategy {
type = "RollingUpdate"
}
selector {
match_labels = {
app = "actualbudget-http-api-${var.name}"
}
}
template {
metadata {
labels = {
app = "actualbudget-http-api-${var.name}"
}
}
spec {
container {
image = "jhonderson/actual-http-api:latest"
name = "actualbudget"
port {
container_port = 5007
}
env {
name = "ACTUAL_SERVER_URL"
value = "https://budget-${var.name}.viktorbarzin.me"
}
env {
name = "ACTUAL_SERVER_PASSWORD"
value = var.budget_encryption_password
}
env {
name = "API_KEY"
value = random_string.api-key.result
}
}
}
}
}
}
resource "kubernetes_service" "actualbudget-http-api" {
metadata {
name = "budget-http-api-${var.name}"
namespace = "actualbudget"
labels = {
app = "actualbudget-http-api-${var.name}"
}
}
spec {
selector = {
app = "actualbudget-http-api-${var.name}"
}
port {
name = "http"
port = 80
target_port = 5007
}
}
}
resource "kubernetes_cron_job_v1" "bank-sync" {
count = var.sync_id != null && var.budget_encryption_password != null ? 1 : 0
metadata {
name = "bank-sync-${var.name}"
namespace = "actualbudget"
}
spec {
concurrency_policy = "Replace"
failed_jobs_history_limit = 5
schedule = "0 0 * * *" # Daily
starting_deadline_seconds = 10
successful_jobs_history_limit = 10
job_template {
metadata {}
spec {
backoff_limit = 3
ttl_seconds_after_finished = 10
template {
metadata {}
spec {
container {
name = "bank-sync"
image = "curlimages/curl"
command = ["/bin/sh", "-c", <<-EOT
# set -eux # Shows credentials so use only when debugging
curl -X POST --location 'http://budget-http-api-${var.name}/v1/budgets/${var.sync_id}/accounts/banksync' --header 'accept: application/json' --header 'budget-encryption-password: ${var.budget_encryption_password}' --header 'x-api-key: ${random_string.api-key.result}'
EOT
]
}
}
}
}
}
}
}

View file

@ -0,0 +1,63 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "credentials" { type = map(any) }
# To create a new deployment:
/**
1. Export a new nfs share with {name} in truenas
2. Add {name} as proxied cloudflare route (tfvars)
3. Add module here
*/
resource "kubernetes_namespace" "actualbudget" {
metadata {
name = "actualbudget"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.actualbudget.metadata[0].name
tls_secret_name = var.tls_secret_name
}
# https://budget-viktor.viktorbarzin.me/
module "viktor" {
source = "./factory"
name = "viktor"
tag = "edge"
tls_secret_name = var.tls_secret_name
depends_on = [kubernetes_namespace.actualbudget]
tier = var.tier
budget_encryption_password = lookup(var.credentials["viktor"], "password", null)
sync_id = lookup(var.credentials["viktor"], "sync_id", null)
}
# https://budget-anca.viktorbarzin.me/
module "anca" {
source = "./factory"
name = "anca"
tag = "edge"
tls_secret_name = var.tls_secret_name
depends_on = [kubernetes_namespace.actualbudget]
tier = var.tier
budget_encryption_password = lookup(var.credentials["anca"], "password", null)
sync_id = lookup(var.credentials["anca"], "sync_id", null)
}
# https://budget-emo.viktorbarzin.me/
module "emo" {
source = "./factory"
name = "emo"
tag = "edge"
tls_secret_name = var.tls_secret_name
depends_on = [kubernetes_namespace.actualbudget]
tier = var.tier
budget_encryption_password = lookup(var.credentials["emo"], "password", null)
sync_id = lookup(var.credentials["emo"], "sync_id", null)
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/actualbudget/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/affine/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

6
stacks/affine/backend.tf Normal file
View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/affine/terraform.tfstate"
}
}

View file

@ -13,9 +13,9 @@ locals {
}
module "affine" {
source = "../../modules/kubernetes/affine"
tls_secret_name = var.tls_secret_name
postgresql_password = var.affine_postgresql_password
smtp_password = var.mailserver_accounts["info@viktorbarzin.me"]
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
postgresql_password = var.affine_postgresql_password
smtp_password = var.mailserver_accounts["info@viktorbarzin.me"]
tier = local.tiers.aux
}

View file

@ -0,0 +1,217 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "postgresql_password" {}
variable "smtp_password" { type = string }
resource "kubernetes_namespace" "affine" {
metadata {
name = "affine"
labels = {
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.affine.metadata[0].name
tls_secret_name = var.tls_secret_name
}
locals {
common_env = [
{
name = "DATABASE_URL"
value = "postgresql://affine:${var.postgresql_password}@postgresql.dbaas.svc.cluster.local:5432/affine"
},
{
name = "REDIS_SERVER_HOST"
value = "redis.redis.svc.cluster.local"
},
{
name = "AFFINE_INDEXER_ENABLED"
value = "false"
},
{
name = "NODE_OPTIONS"
value = "--max-old-space-size=4096"
},
# Server URL configuration
{
name = "AFFINE_SERVER_EXTERNAL_URL"
value = "https://affine.viktorbarzin.me"
},
{
name = "AFFINE_SERVER_HTTPS"
value = "true"
},
# Email/SMTP configuration
{
name = "MAILER_HOST"
value = "mailserver.viktorbarzin.me"
},
{
name = "MAILER_PORT"
value = "587"
},
{
name = "MAILER_USER"
value = "info@viktorbarzin.me"
},
{
name = "MAILER_PASSWORD"
value = var.smtp_password
},
{
name = "MAILER_SENDER"
value = "AFFiNE <info@viktorbarzin.me>"
},
]
}
resource "kubernetes_deployment" "affine" {
metadata {
name = "affine"
namespace = kubernetes_namespace.affine.metadata[0].name
labels = {
app = "affine"
tier = var.tier
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "affine"
}
}
template {
metadata {
labels = {
app = "affine"
}
}
spec {
# Init container to run database migrations
init_container {
name = "migration"
image = "ghcr.io/toeverything/affine:stable"
command = ["sh", "-c", "npx prisma migrate deploy && SERVER_FLAVOR=script node ./dist/main.js run"]
dynamic "env" {
for_each = local.common_env
content {
name = env.value.name
value = env.value.value
}
}
volume_mount {
name = "data"
mount_path = "/root/.affine/storage"
sub_path = "storage"
}
volume_mount {
name = "data"
mount_path = "/root/.affine/config"
sub_path = "config"
}
}
container {
name = "affine"
image = "ghcr.io/toeverything/affine:stable"
port {
container_port = 3010
}
dynamic "env" {
for_each = local.common_env
content {
name = env.value.name
value = env.value.value
}
}
volume_mount {
name = "data"
mount_path = "/root/.affine/storage"
sub_path = "storage"
}
volume_mount {
name = "data"
mount_path = "/root/.affine/config"
sub_path = "config"
}
resources {
requests = {
memory = "512Mi"
cpu = "100m"
}
limits = {
memory = "4Gi"
cpu = "2"
}
}
liveness_probe {
http_get {
path = "/info"
port = 3010
}
initial_delay_seconds = 120
period_seconds = 30
timeout_seconds = 10
}
readiness_probe {
http_get {
path = "/info"
port = 3010
}
initial_delay_seconds = 60
period_seconds = 10
timeout_seconds = 5
}
}
volume {
name = "data"
nfs {
server = "10.0.10.15"
path = "/mnt/main/affine"
}
}
}
}
}
}
resource "kubernetes_service" "affine" {
metadata {
name = "affine"
namespace = kubernetes_namespace.affine.metadata[0].name
labels = {
app = "affine"
}
}
spec {
selector = {
app = "affine"
}
port {
name = "http"
port = 80
target_port = 3010
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.affine.metadata[0].name
name = "affine"
tls_secret_name = var.tls_secret_name
max_body_size = "500m"
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/affine/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/audiobookshelf/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "audiobookshelf" {
source = "../../modules/kubernetes/audiobookshelf"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
}

View file

@ -0,0 +1,135 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
resource "kubernetes_namespace" "audiobookshelf" {
metadata {
name = "audiobookshelf"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.audiobookshelf.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "audiobookshelf" {
metadata {
name = "audiobookshelf"
namespace = kubernetes_namespace.audiobookshelf.metadata[0].name
labels = {
app = "audiobookshelf"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
}
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "audiobookshelf"
}
}
template {
metadata {
labels = {
app = "audiobookshelf"
}
}
spec {
container {
image = "ghcr.io/advplyr/audiobookshelf:2.32.1"
name = "audiobookshelf"
port {
container_port = 80
}
volume_mount {
name = "audiobooks"
mount_path = "/audiobooks"
}
volume_mount {
name = "podcasts"
mount_path = "/podcasts"
}
volume_mount {
name = "config"
mount_path = "/config"
}
volume_mount {
name = "metadata"
mount_path = "/metadata"
}
}
volume {
name = "audiobooks"
nfs {
path = "/mnt/main/audiobookshelf/audiobooks"
server = "10.0.10.15"
}
}
volume {
name = "podcasts"
nfs {
path = "/mnt/main/audiobookshelf/podcasts"
server = "10.0.10.15"
}
}
volume {
name = "config"
nfs {
path = "/mnt/main/audiobookshelf/config"
server = "10.0.10.15"
}
}
volume {
name = "metadata"
nfs {
path = "/mnt/main/audiobookshelf/metadata"
server = "10.0.10.15"
}
}
}
}
}
}
resource "kubernetes_service" "audiobookshelf" {
metadata {
name = "audiobookshelf"
namespace = kubernetes_namespace.audiobookshelf.metadata[0].name
labels = {
"app" = "audiobookshelf"
}
}
spec {
selector = {
app = "audiobookshelf"
}
port {
name = "http"
target_port = 80
port = 80
protocol = "TCP"
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.audiobookshelf.metadata[0].name
name = "audiobookshelf"
tls_secret_name = var.tls_secret_name
rybbit_site_id = "b38fda4285df"
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

View file

@ -0,0 +1 @@
../../secrets

40
stacks/blog/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

6
stacks/blog/backend.tf Normal file
View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/blog/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "blog" {
source = "../../modules/kubernetes/blog"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
}

130
stacks/blog/module/main.tf Normal file
View file

@ -0,0 +1,130 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
# variable "dockerhub_password" {}
resource "kubernetes_namespace" "website" {
metadata {
name = "website"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.website.metadata[0].name
tls_secret_name = var.tls_secret_name
}
# module "dockerhub_creds" {
# source = "../../../modules/kubernetes/dockerhub_secret"
# namespace = kubernetes_namespace.website.metadata[0].name
# password = var.dockerhub_password
# }
resource "kubernetes_deployment" "blog" {
metadata {
name = "blog"
namespace = kubernetes_namespace.website.metadata[0].name
labels = {
run = "blog"
tier = var.tier
}
}
spec {
replicas = 3
selector {
match_labels = {
run = "blog"
}
}
template {
metadata {
labels = {
run = "blog"
}
}
spec {
container {
image = "viktorbarzin/blog:latest"
name = "blog"
resources {
limits = {
cpu = "0.5"
memory = "512Mi"
}
requests = {
cpu = "250m"
memory = "50Mi"
}
}
port {
container_port = 80
}
}
container {
image = "nginx/nginx-prometheus-exporter"
name = "nginx-exporter"
args = ["-nginx.scrape-uri", "http://127.0.0.1:8080/nginx_status"]
port {
container_port = 9113
}
}
}
}
}
}
resource "kubernetes_service" "blog" {
metadata {
name = "blog"
namespace = kubernetes_namespace.website.metadata[0].name
labels = {
"run" = "blog"
}
annotations = {
"prometheus.io/scrape" = "true"
"prometheus.io/path" = "/metrics"
"prometheus.io/port" = "9113"
}
}
spec {
selector = {
run = "blog"
}
port {
name = "http"
port = "80"
target_port = "80"
}
port {
name = "prometheus"
port = "9113"
target_port = "9113"
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.website.metadata[0].name
name = "blog"
service_name = "blog"
full_host = "viktorbarzin.me"
tls_secret_name = var.tls_secret_name
rybbit_site_id = "da853a2438d0"
}
module "ingress-www" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.website.metadata[0].name
name = "blog-www"
service_name = "blog"
full_host = "www.viktorbarzin.me"
tls_secret_name = var.tls_secret_name
rybbit_site_id = "da853a2438d0"
}

15
stacks/blog/providers.tf Normal file
View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/blog/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/calibre/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/calibre/terraform.tfstate"
}
}

View file

@ -12,9 +12,9 @@ locals {
}
module "calibre" {
source = "../../modules/kubernetes/calibre"
tls_secret_name = var.tls_secret_name
homepage_username = var.homepage_credentials["calibre-web"]["username"]
homepage_password = var.homepage_credentials["calibre-web"]["password"]
tier = local.tiers.edge
source = "./module"
tls_secret_name = var.tls_secret_name
homepage_username = var.homepage_credentials["calibre-web"]["username"]
homepage_password = var.homepage_credentials["calibre-web"]["password"]
tier = local.tiers.edge
}

View file

@ -0,0 +1,335 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "homepage_username" {
default = ""
}
variable "homepage_password" {
default = ""
}
resource "kubernetes_namespace" "calibre" {
metadata {
name = "calibre"
labels = {
tier = var.tier
}
# labels = {
# "istio-injection" : "enabled"
# }
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.calibre.metadata[0].name
tls_secret_name = var.tls_secret_name
}
# resource "kubernetes_deployment" "calibre" {
# metadata {
# name = "calibre"
# namespace = kubernetes_namespace.calibre.metadata[0].name
# labels = {
# app = "calibre"
# }
# annotations = {
# "reloader.stakater.com/search" = "true"
# }
# }
# spec {
# replicas = 1
# strategy {
# type = "Recreate"
# }
# selector {
# match_labels = {
# app = "calibre"
# }
# }
# template {
# metadata {
# annotations = {
# # "diun.enable" = "true"
# "diun.enable" = "false"
# "diun.include_tags" = "^\\d+(?:\\.\\d+)?(?:\\.\\d+)?$"
# }
# labels = {
# app = "calibre"
# }
# }
# spec {
# container {
# image = "lscr.io/linuxserver/calibre-web:latest"
# name = "calibre"
# env {
# name = "PUID"
# value = 1000
# }
# env {
# name = "PGID"
# value = 1000
# }
# env {
# name = "DOCKER_MODS"
# value = "linuxserver/mods:universal-calibre"
# }
# port {
# container_port = 8083
# }
# volume_mount {
# name = "data"
# mount_path = "/config"
# }
# volume_mount {
# name = "data"
# mount_path = "/books"
# }
# }
# volume {
# name = "data"
# nfs {
# path = "/mnt/main/calibre"
# server = "10.0.10.15"
# }
# }
# }
# }
# }
# }
resource "kubernetes_deployment" "calibre-web-automated" {
metadata {
name = "calibre-web-automated"
namespace = kubernetes_namespace.calibre.metadata[0].name
labels = {
app = "calibre-web-automated"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
}
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "calibre-web-automated"
}
}
template {
metadata {
annotations = {
# "diun.enable" = "true"
"diun.enable" = "false"
"diun.include_tags" = "^\\d+(?:\\.\\d+)?(?:\\.\\d+)?$"
}
labels = {
app = "calibre-web-automated"
}
}
spec {
container {
image = "crocodilestick/calibre-web-automated:latest"
name = "calibre-web-automated"
env {
name = "PUID"
value = 1000
}
env {
name = "PGID"
value = 1000
}
env {
name = "DOCKER_MODS"
value = "linuxserver/mods:universal-calibre"
}
env {
# If your library is on a network share (e.g., NFS/SMB), disable WAL to reduce locking issues
name = "NETWORK_SHARE_MODE"
value = "true"
}
env {
name = "CALIBRE_PORT"
value = "8083"
}
port {
container_port = 8083
}
volume_mount {
name = "config"
mount_path = "/config"
}
volume_mount {
name = "library"
mount_path = "/calibre-library"
}
volume_mount {
name = "ingest"
mount_path = "/cwa-book-ingest"
}
}
volume {
name = "library"
nfs {
path = "/mnt/main/calibre-web-automated/calibre-library"
server = "10.0.10.15"
}
}
volume {
name = "config"
nfs {
path = "/mnt/main/calibre-web-automated/config"
server = "10.0.10.15"
}
}
volume {
name = "ingest"
nfs {
path = "/mnt/main/calibre-web-automated/cwa-book-ingest"
server = "10.0.10.15"
}
}
}
}
}
}
resource "kubernetes_service" "calibre" {
metadata {
name = "calibre"
namespace = kubernetes_namespace.calibre.metadata[0].name
labels = {
"app" = "calibre"
}
}
spec {
selector = {
# app = "calibre"
app = "calibre-web-automated"
}
port {
name = "http"
target_port = 8083
port = 80
protocol = "TCP"
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.calibre.metadata[0].name
name = "calibre"
tls_secret_name = var.tls_secret_name
extra_annotations = {
"gethomepage.dev/enabled" = "true"
"gethomepage.dev/description" = "Book library"
# gethomepage.dev/group: Media
"gethomepage.dev/icon" : "calibre-web.png"
"gethomepage.dev/name" = "Calibre"
"gethomepage.dev/widget.type" = "calibreweb"
"gethomepage.dev/widget.url" = "https://calibre.viktorbarzin.me"
"gethomepage.dev/widget.username" = var.homepage_username
"gethomepage.dev/widget.password" = var.homepage_password
"gethomepage.dev/pod-selector" = ""
# gethomepage.dev/weight: 10 # optional
# gethomepage.dev/instance: "public" # optional
}
rybbit_site_id = "17a5c7fbb077"
custom_content_security_policy = "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://rybbit.viktorbarzin.me"
}
# Stacks - Anna's Archive Download Manager
resource "kubernetes_deployment" "annas-archive-stacks" {
metadata {
name = "annas-archive-stacks"
namespace = kubernetes_namespace.calibre.metadata[0].name
labels = {
app = "annas-archive-stacks"
tier = var.tier
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "annas-archive-stacks"
}
}
template {
metadata {
labels = {
app = "annas-archive-stacks"
}
}
spec {
container {
image = "zelest/stacks:latest"
name = "annas-archive-stacks"
port {
container_port = 7788
}
volume_mount {
name = "config"
mount_path = "/opt/stacks/config"
}
volume_mount {
name = "ingest"
mount_path = "/opt/stacks/download" # this must be the same as CWA ingest dir to auto ingest
}
}
volume {
name = "config"
nfs {
path = "/mnt/main/calibre-web-automated/stacks"
server = "10.0.10.15"
}
}
volume {
name = "ingest"
nfs {
path = "/mnt/main/calibre-web-automated/cwa-book-ingest"
server = "10.0.10.15"
}
}
}
}
}
}
resource "kubernetes_service" "annas-archive-stacks" {
metadata {
name = "annas-archive-stacks"
namespace = kubernetes_namespace.calibre.metadata[0].name
labels = {
"app" = "annas-archive-stacks"
}
}
spec {
selector = {
app = "annas-archive-stacks"
}
port {
name = "http"
port = "80"
target_port = 7788
}
}
}
module "stacks-ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.calibre.metadata[0].name
name = "stacks"
service_name = "annas-archive-stacks"
tls_secret_name = var.tls_secret_name
protected = true
rybbit_site_id = "ce5f8aed6bbb"
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/calibre/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/changedetection/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "changedetection" {
source = "../../modules/kubernetes/changedetection"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
}

View file

@ -0,0 +1,132 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
resource "kubernetes_namespace" "changedetection" {
metadata {
name = "changedetection"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.changedetection.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "changedetection" {
metadata {
name = "changedetection"
namespace = kubernetes_namespace.changedetection.metadata[0].name
labels = {
app = "changedetection"
tier = var.tier
}
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "changedetection"
}
}
template {
metadata {
labels = {
app = "changedetection"
}
}
spec {
container {
name = "sockpuppetbrowser"
image = "dgtlmoon/sockpuppetbrowser:latest"
image_pull_policy = "IfNotPresent"
port {
name = "ws"
container_port = 3000
protocol = "TCP"
}
security_context {
capabilities {
add = ["SYS_ADMIN"]
}
}
}
container {
name = "changedetection"
image = "ghcr.io/dgtlmoon/changedetection.io:latest" # latest is latest stable
env {
name = "PLAYWRIGHT_DRIVER_URL"
value = "ws://localhost:3000"
}
env {
name = "BASE_URL"
value = "https://changedetection.viktorbarzin.me"
}
env {
name = "LOGGER_LEVEL"
value = "WARNING"
}
env {
name = "TZ"
value = "Europe/Sofia"
}
volume_mount {
name = "data"
mount_path = "/datastore"
}
port {
name = "http"
container_port = 5000
protocol = "TCP"
}
}
# security_context {
# fs_group = "1500"
# }
volume {
name = "data"
nfs {
path = "/mnt/main/changedetection"
server = "10.0.10.15"
}
}
}
}
}
}
resource "kubernetes_service" "changedetection" {
metadata {
name = "changedetection"
namespace = kubernetes_namespace.changedetection.metadata[0].name
labels = {
"app" = "changedetection"
}
}
spec {
selector = {
app = "changedetection"
}
port {
port = 80
target_port = 5000
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.changedetection.metadata[0].name
name = "changedetection"
tls_secret_name = var.tls_secret_name
protected = true
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

View file

@ -0,0 +1 @@
../../secrets

40
stacks/city-guesser/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/city-guesser/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "city-guesser" {
source = "../../modules/kubernetes/city-guesser"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
}

View file

@ -0,0 +1,154 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
resource "kubernetes_namespace" "city-guesser" {
metadata {
name = "city-guesser"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = "city-guesser"
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "city-guesser" {
metadata {
name = "city-guesser"
namespace = "city-guesser"
labels = {
run = "city-guesser"
tier = var.tier
}
}
spec {
replicas = 1
selector {
match_labels = {
run = "city-guesser"
}
}
template {
metadata {
labels = {
run = "city-guesser"
}
}
spec {
container {
image = "viktorbarzin/city-guesser:latest"
name = "city-guesser"
resources {
limits = {
cpu = "0.5"
memory = "512Mi"
}
requests = {
cpu = "250m"
memory = "50Mi"
}
}
port {
container_port = 80
}
}
}
}
}
}
resource "kubernetes_service" "city-guesser" {
metadata {
name = "city-guesser"
namespace = "city-guesser"
labels = {
"run" = "city-guesser"
}
}
spec {
selector = {
run = "city-guesser"
}
port {
name = "http"
port = "80"
target_port = "80"
}
}
}
# resource "kubernetes_service" "city-guesser-oauth" {
# metadata {
# name = "city-guesser-oauth"
# namespace = "city-guesser"
# labels = {
# "run" = "city-guesser-oauth"
# }
# }
# spec {
# type = "ExternalName"
# external_name = "oauth-proxy.oauth.svc.cluster.local"
# # port {
# # name = "tcp"
# # port = "80"
# # target_port = "80"
# # }
# }
# }
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = "city-guesser"
name = "city-guesser"
tls_secret_name = var.tls_secret_name
protected = true
}
# resource "kubernetes_ingress_v1" "city-guesser-oauth" {
# metadata {
# name = "city-guesser-ingress-oauth"
# namespace = "city-guesser"
# annotations = {
# "kubernetes.io/ingress.class" = "nginx"
# }
# }
# spec {
# tls {
# hosts = ["city-guesser.viktorbarzin.me"]
# secret_name = var.tls_secret_name
# }
# rule {
# host = "city-guesser.viktorbarzin.me"
# http {
# path {
# path = "/oauth2"
# backend {
# service_name = "city-guesser-oauth"
# service_port = "80"
# }
# }
# }
# }
# }
# }
# module "oauth" {
# source = "../../../modules/kubernetes/oauth-proxy"
# # oauth_client_id = "3d8ce4bf7b893899d967"
# # oauth_client_secret = "08dca09b05e511cfa7f85cd7f85c332fd0768113"
# client_id = "3d8ce4bf7b893899d967"
# client_secret = "08dca09b05e511cfa7f85cd7f85c332fd0768113"
# namespace = "city-guesser"
# host = "city-guesser.viktorbarzin.me"
# tls_secret_name = var.tls_secret_name
# svc_name = "city-guesser-oauth"
# }

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/city-guesser/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/coturn/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

6
stacks/coturn/backend.tf Normal file
View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/coturn/terraform.tfstate"
}
}

View file

@ -13,9 +13,9 @@ locals {
}
module "coturn" {
source = "../../modules/kubernetes/coturn"
tls_secret_name = var.tls_secret_name
tier = local.tiers.edge
turn_secret = var.coturn_turn_secret
public_ip = var.public_ip
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.edge
turn_secret = var.coturn_turn_secret
public_ip = var.public_ip
}

View file

@ -0,0 +1,194 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "turn_secret" { type = string }
variable "public_ip" { type = string }
locals {
turn_realm = "viktorbarzin.me"
turn_port = 3478
# Small relay range 100 ports is plenty for a home lab (~50 concurrent streams)
min_port = 49152
max_port = 49252
}
resource "kubernetes_namespace" "coturn" {
metadata {
name = "coturn"
labels = {
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.coturn.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_config_map" "coturn_config" {
metadata {
name = "coturn-config"
namespace = kubernetes_namespace.coturn.metadata[0].name
}
data = {
"turnserver.conf" = <<-EOF
# TURN server configuration
listening-port=${local.turn_port}
fingerprint
lt-cred-mech
use-auth-secret
static-auth-secret=${var.turn_secret}
realm=${local.turn_realm}
server-name=turn.${local.turn_realm}
# Network use 0.0.0.0, coturn auto-detects pod IP
listening-ip=0.0.0.0
external-ip=${var.public_ip}
# Media relay port range (narrow 100 ports)
min-port=${local.min_port}
max-port=${local.max_port}
# Logging
verbose
no-stdout-log
syslog
# Security
no-multicast-peers
no-cli
no-tlsv1
no-tlsv1_1
# Performance
total-quota=100
stale-nonce=600
max-bps=0
EOF
}
}
resource "kubernetes_deployment" "coturn" {
metadata {
name = "coturn"
namespace = kubernetes_namespace.coturn.metadata[0].name
labels = {
app = "coturn"
tier = var.tier
}
}
spec {
replicas = 1
strategy {
type = "RollingUpdate"
rolling_update {
max_unavailable = 0
max_surge = 1
}
}
selector {
match_labels = {
app = "coturn"
}
}
template {
metadata {
labels = {
app = "coturn"
}
}
spec {
container {
name = "coturn"
image = "coturn/coturn:latest"
args = ["-c", "/etc/turnserver/turnserver.conf"]
# STUN/TURN signaling port
port {
name = "turn-udp"
container_port = local.turn_port
protocol = "UDP"
}
port {
name = "turn-tcp"
container_port = local.turn_port
protocol = "TCP"
}
volume_mount {
name = "config"
mount_path = "/etc/turnserver"
read_only = true
}
resources {
requests = {
cpu = "100m"
memory = "128Mi"
}
limits = {
cpu = "1"
memory = "512Mi"
}
}
}
volume {
name = "config"
config_map {
name = kubernetes_config_map.coturn_config.metadata[0].name
}
}
}
}
}
}
# LoadBalancer service with MetalLB exposes STUN/TURN signaling + relay ports
resource "kubernetes_service" "coturn" {
metadata {
name = "coturn"
namespace = kubernetes_namespace.coturn.metadata[0].name
annotations = {
"metallb.universe.tf/loadBalancerIPs" = "10.0.20.200"
"metallb.universe.tf/allow-shared-ip" = "shared"
}
}
spec {
type = "LoadBalancer"
selector = {
app = "coturn"
}
# STUN/TURN signaling
port {
name = "turn-udp"
port = local.turn_port
target_port = local.turn_port
protocol = "UDP"
}
port {
name = "turn-tcp"
port = local.turn_port
target_port = local.turn_port
protocol = "TCP"
}
# Relay port range (49152-49252)
dynamic "port" {
for_each = range(local.min_port, local.max_port + 1)
content {
name = "relay-${port.value}"
port = port.value
target_port = port.value
protocol = "UDP"
}
}
}
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/coturn/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/cyberchef/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/cyberchef/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "cyberchef" {
source = "../../modules/kubernetes/cyberchef"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
}

View file

@ -0,0 +1,88 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
resource "kubernetes_namespace" "cyberchef" {
metadata {
name = "cyberchef"
labels = {
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.cyberchef.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "cyberchef" {
metadata {
name = "cyberchef"
namespace = kubernetes_namespace.cyberchef.metadata[0].name
labels = {
app = "cyberchef"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
}
}
spec {
replicas = 1
strategy {
type = "RollingUpdate"
}
selector {
match_labels = {
app = "cyberchef"
}
}
template {
metadata {
labels = {
app = "cyberchef"
}
}
spec {
container {
image = "mpepping/cyberchef:latest"
name = "cyberchef"
port {
container_port = 8000
}
}
}
}
}
}
resource "kubernetes_service" "cyberchef" {
metadata {
name = "cc"
namespace = kubernetes_namespace.cyberchef.metadata[0].name
labels = {
"app" = "cyberchef"
}
}
spec {
selector = {
app = "cyberchef"
}
port {
name = "http"
target_port = 8000
port = 80
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.cyberchef.metadata[0].name
name = "cc"
tls_secret_name = var.tls_secret_name
rybbit_site_id = "7c460afc68c4"
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/cyberchef/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/dashy/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

6
stacks/dashy/backend.tf Normal file
View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/dashy/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "dashy" {
source = "../../modules/kubernetes/dashy"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.aux
}

View file

@ -0,0 +1,440 @@
pageInfo:
title: Dashy
description: Welcome to your new dashboard!
navLinks:
- title: GitHub
path: https://github.com/Lissy93/dashy
- title: Documentation
path: https://dashy.to/docs
appConfig:
theme: material
layout: auto
iconSize: large
sections:
- name: Infra
icon: si-databricks
displayData:
sortBy: alphabetical
rows: 2
cols: 2
collapsed: false
hideForGuests: false
items:
- &ref_0
title: ESXi R730 (Server)
description: R730 esxi UI
icon: si-vmware
url: https://esxi.viktorbarzin.me/ui/#/login
target: newtab
id: 0_496_esxirserver
- &ref_1
title: PFsense (Firewall)
description: Firewall
icon: si-pfsense
url: https://pfsense.viktorbarzin.me
target: newtab
id: 1_496_pfsensefirewall
- &ref_2
title: iDRAC
description: ""
icon: si-dell
url: https://idrac.viktorbarzin.me/
target: newtab
id: 2_496_idrac
- &ref_3
title: TP-Link Gateway Router
icon: hl-asus-router
url: https://gw.viktorbarzin.me/webpages/login.html
id: 3_496_tplinkgatewayrouter
- &ref_4
title: Home Assistant London
description: Home Assistant London Deployment
icon: si-homeassistant
url: http://ha-london.viktorbarzin.me/
target: newtab
id: 4_496_homeassistantlondon
- &ref_5
title: NAS
description: ""
icon: si-synology
url: https://nas.viktorbarzin.me/
id: 5_496_nas
- &ref_6
title: Server Switch
description: TP-Link Extension Switch
icon: 🔀
url: http://192.168.1.6/
target: newtab
id: 6_496_serverswitch
- &ref_7
title: Home Assistant Sofia
description: Home Assistant Sofia Deployment
icon: si-homeassistant
url: http://ha-sofia.viktorbarzin.me/
target: newtab
id: 7_496_homeassistantsofia
- &ref_8
title: IP Cameras
description: Frigate
icon: si-protodotio
url: https://frigate.viktorbarzin.me
target: newtab
id: 8_496_ipcameras
filteredItems:
- *ref_0
- *ref_1
- *ref_2
- *ref_3
- *ref_4
- *ref_5
- *ref_6
- *ref_7
- *ref_8
- name: Valchedrym Infra
displayData:
sortBy: default
rows: 2
cols: 2
collapsed: false
hideForGuests: false
items:
- &ref_9
title: Valchedrym OpenWRT
icon: si-openwrt
url: https://valchedrym.viktorbarzin.me/
target: newtab
id: 0_1567_valchedrymopenwrt
- &ref_10
title: Valchedram Video System
icon: 📷
url: http://valchedrym-video.viktorbarzin.me:5080/
target: newtab
id: 1_1567_valchedramvideosystem
- &ref_11
title: Mladost 3 Router
icon: si-ghostery
url: https://mladost3.viktorbarzin.me/
target: newtab
id: 2_1567_mladostrouter
- &ref_12
title: Valchedrym Services Uptime
description: Uptime Dashboard for Valchedrym Services
icon: si-openwrt
url: https://uptime.viktorbarzin.me/status/valchedrym
target: newtab
id: 3_1567_valchedrymservicesuptime
icon: 🐶
filteredItems:
- *ref_9
- *ref_10
- *ref_11
- *ref_12
- name: Monitoring
icon: hl-grafana
displayData:
sortBy: alphabetical
rows: 3
collapsed: false
hideForGuests: false
cols: 2
items:
- &ref_13
title: Uptime Kuma
description: Internal Uptime Monitoring
icon: si-uptimekuma
url: https://uptime.viktorbarzin.me/status/cluster-internal
target: newtab
id: 0_1062_uptimekuma
- &ref_14
title: iDRAC Grafana
icon: si-dell
url: https://grafana.viktorbarzin.me/d/O19gr0jZk/idrac-host-stats
target: newtab
statusCheckAcceptCodes: "400"
id: 1_1062_idracgrafana
- &ref_15
title: Kubernetes Cluster Nodes
description: Kubernetes Nodes Stats
icon: hl-kubernetes
url: https://grafana.viktorbarzin.me/d/xfpJB9FGz/node-exporter?orgId=1
target: newtab
statusCheckAcceptCodes: "400"
id: 2_1062_kubernetesclusternodes
- &ref_16
title: OpenWRT (London)
icon: si-openwrt
url: https://grafana.viktorbarzin.me/d/fLi0yXAWk/openwrt?orgId=1
target: newtab
statusCheckAcceptCodes: "400"
id: 3_1062_openwrtlondon
- &ref_17
title: Prometheus
icon: si-prometheus
url: https://prometheus.viktorbarzin.me/
statusCheck: false
statusCheckAcceptCodes: "400"
id: 4_1062_prometheus
- &ref_18
title: Alert Manager
icon: si-protractor
url: https://alertmanager.viktorbarzin.me/
target: newtab
id: 5_1062_alertmanager
- &ref_19
title: External Monitoring
description: Hetrix report
icon: si-amp
url: https://wl.hetrixtools.com/r/38981b548b5d38b052aca8d01285a3f3/
target: modal
id: 6_1062_externalmonitoring
- &ref_20
title: K8S Dashboard
description: Kubernetes dashboard with view of all nodes, pods etc
icon: si-kubernetes
url: https://k8s.viktorbarzin.me/#/node
id: 7_1062_ksdashboard
filteredItems:
- *ref_13
- *ref_14
- *ref_15
- *ref_16
- *ref_17
- *ref_18
- *ref_19
- *ref_20
- name: Infra Services
displayData:
sortBy: default
rows: 3
cols: 2
collapsed: false
hideForGuests: false
items:
- &ref_21
title: PhpMyAdmin
description: Admin UI for the DB Cluster
icon: si-phpmyadmin
url: https://pma.viktorbarzin.me/index.php
displayData: ttt
target: newtab
statusCheck: false
id: 0_1364_phpmyadmin
- &ref_22
title: Drone CI
description: CI/CD Service
icon: si-drone
url: https://drone.viktorbarzin.me/
target: newtab
id: 1_1364_droneci
- &ref_23
title: DNS Server
description: Technitium
icon: hl-azure-dns
url: https://technitium.viktorbarzin.me/
target: newtab
statusCheck: false
statusCheckAcceptCodes: "400"
id: 2_1364_dnsserver
- &ref_24
title: Headscale (VPN) UI
icon: si-wireguard
url: https://headscale.viktorbarzin.me/manager
target: newtab
statusCheck: false
statusCheckAcceptCodes: "400"
id: 3_1364_headscalevpnui
- &ref_25
title: URL Shorterner
description: Shlink
icon: si-curl
url: https://shlink.viktorbarzin.me
statusCheck: false
statusCheckAcceptCodes: "400"
id: 4_1364_urlshorterner
- &ref_26
title: Crowdsec Dashboard
icon: si-crowdsource
url: >-
https://crowdsec.viktorbarzin.me/public/dashboard/8f6226be-d4dc-45f1-bacf-a4584f71dcb0
target: newtab
id: 5_1364_crowdsecdashboard
- &ref_27
title: Redis
description: Redis
icon: si-redis
url: https://redis.viktorbarzin.me/
target: newtab
id: 6_1364_redis
- &ref_28
title: Truenas
description: Network Storage VM
icon: si-truenas
url: http://truenas.viktorbarzin.me/ui/dashboard
id: 7_1364_truenas
icon: si-adminer
filteredItems:
- *ref_21
- *ref_22
- *ref_23
- *ref_24
- *ref_25
- *ref_26
- *ref_27
- *ref_28
- name: Public Services
displayData:
sortBy: alphabetical
rows: 2
cols: 4
collapsed: false
hideForGuests: false
items:
- &ref_29
title: City Guesser
description: Geolocator Game
icon: hl-openmaptiles
url: https://city-guesser.viktorbarzin.me/
target: newtab
statusCheck: false
id: 0_1475_cityguesser
- &ref_30
title: Excalidraw
description: Collaborative Hand Drawing Tool
icon: hl-excalidraw-light
url: https://excalidraw.viktorbarzin.me
target: newtab
statusCheck: false
id: 1_1475_excalidraw
- &ref_31
title: Formula 1 Stream
icon: si-f1
url: http://f1.viktorbarzin.me/
statusCheck: false
id: 2_1475_formulastream
- &ref_32
title: HackMD
description: Collaborative Markdown Document Editing
icon: si-hackclub
url: https://hackmd.viktorbarzin.me/
statusCheck: false
id: 3_1475_hackmd
- &ref_33
title: Activate Windows (KMS)
description: How to activate Windows Machines
icon: si-windows95
url: https://kms.viktorbarzin.me/
statusCheck: false
id: 4_1475_activatewindowskms
- &ref_34
title: PrivateBin
description: E2E Encrypted Pastebin
icon: si-pastebin
url: https://pb.viktorbarzin.me/
statusCheck: false
id: 5_1475_privatebin
- &ref_35
title: Blog
description: Personal Blog
icon: si-rss
url: https://viktorbarzin.me/
statusCheck: false
id: 6_1475_blog
- &ref_36
title: Setup VPN (Tailscale)
description: "URL to set in app config: https://headscale.viktorbarzin.me"
icon: si-wireguard
url: https://github.com/juanfont/headscale/blob/main/docs/iOS-client.md
target: newtab
id: 7_1475_setupvpntailscale
- &ref_37
title: Vaultwarden
description: Self-hosted Bitwarden server (Password Manager)
icon: si-bitwarden
url: https://vaultwarden.viktorbarzin.me
target: newtab
id: 8_1475_vaultwarden
- &ref_38
title: Send
description: Share files
icon: si-libreoffice
url: https://send.viktorbarzin.me/
target: newtab
id: 9_1475_send
- &ref_39
title: Youtube Downloader
icon: si-youtube
url: https://yt.viktorbarzin.me
target: newtab
id: 10_1475_youtubedownloader
- &ref_40
title: Photos
description: Immich
icon: si-immich
url: https://photos.viktorbarzin.me
target: newtab
id: 11_1475_photos
- &ref_41
title: Audiobookshelf
description: >-
Audiobook shelf. For iOS, install app from
https://url.viktorbarzin.me/audiobookshelf
icon: si-audible
url: https://audiobookshelf.viktorbarzin.me/
target: newtab
id: 12_1475_audiobookshelf
- &ref_42
title: Ollama
description: Self-hosted ChatGPT (using llama3)
icon: si-openai
url: https://ollama.viktorbarzin.me/
target: newtab
id: 13_1475_ollama
- &ref_43
title: Paperless-ngx
description: Document index
icon: hl-paperless-ngx
url: https://pdf.viktorbarzin.me/
target: newtab
id: 14_1475_paperlessngx
icon: si-sublimetext
filteredItems:
- *ref_29
- *ref_30
- *ref_31
- *ref_32
- *ref_33
- *ref_34
- *ref_35
- *ref_36
- *ref_37
- *ref_38
- *ref_39
- *ref_40
- *ref_41
- *ref_42
- *ref_43
- name: Under Construction
displayData:
sortBy: alphabetical
rows: 1
cols: 1
collapsed: false
hideForGuests: false
items:
- &ref_44
title: Travel Blog
icon: si-hugo
url: https://travel.viktorbarzin.me/
target: newtab
statusCheck: false
id: 0_1833_travelblog
- &ref_45
title: Personal Finance App
icon: si-abstract
url: https://finance.viktorbarzin.me/transaction
statusCheck: false
id: 1_1833_personalfinanceapp
icon: si-progress
filteredItems:
- *ref_44
- *ref_45

126
stacks/dashy/module/main.tf Normal file
View file

@ -0,0 +1,126 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.dashy.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_namespace" "dashy" {
metadata {
name = "dashy"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
resource "kubernetes_config_map" "config" {
metadata {
name = "config"
namespace = kubernetes_namespace.dashy.metadata[0].name
annotations = {
"reloader.stakater.com/match" = "true"
}
}
data = {
"conf.yml" = file("${path.module}/conf.yml")
}
}
resource "kubernetes_deployment" "dashy" {
metadata {
name = "dashy"
namespace = kubernetes_namespace.dashy.metadata[0].name
labels = {
app = "dashy"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "dashy"
}
}
template {
metadata {
annotations = {
# "diun.enable" = "true"
}
labels = {
app = "dashy"
}
}
spec {
container {
image = "lissy93/dashy:latest"
name = "dashy"
resources {
requests = {
cpu = "50m"
memory = "256Mi"
}
limits = {
cpu = "1"
memory = "2Gi"
}
}
port {
container_port = 8080
}
volume_mount {
name = "config"
mount_path = "/app/user-data/"
}
}
volume {
name = "config"
config_map {
name = "config"
}
}
}
}
}
}
resource "kubernetes_service" "dashy" {
metadata {
name = "dashy"
namespace = kubernetes_namespace.dashy.metadata[0].name
labels = {
app = "dashy"
}
}
spec {
selector = {
app = "dashy"
}
port {
name = "http"
port = 80
target_port = 8080
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.dashy.metadata[0].name
name = "dashy"
tls_secret_name = var.tls_secret_name
protected = true # hidden as we use homepage now
}

15
stacks/dashy/providers.tf Normal file
View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/dashy/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/dawarich/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/dawarich/terraform.tfstate"
}
}

View file

@ -13,9 +13,9 @@ locals {
}
module "dawarich" {
source = "../../modules/kubernetes/dawarich"
tls_secret_name = var.tls_secret_name
database_password = var.dawarich_database_password
geoapify_api_key = var.geoapify_api_key
tier = local.tiers.edge
source = "./module"
tls_secret_name = var.tls_secret_name
database_password = var.dawarich_database_password
geoapify_api_key = var.geoapify_api_key
tier = local.tiers.edge
}

View file

@ -0,0 +1,325 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "database_password" {}
variable "geoapify_api_key" {}
variable "image_version" {
type = string
default = "0.37.1"
}
resource "kubernetes_namespace" "dawarich" {
metadata {
name = "dawarich"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.dawarich.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "dawarich" {
metadata {
name = "dawarich"
namespace = kubernetes_namespace.dawarich.metadata[0].name
labels = {
app = "dawarich"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
}
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "dawarich"
}
}
template {
metadata {
labels = {
app = "dawarich"
}
annotations = {
# "diun.enable" = "true"
# "diun.include_tags" = "latest"
}
}
spec {
container {
image = "freikin/dawarich:${var.image_version}"
name = "dawarich"
port {
name = "http"
container_port = 3000
}
port {
name = "prometheus"
container_port = 9394
}
command = ["web-entrypoint.sh"]
args = ["bin/dev"]
env {
name = "REDIS_URL"
value = "redis://redis.redis.svc.cluster.local:6379"
}
env {
name = "DATABASE_HOST"
value = "postgresql.dbaas"
}
env {
name = "DATABASE_USERNAME"
value = "dawarich"
}
env {
name = "DATABASE_PASSWORD"
value = var.database_password
}
env {
name = "DATABASE_NAME"
value = "dawarich"
}
env {
name = "MIN_MINUTES_SPENT_IN_CITY"
value = "60"
}
env {
name = "TIME_ZONE"
value = "Europe/London"
}
env {
name = "DISTANCE_UNIT"
value = "km"
}
env {
name = "ENABLE_TELEMETRY"
value = "true"
}
env {
name = "APPLICATION_HOSTS"
value = "dawarich.viktorbarzin.me"
}
# env {
# name = "PROMETHEUS_EXPORTER_ENABLED"
# value = "true"
# }
# env {
# name = "PROMETHEUS_EXPORTER_PORT"
# value = "9394"
# }
# env {
# name = "PROMETHEUS_EXPORTER_HOST"
# value = "0.0.0.0"
# }
env {
name = "SELF_HOSTED"
value = "true"
}
# env {
# name = "PHOTON_API_HOST"
# value = "photon.dawarich"
# }
# volume_mount {
# name = "watched"
# mount_path = "/var/app/tmp/imports/watched"
# }
}
# container {
# image = "freikin/dawarich:${var.image_version}"
# name = "dawarich-sidekiq"
# command = ["sidekiq-entrypoint.sh"]
# args = ["bundle exec sidekiq"]
# env {
# name = "REDIS_URL"
# value = "redis://redis.redis.svc.cluster.local:6379"
# }
# env {
# name = "DATABASE_HOST"
# value = "postgresql.dbaas"
# }
# env {
# name = "DATABASE_USERNAME"
# value = "dawarich"
# }
# env {
# name = "DATABASE_PASSWORD"
# value = var.database_password
# }
# env {
# name = "DATABASE_NAME"
# value = "dawarich"
# }
# env {
# name = "MIN_MINUTES_SPENT_IN_CITY"
# value = "60"
# }
# env {
# name = "BACKGROUND_PROCESSING_CONCURRENCY"
# value = "10"
# }
# env {
# name = "ENABLE_TELEMETRY"
# value = "true"
# }
# env {
# name = "APPLICATION_HOST"
# value = "dawarich.viktorbarzin.me"
# }
# # env {
# # name = "PROMETHEUS_EXPORTER_ENABLED"
# # value = "false"
# # }
# # env {
# # name = "PROMETHEUS_EXPORTER_HOST"
# # value = "dawarich.dawarich"
# # }
# # env {
# # name = "PHOTON_API_HOST"
# # value = "photon.dawarich:2322"
# # # value = "photon.komoot.io"
# # }
# # env {
# # name = "PHOTON_API_USE_HTTPS"
# # value = "false"
# # }
# env {
# name = "GEOAPIFY_API_KEY"
# value = var.geoapify_api_key
# }
# env {
# name = "SELF_HOSTED"
# value = "true"
# }
# # volume_mount {
# # name = "watched"
# # mount_path = "/var/app/tmp/imports/watched"
# # }
# }
}
}
}
}
# resource "kubernetes_deployment" "photon" {
# metadata {
# name = "photon"
# namespace = kubernetes_namespace.dawarich.metadata[0].name
# labels = {
# app = "photon"
# }
# }
# spec {
# replicas = 1
# strategy {
# type = "Recreate"
# }
# selector {
# match_labels = {
# app = "photon"
# }
# }
# template {
# metadata {
# labels = {
# app = "photon"
# }
# }
# spec {
# container {
# image = "rtuszik/photon-docker:latest"
# name = "photon"
# port {
# name = "tcp"
# container_port = 2322
# }
# env {
# name = "COUNTRY_CODE"
# value = "bg"
# }
# volume_mount {
# name = "data"
# mount_path = "/photon/photon_data"
# }
# }
# volume {
# name = "data"
# nfs {
# path = "/mnt/main/photon"
# server = "10.0.10.15"
# }
# }
# }
# }
# }
# }
resource "kubernetes_service" "dawarich" {
metadata {
name = "dawarich"
namespace = kubernetes_namespace.dawarich.metadata[0].name
labels = {
"app" = "dawarich"
}
}
spec {
selector = {
app = "dawarich"
}
port {
name = "http"
port = 80
target_port = 3000
protocol = "TCP"
}
}
}
# resource "kubernetes_service" "photon" {
# metadata {
# name = "photon"
# namespace = kubernetes_namespace.dawarich.metadata[0].name
# labels = {
# "app" = "photon"
# }
# }
# spec {
# selector = {
# app = "photon"
# }
# port {
# name = "http"
# port = 2322
# target_port = 2322
# protocol = "TCP"
# }
# }
# }
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.dawarich.metadata[0].name
name = "dawarich"
tls_secret_name = var.tls_secret_name
rybbit_site_id = "0abfd409f2fb"
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/dawarich/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/descheduler/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/descheduler/terraform.tfstate"
}
}

View file

@ -1,3 +1,3 @@
module "descheduler" {
source = "../../modules/kubernetes/descheduler"
source = "./module"
}

View file

@ -0,0 +1,87 @@
resource "kubernetes_namespace" "descheduler" {
metadata {
name = "descheduler"
}
}
resource "kubernetes_cluster_role" "descheduler" {
metadata {
name = "descheduler-cluster-role"
}
rule {
api_groups = [""]
resources = ["events"]
verbs = ["create", "update"]
}
rule {
api_groups = ["metrics.k8s.io"]
resources = ["nodes"]
verbs = ["get", "watch", "list"]
}
rule {
api_groups = [""]
resources = ["namespaces"]
verbs = ["get", "list", "watch"]
}
rule {
api_groups = ["metrics.k8s.io"]
resources = ["pods"]
verbs = ["get", "watch", "list", "delete"]
}
rule {
api_groups = [""]
resources = ["pods/eviction"]
verbs = ["create"]
}
rule {
api_groups = [""]
resources = ["scheduling.k8s.io"]
verbs = ["get", "watch", "list"]
}
rule {
api_groups = ["scheduling.k8s.io"]
resources = ["priorityclasses"]
verbs = ["get", "list", "watch"]
}
rule {
api_groups = ["policy"]
resources = ["poddisruptionbudgets"]
verbs = ["get", "list", "watch"]
}
}
resource "kubernetes_service_account" "descheduler" {
metadata {
name = "descheduler-sa"
namespace = kubernetes_namespace.descheduler.metadata[0].name
}
}
resource "kubernetes_cluster_role_binding" "descheduler" {
metadata {
name = "descheduler-cluster-role-binding"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "descheduler-cluster-role"
}
subject {
name = "descheduler-sa"
kind = "ServiceAccount"
namespace = kubernetes_namespace.descheduler.metadata[0].name
}
}
resource "helm_release" "descheduler" { # rename me
namespace = kubernetes_namespace.descheduler.metadata[0].name
name = "descheduler"
repository = "https://kubernetes-sigs.github.io/descheduler/"
chart = "descheduler"
values = [templatefile("${path.module}/values.yaml", {})]
}

View file

@ -0,0 +1,311 @@
# Source from https://github.com/kubernetes-sigs/descheduler/blob/master/charts/descheduler/values.yaml
# Default values for descheduler.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# CronJob or Deployment
kind: CronJob
image:
repository: registry.k8s.io/descheduler/descheduler
# Overrides the image tag whose default is the chart version
tag: ""
pullPolicy: IfNotPresent
imagePullSecrets:
# - name: container-registry-secret
resources:
requests:
cpu: 500m
memory: 256Mi
limits:
cpu: 500m
memory: 256Mi
ports:
- containerPort: 10258
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
# podSecurityContext -- [Security context for pod](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
podSecurityContext:
{}
# fsGroup: 1000
nameOverride: ""
fullnameOverride: ""
# -- Override the deployment namespace; defaults to .Release.Namespace
namespaceOverride: ""
# labels that'll be applied to all resources
commonLabels: {}
cronJobApiVersion: "batch/v1"
schedule: "0 * * * *"
suspend: false
# startingDeadlineSeconds: 200
successfulJobsHistoryLimit: 10
# failedJobsHistoryLimit: 1
# ttlSecondsAfterFinished 600
# timeZone: Etc/UTC
# Required when running as a Deployment
deschedulingInterval: 5m
# Specifies the replica count for Deployment
# Set leaderElection if you want to use more than 1 replica
# Set affinity.podAntiAffinity rule if you want to schedule onto a node
# only if that node is in the same zone as at least one already-running descheduler
replicas: 1
# Specifies whether Leader Election resources should be created
# Required when running as a Deployment
# NOTE: Leader election can't be activated if DryRun enabled
leaderElection: {}
# enabled: true
# leaseDuration: 15s
# renewDeadline: 10s
# retryPeriod: 2s
# resourceLock: "leases"
# resourceName: "descheduler"
# resourceNamespace: "kube-system"
command:
- "/bin/descheduler"
cmdOptions:
v: 3
# Recommended to use the latest Policy API version supported by the Descheduler app version
deschedulerPolicyAPIVersion: "descheduler/v1alpha2"
# deschedulerPolicy contains the policies the descheduler will execute.
# To use policies stored in an existing configMap use:
# NOTE: The name of the cm should comply to {{ template "descheduler.fullname" . }}
# deschedulerPolicy: {}
deschedulerPolicy:
# nodeSelector: "key1=value1,key2=value2"
# maxNoOfPodsToEvictPerNode: 10
maxNoOfPodsToEvictTotal: 10
# maxNoOfPodsToEvictPerNamespace: 10
# ignorePvcPods: true
# evictLocalStoragePods: true
# evictDaemonSetPods: true
# tracing:
# collectorEndpoint: otel-collector.observability.svc.cluster.local:4317
# transportCert: ""
# serviceName: ""
# serviceNamespace: ""
# sampleRate: 1.0
# fallbackToNoOpProviderOnError: true
metricsCollector:
enabled: true
profiles:
- name: default
pluginConfig:
- name: DefaultEvictor
args:
ignorePvcPods: true
evictLocalStoragePods: true
- name: RemoveDuplicates
- name: RemovePodsHavingTooManyRestarts
args:
podRestartThreshold: 2
includingInitContainers: true
states:
- CrashLoopBackOff
- name: RemovePodsViolatingNodeAffinity
args:
nodeAffinityType:
- requiredDuringSchedulingIgnoredDuringExecution
- name: RemovePodsViolatingNodeTaints
- name: RemovePodsViolatingInterPodAntiAffinity
- name: RemovePodsViolatingTopologySpreadConstraint
- name: LowNodeUtilization
args:
evictableNamespaces:
exclude:
- "dbaas" # let's not meddle with the dbs
thresholds:
cpu: 50
memory: 50
# pods: 20
targetThresholds:
cpu: 80
memory: 80
# pods: 30
metricsUtilization:
metricsServer: true
- name: PodLifeTime
args:
maxPodLifeTimeSeconds: 604800
namespaces:
exclude:
- "dbaas" # let's not meddle with the dbs
- "kube-system"
- "calico-system"
- "calico-apiserver"
- "metallb-system"
- "monitoring"
- "authentik"
- name: "RemoveFailedPods"
args:
reasons:
- "CrashLoopBackOff"
- "Error"
- "ContainerStatusUnknown"
- "ImagePullBackOff"
# exitCodes:
# - 1
includingInitContainers: true
# minPodLifetimeSeconds: 0
plugins:
balance:
enabled:
- RemoveDuplicates
- RemovePodsViolatingTopologySpreadConstraint
- LowNodeUtilization
deschedule:
enabled:
- RemovePodsHavingTooManyRestarts
- RemovePodsViolatingNodeTaints
- RemovePodsViolatingNodeAffinity
- RemovePodsViolatingInterPodAntiAffinity
- PodLifeTime
- RemoveFailedPods
- name: idrac-restart
pluginConfig:
- name: DefaultEvictor
args:
ignorePvcPods: true
evictLocalStoragePods: true
- name: PodLifeTime
args:
maxPodLifeTimeSeconds: 21600
namespaces:
include:
- "monitoring"
labelSelector:
matchLabels:
app: idrac-redfish-exporter
plugins:
deschedule:
enabled:
- PodLifeTime
priorityClassName: system-cluster-critical
nodeSelector: {}
# foo: bar
affinity: {}
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: kubernetes.io/e2e-az-name
# operator: In
# values:
# - e2e-az1
# - e2e-az2
# podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# - labelSelector:
# matchExpressions:
# - key: app.kubernetes.io/name
# operator: In
# values:
# - descheduler
# topologyKey: "kubernetes.io/hostname"
topologySpreadConstraints: []
# - maxSkew: 1
# topologyKey: kubernetes.io/hostname
# whenUnsatisfiable: DoNotSchedule
# labelSelector:
# matchLabels:
# app.kubernetes.io/name: descheduler
tolerations: []
# - key: 'management'
# operator: 'Equal'
# value: 'tool'
# effect: 'NoSchedule'
rbac:
# Specifies whether RBAC resources should be created
create: true
serviceAccount:
# Specifies whether a ServiceAccount should be created
create: false
# The name of the ServiceAccount to use.
# If not set and create is true, a name is generated using the fullname template
name: "descheduler-sa"
# Specifies custom annotations for the serviceAccount
annotations: {}
podAnnotations: {}
podLabels: {}
dnsConfig: {}
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10258
scheme: HTTPS
initialDelaySeconds: 3
periodSeconds: 10
service:
enabled: false
# @param service.ipFamilyPolicy [string], support SingleStack, PreferDualStack and RequireDualStack
#
ipFamilyPolicy: ""
# @param service.ipFamilies [array] List of IP families (e.g. IPv4, IPv6) assigned to the service.
# Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/
# E.g.
# ipFamilies:
# - IPv6
# - IPv4
ipFamilies: []
serviceMonitor:
enabled: false
# The namespace where Prometheus expects to find service monitors.
# namespace: ""
# Add custom labels to the ServiceMonitor resource
additionalLabels:
{}
# prometheus: kube-prometheus-stack
interval: ""
# honorLabels: true
insecureSkipVerify: true
serverName: null
metricRelabelings:
[]
# - action: keep
# regex: 'descheduler_(build_info|pods_evicted)'
# sourceLabels: [__name__]
relabelings:
[]
# - sourceLabels: [__meta_kubernetes_pod_node_name]
# separator: ;
# regex: ^(.*)$
# targetLabel: nodename
# replacement: $1
# action: replace

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/descheduler/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/diun/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

6
stacks/diun/backend.tf Normal file
View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/diun/terraform.tfstate"
}
}

View file

@ -13,9 +13,9 @@ locals {
}
module "diun" {
source = "../../modules/kubernetes/diun"
tls_secret_name = var.tls_secret_name
diun_nfty_token = var.diun_nfty_token
diun_slack_url = var.diun_slack_url
tier = local.tiers.aux
source = "./module"
tls_secret_name = var.tls_secret_name
diun_nfty_token = var.diun_nfty_token
diun_slack_url = var.diun_slack_url
tier = local.tiers.aux
}

177
stacks/diun/module/main.tf Normal file
View file

@ -0,0 +1,177 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "diun_nfty_token" {}
variable "diun_slack_url" {}
resource "kubernetes_namespace" "diun" {
metadata {
name = "diun"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.diun.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_service_account" "diun" {
metadata {
name = "diun"
namespace = kubernetes_namespace.diun.metadata[0].name
}
}
resource "kubernetes_cluster_role" "diun" {
metadata {
name = "diun"
}
rule {
api_groups = [""]
resources = ["pods"]
verbs = ["get", "watch", "list"]
}
}
resource "kubernetes_cluster_role_binding" "diun" {
metadata {
name = "diun"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "diun"
}
subject {
kind = "ServiceAccount"
name = "diun"
namespace = kubernetes_namespace.diun.metadata[0].name
}
}
resource "kubernetes_deployment" "diun" {
metadata {
name = "diun"
namespace = kubernetes_namespace.diun.metadata[0].name
labels = {
app = "diun"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
"diun.enable" = "true"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "diun"
}
}
template {
metadata {
labels = {
app = "diun"
}
}
spec {
service_account_name = "diun"
container {
image = "crazymax/diun:latest"
name = "diun"
args = ["serve"]
env {
name = "TZ"
value = "Europe/Sofia"
}
env {
name = "DIUN_WATCH_WORKERS"
value = "20"
}
env {
name = "DIUN_WATCH_SCHEDULE"
value = "0 */6 * * *"
}
env {
name = "DIUN_WATCH_JITTER"
value = "30s"
}
env {
name = "DIUN_PROVIDERS_KUBERNETES"
value = "true"
}
# env {
# name = "DIUN_DEFAULTS_EXCLUDETAGS"
# value = "^.*nightly.*$"
# }
# env {
# name = "DIUN_DEFAULTS_INCLUDETAGS"
# value = "^\\d+\\.\\d+\\.\\d+$"
# }
env {
name = "DIUN_DEFAULTS_WATCHREPO"
value = "true"
# value = "false"
}
env {
name = "DIUN_DEFAULTS_MAXTAGS"
value = "3"
}
env {
name = "DIUN_DEFAULTS_SORTTAGS"
value = "reverse"
}
# DIUN_PROVIDERS_KUBERNETES_WATCHBYDEFAULT = "true" ??
// ntfy settings
# env { // disabled as if this fails, no other notifications are sent
# name = "DIUN_NOTIF_NTFY_ENDPOINT"
# value = "https://ntfy.viktorbarzin.me"
# }
# env {
# name = "DIUN_NOTIF_NTFY_TOPIC"
# value = "diun-updates"
# }
# env {
# name = "DIUN_NOTIF_NTFY_TOKEN"
# value = var.diun_nfty_token
# }
env {
name = "DIUN_NOTIF_SLACK_WEBHOOKURL"
value = var.diun_slack_url
}
env {
name = "LOG_LEVEL"
# value = "info"
value = "debug"
}
# env {
# name = "DIUN_WATCH_FIRSTCHECKNOTIF"
# value = "true" # send notfication on start; subsequent checks check for newer versions and is what you need
# }
# env {
# name = "DIUN_NOTIF_NTFY_TIMEOUT"
# value = "10s"
# }
volume_mount {
name = "data"
mount_path = "/data"
}
}
volume {
name = "data"
nfs {
path = "/mnt/main/diun"
server = "10.0.10.15"
}
}
}
}
}
}

15
stacks/diun/providers.tf Normal file
View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/diun/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

40
stacks/drone/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

6
stacks/drone/backend.tf Normal file
View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/drone/terraform.tfstate"
}
}

View file

@ -15,14 +15,14 @@ locals {
}
module "drone" {
source = "../../modules/kubernetes/drone"
tls_secret_name = var.tls_secret_name
git_crypt_key_base64 = filebase64("${path.root}/../../.git/git-crypt/keys/default")
github_client_id = var.drone_github_client_id
github_client_secret = var.drone_github_client_secret
rpc_secret = var.drone_rpc_secret
webhook_secret = var.drone_webhook_secret
server_host = "drone.viktorbarzin.me"
server_proto = "https"
tier = local.tiers.edge
source = "./module"
tls_secret_name = var.tls_secret_name
git_crypt_key_base64 = filebase64("${path.root}/../../.git/git-crypt/keys/default")
github_client_id = var.drone_github_client_id
github_client_secret = var.drone_github_client_secret
rpc_secret = var.drone_rpc_secret
webhook_secret = var.drone_webhook_secret
server_host = "drone.viktorbarzin.me"
server_proto = "https"
tier = local.tiers.edge
}

419
stacks/drone/module/main.tf Normal file
View file

@ -0,0 +1,419 @@
variable "tls_secret_name" {}
variable "git_crypt_key_base64" { type = string }
variable "tier" { type = string }
variable "github_client_id" {}
variable "github_client_secret" {}
variable "rpc_secret" {}
variable "webhook_secret" {}
variable "server_host" {}
variable "server_proto" {}
variable "rpc_host" {
default = "drone.drone.svc.cluster.local"
}
variable "allowed_users" {
# comma separated list
default = "viktorbarzin,ancamilea"
}
resource "kubernetes_namespace" "drone" {
metadata {
name = "drone"
labels = {
"resource-governance/custom-quota" = "true"
tier = var.tier
}
}
}
resource "kubernetes_resource_quota" "drone" {
metadata {
name = "tier-quota"
namespace = kubernetes_namespace.drone.metadata[0].name
}
spec {
hard = {
"requests.cpu" = "16"
"requests.memory" = "16Gi"
"limits.cpu" = "64"
"limits.memory" = "128Gi"
pods = "60"
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.drone.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_config_map" "git_crypt_key" {
metadata {
name = "git-crypt-key"
namespace = kubernetes_namespace.drone.metadata[0].name
}
data = {
"key" = var.git_crypt_key_base64
}
}
resource "kubernetes_deployment" "drone_server" {
metadata {
name = "drone-server"
namespace = kubernetes_namespace.drone.metadata[0].name
labels = {
app = "drone"
tier = var.tier
}
}
spec {
strategy {
type = "Recreate"
}
replicas = 1
selector {
match_labels = {
app = "drone"
}
}
template {
metadata {
labels = {
app = "drone"
}
}
spec {
container {
image = "drone/drone:2.27.0"
name = "drone-server"
# resources {
# limits = {
# cpu = "1"
# memory = "1Gi"
# }
# requests = {
# cpu = "500m"
# memory = "1Gi"
# }
# }
port {
container_port = 80
}
volume_mount {
name = "data"
mount_path = "/data"
}
env {
name = "DRONE_GITHUB_CLIENT_ID"
value = var.github_client_id
}
env {
name = "DRONE_GITHUB_CLIENT_SECRET"
value = var.github_client_secret
}
env {
name = "DRONE_RPC_SECRET"
value = var.rpc_secret
}
env {
name = "DRONE_WEBHOOK_SECRET"
value = var.webhook_secret
}
env {
name = "DRONE_SERVER_HOST"
value = var.server_host
}
env {
name = "DRONE_SERVER_PROTO"
value = var.server_proto
}
env {
name = "DRONE_USER_FILTER"
value = var.allowed_users
}
env {
name = "DRONE_CRON_INTERVAL"
value = "1m"
}
env {
name = "DRONE_LOGS_TRACE"
value = "true"
}
env {
name = "DRONE_LOGS_PRETTY"
value = "true"
}
env {
name = "DRONE_LOGS_TEXT"
value = "true"
}
}
volume {
name = "data"
nfs {
path = "/mnt/main/drone"
server = "10.0.10.15"
}
# iscsi {
# target_portal = "iscsi.viktorbarzin.lan:3260"
# fs_type = "ext4"
# iqn = "iqn.2020-12.lan.viktorbarzin:storage:drone"
# lun = 0
# read_only = false
# }
}
}
}
}
}
resource "kubernetes_service" "drone" {
metadata {
name = "drone"
namespace = kubernetes_namespace.drone.metadata[0].name
labels = {
app = "drone"
}
}
spec {
selector = {
app = "drone"
}
port {
name = "http"
port = "80"
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.drone.metadata[0].name
name = "drone"
tls_secret_name = var.tls_secret_name
# protected = true
}
# Setup drone runner
resource "kubernetes_cluster_role" "drone" {
metadata {
name = "drone"
}
rule {
api_groups = [""]
resources = ["configmaps"]
verbs = ["get", "list", "update", "patch"]
}
rule {
api_groups = [""]
resources = ["secrets"]
verbs = ["get", "list", "create", "delete"]
}
rule {
api_groups = [""]
resources = ["pods", "pods/log"]
verbs = ["get", "create", "delete", "list", "watch", "update"]
}
rule {
api_groups = ["apps"]
resources = ["deployments"]
verbs = ["get", "create", "delete", "list", "watch", "update", "patch"]
}
}
resource "kubernetes_cluster_role_binding" "drone" {
metadata {
name = "drone"
}
subject {
kind = "ServiceAccount"
name = "default"
namespace = kubernetes_namespace.drone.metadata[0].name
}
role_ref {
kind = "ClusterRole"
# name = "drone"
name = "cluster-admin"
api_group = "rbac.authorization.k8s.io"
}
}
resource "kubernetes_deployment" "drone_runner" {
metadata {
name = "drone-runner"
namespace = kubernetes_namespace.drone.metadata[0].name
labels = {
app = "drone-runner"
tier = var.tier
}
}
spec {
strategy {
type = "Recreate"
}
replicas = 4
selector {
match_labels = {
app = "drone-runner"
}
}
template {
metadata {
labels = {
app = "drone-runner"
}
}
spec {
container {
image = "drone/drone-runner-kube:latest"
name = "drone-runner"
# resources {
# limits = {
# cpu = "1"
# memory = "1Gi"
# }
# requests = {
# cpu = "500m"
# memory = "1Gi"
# }
# }
env {
name = "DRONE_RPC_HOST"
value = var.rpc_host
}
env {
name = "DRONE_RPC_PROTO"
value = "http"
}
env {
name = "DRONE_RPC_SECRET"
value = var.rpc_secret
}
env {
name = "DRONE_NAMESPACE_DEFAULT"
value = "drone"
}
env {
name = "SECRET_KEY"
value = var.rpc_secret
}
env {
name = "DRONE_SECRET_PLUGIN_ENDPOINT"
value = "http://drone-runner-secret.drone.svc.cluster.local:3000"
}
env {
name = "DRONE_SECRET_PLUGIN_TOKEN"
value = var.rpc_secret
}
env {
name = "DRONE_DEBUG"
value = "true"
}
env {
name = "DRONE_IMAGES_CLONE"
value = "alpine/git:latest"
}
}
}
}
}
}
resource "kubernetes_deployment" "drone_runner_secret" {
metadata {
name = "drone-runner-secret"
namespace = kubernetes_namespace.drone.metadata[0].name
labels = {
app = "drone-runner-secret"
tier = var.tier
}
}
spec {
strategy {
type = "Recreate"
}
replicas = 1
selector {
match_labels = {
app = "drone-runner-secret"
}
}
template {
metadata {
labels = {
app = "drone-runner-secret"
}
}
spec {
container {
name = "secret"
image = "drone/kubernetes-secrets:latest"
port {
container_port = 3000
}
env {
name = "SECRET_KEY"
value = var.rpc_secret
}
env {
name = "DEBUG"
value = "true"
}
env {
name = "KUBERNETES_NAMESPACE"
value = "drone"
}
// Custom variable to start terraform as prod
env {
name = "TF_VAR_prod"
value = true
}
}
}
}
}
}
resource "kubernetes_service" "drone_runner_secret" {
metadata {
name = "drone-runner-secret"
namespace = kubernetes_namespace.drone.metadata[0].name
labels = {
app = "drone-runner-secret"
}
}
spec {
selector = {
app = "drone-runner-secret"
}
port {
name = "http"
port = "3000"
}
}
}
# SQL to delete last N builds (n = 1000)
# PRAGMA foreign_keys = ON;
# WITH n_build_ids_per_repo as (
# SELECT build_id
# FROM (
# SELECT
# build_id,
# build_repo_id,
# DENSE_RANK() OVER (PARTITION BY build_repo_id ORDER BY build_id DESC) AS rank
# FROM builds
# ) AS t
# WHERE t.rank <= 1000
# )
# DELETE FROM
# builds
# WHERE
# builds.build_id NOT IN (SELECT build_id FROM n_build_ids_per_repo);

15
stacks/drone/providers.tf Normal file
View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/drone/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/ebook2audiobook/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "ebook2audiobook" {
source = "../../modules/kubernetes/ebook2audiobook"
tls_secret_name = var.tls_secret_name
tier = local.tiers.gpu
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.gpu
}

@ -0,0 +1 @@
Subproject commit 22a69d0fb169bcff79f894f7ae9769c6fea09b6d

View file

@ -0,0 +1,410 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_namespace" "ebook2audiobook" {
metadata {
name = "ebook2audiobook"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
resource "kubernetes_deployment" "ebook2audiobook" {
metadata {
name = "ebook2audiobook"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
labels = {
app = "ebook2audiobook"
tier = var.tier
}
}
spec {
replicas = 0 # Disabled - using audiblez instead
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "ebook2audiobook"
}
}
template {
metadata {
labels = {
app = "ebook2audiobook"
}
}
spec {
node_selector = {
"gpu" : "true"
}
toleration {
key = "nvidia.com/gpu"
operator = "Equal"
value = "true"
effect = "NoSchedule"
}
container {
name = "ebook2audiobook"
image = "docker.io/athomasson2/ebook2audiobook:v25.12.30-cu128"
tty = true
stdin = true
port {
container_port = 7860
}
# LD_LIBRARY_PATH needed for CUDA detection - libcudart.so is in non-standard location
env {
name = "LD_LIBRARY_PATH"
value = "/usr/local/lib/python3.12/site-packages/nvidia/cuda_runtime/lib:/usr/local/lib/python3.12/site-packages/nvidia/cudnn/lib"
}
volume_mount {
mount_path = "/home/user"
name = "data"
}
resources {
limits = {
"nvidia.com/gpu" = "1"
}
}
}
volume {
name = "data"
nfs {
server = "10.0.10.15"
path = "/mnt/main/ebook2audiobook"
}
}
}
}
}
}
resource "kubernetes_service" "ebook2audiobook" {
metadata {
name = "ebook2audiobook"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
labels = {
"app" = "ebook2audiobook"
}
}
spec {
selector = {
app = "ebook2audiobook"
}
port {
name = "http"
port = 80
target_port = 7860
}
}
}
# resource "kubernetes_deployment" "piper" {
# metadata {
# name = "piper"
# namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
# labels = {
# app = "piper"
# }
# }
# spec {
# replicas = 1
# strategy {
# type = "Recreate"
# }
# selector {
# match_labels = {
# app = "piper"
# }
# }
# template {
# metadata {
# labels = {
# app = "piper"
# }
# }
# spec {
# container {
# name = "piper"
# # image = "lscr.io/linuxserver/piper:gpu"
# # image = "piper-tts-wyoming:latest"
# image = "viktorbarzin/piper"
# # image = "nvidia/cuda:12.8.1-cudnn-devel-ubuntu24.04"
# # working_dir = "/app"
# command = ["sleep", "3600"]
# volume_mount {
# mount_path = "/config"
# name = "data"
# }
# resources {
# limits = {
# "nvidia.com/gpu" = "1"
# }
# }
# # env {
# # name = "PIPER_VOICE"
# # value = "en_US-lessac-medium"
# # }
# env {
# name = "VOICE_MODEL"
# value = "en_US-lessac-medium"
# }
# env {
# name = "LOG_LEVEL"
# value = "DEBUG"
# }
# port {
# name = "web"
# container_port = 10200
# }
# }
# volume {
# name = "data"
# nfs {
# server = "10.0.10.15"
# path = "/mnt/main/piper"
# }
# }
# }
# }
# }
# }
# resource "kubernetes_service" "piper" {
# metadata {
# name = "piper"
# namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
# labels = {
# "app" = "piper"
# }
# }
# spec {
# selector = {
# app = "piper"
# }
# port {
# name = "http"
# port = 80
# target_port = 10200
# }
# }
# }
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
name = "ebook2audiobook"
tls_secret_name = var.tls_secret_name
protected = true
}
resource "kubernetes_deployment" "audiblez" {
metadata {
name = "audiblez"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
labels = {
app = "audiblez"
tier = var.tier
}
}
spec {
replicas = 0 # Disabled - using audiblez-web instead
selector {
match_labels = {
app = "audiblez"
}
}
template {
metadata {
labels = {
app = "audiblez"
}
}
spec {
node_selector = {
"gpu" : "true"
}
toleration {
key = "nvidia.com/gpu"
operator = "Equal"
value = "true"
effect = "NoSchedule"
}
container {
image = "viktorbarzin/audiblez:latest"
name = "audiblez"
command = ["/usr/bin/sleep", "infinity"]
volume_mount {
name = "data"
mount_path = "/mnt"
}
resources {
limits = {
"nvidia.com/gpu" = "1"
}
}
}
volume {
name = "data"
nfs {
server = "10.0.10.15"
path = "/mnt/main/audiblez"
}
}
}
}
}
}
# Audiblez Web UI
resource "kubernetes_deployment" "audiblez-web" {
metadata {
name = "audiblez-web"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
labels = {
app = "audiblez-web"
tier = var.tier
}
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "audiblez-web"
}
}
template {
metadata {
labels = {
app = "audiblez-web"
}
}
spec {
node_selector = {
"gpu" : "true"
}
toleration {
key = "nvidia.com/gpu"
operator = "Equal"
value = "true"
effect = "NoSchedule"
}
container {
# Use digest to bypass local registry cache
image = "docker.io/viktorbarzin/audiblez-web@sha256:eb6d13e6372b931bcac45ca389c063dfadc7b3fc2a607127fc76c5627b13a34c"
image_pull_policy = "Always"
name = "audiblez-web"
port {
container_port = 8000
}
volume_mount {
name = "data"
mount_path = "/mnt"
}
resources {
limits = {
"nvidia.com/gpu" = "1"
}
}
# liveness_probe {
# http_get {
# path = "/health"
# port = 8000
# }
# initial_delay_seconds = 10
# period_seconds = 30
# }
# readiness_probe {
# http_get {
# path = "/health"
# port = 8000
# }
# initial_delay_seconds = 5
# period_seconds = 10
# }
}
volume {
name = "data"
nfs {
server = "10.0.10.15"
path = "/mnt/main/audiblez"
}
}
}
}
}
}
resource "kubernetes_service" "audiblez-web" {
metadata {
name = "audiblez-web"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
labels = {
"app" = "audiblez-web"
}
}
spec {
selector = {
app = "audiblez-web"
}
port {
name = "http"
port = 80
target_port = 8000
}
}
}
module "audiblez-web-ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.ebook2audiobook.metadata[0].name
name = "audiblez-web"
host = "audiblez"
tls_secret_name = var.tls_secret_name
protected = true
max_body_size = "500m" # Allow large EPUB uploads
}

View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

View file

@ -0,0 +1 @@
../../secrets

40
stacks/echo/.terraform.lock.hcl generated Normal file
View file

@ -0,0 +1,40 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/helm" {
version = "3.1.1"
hashes = [
"h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=",
"zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275",
"zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a",
"zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29",
"zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104",
"zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990",
"zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34",
"zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8",
"zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1",
"zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b",
"zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903",
"zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}
provider "registry.terraform.io/hashicorp/kubernetes" {
version = "3.0.1"
hashes = [
"h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=",
"zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281",
"zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba",
"zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7",
"zh:8d0656ff422df94575668e32c310980193fccb1c28117e5c78dd2d4050a760a6",
"zh:9795119b30ec0c1baa99a79abace56ac850b6e6fbce60e7f6067792f6eb4b5f4",
"zh:b388c87acc40f6bd9620f4e23f01f3c7b41d9b88a68d5255dec0a72f0bdec249",
"zh:b59abd0a980649c2f97f172392f080eaeb18e486b603f83bf95f5d93aeccc090",
"zh:ba6e3060fddf4a022087d8f09e38aa0001c705f21170c2ded3d1c26c12f70d97",
"zh:c12626d044b1d5501cf95ca78cbe507c13ad1dd9f12d4736df66eb8e5f336eb8",
"zh:c55203240d50f4cdeb3df1e1760630d677679f5b1a6ffd9eba23662a4ad05119",
"zh:ea206a5a32d6e0d6e32f1849ad703da9a28355d9c516282a8458b5cf1502b2a1",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

6
stacks/echo/backend.tf Normal file
View file

@ -0,0 +1,6 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
terraform {
backend "local" {
path = "/Users/viktorbarzin/code/infra/state/stacks/echo/terraform.tfstate"
}
}

View file

@ -11,7 +11,7 @@ locals {
}
module "echo" {
source = "../../modules/kubernetes/echo"
tls_secret_name = var.tls_secret_name
tier = local.tiers.edge
source = "./module"
tls_secret_name = var.tls_secret_name
tier = local.tiers.edge
}

View file

@ -0,0 +1,84 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
resource "kubernetes_namespace" "echo" {
metadata {
name = "echo"
labels = {
"istio-injection" : "disabled"
tier = var.tier
}
}
}
module "tls_secret" {
source = "../../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.echo.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "echo" {
metadata {
name = "echo"
namespace = kubernetes_namespace.echo.metadata[0].name
labels = {
app = "echo"
tier = var.tier
}
}
spec {
replicas = 5
selector {
match_labels = {
app = "echo"
}
}
template {
metadata {
labels = {
app = "echo"
}
}
spec {
container {
image = "mendhak/http-https-echo"
name = "echo"
port {
container_port = 8080
}
port {
container_port = 8443
}
}
}
}
}
}
resource "kubernetes_service" "echo" {
metadata {
name = "echo"
namespace = kubernetes_namespace.echo.metadata[0].name
labels = {
"app" = "echo"
}
}
spec {
selector = {
app = "echo"
}
port {
name = "http"
port = "80"
target_port = "8080"
}
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.echo.metadata[0].name
name = "echo"
tls_secret_name = var.tls_secret_name
}

15
stacks/echo/providers.tf Normal file
View file

@ -0,0 +1,15 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
variable "kube_config_path" {
type = string
default = "~/.kube/config"
}
provider "kubernetes" {
config_path = var.kube_config_path
}
provider "helm" {
kubernetes = {
config_path = var.kube_config_path
}
}

1
stacks/echo/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

Some files were not shown because too many files have changed in this diff Show more