Compare commits

...

6 commits

8 changed files with 165 additions and 36 deletions

12
main.tf
View file

@ -132,6 +132,7 @@ variable "clickhouse_password" { type = string }
variable "clickhouse_postgres_password" { type = string }
variable "wealthfolio_password_hash" { type = string }
variable "aiostreams_database_connection_string" { type = string }
variable "actualbudget_credentials" { type = map(any) }
provider "kubernetes" {
@ -180,7 +181,14 @@ module "k8s-node-template" {
is_k8s_template = true # provision cloud init file with k8s deps
snippet_name = local.k8s_cloud_init_snippet_name
# Add mirror registry
containerd_config_update_command = "echo '[plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.io\"]' >> /etc/containerd/config.toml && echo ' endpoint = [\"http://10.0.20.10:5000\"]' >> /etc/containerd/config.toml" # docker registry vm
containerd_config_update_command = <<-EOF
echo '[plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.io\"]' >> /etc/containerd/config.toml && echo ' endpoint = [\"http://10.0.20.10:5000\"]' >> /etc/containerd/config.toml # docker registry vm
sed -i 's/.*max_concurrent_downloads = 3/max_concurrent_downloads = 20/g' /etc/containerd/config.toml # Enable multiple concurrent downloads
sudo sed -i '/serializeImagePulls:/d' /var/lib/kubelet/config.yaml && \
sudo sed -i '/maxParallelImagePulls:/d' /var/lib/kubelet/config.yaml && \
echo -e 'serializeImagePulls: false\nmaxParallelImagePulls: 50' | sudo tee -a /var/lib/kubelet/config.yaml && \
EOF
k8s_join_command = var.k8s_join_command
}
@ -546,6 +554,8 @@ module "kubernetes_cluster" {
wealthfolio_password_hash = var.wealthfolio_password_hash
aiostreams_database_connection_string = var.aiostreams_database_connection_string
actualbudget_credentials = var.actualbudget_credentials
}

View file

@ -4,6 +4,14 @@ 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 {
@ -13,9 +21,6 @@ resource "kubernetes_deployment" "actualbudget" {
app = "actualbudget-${var.name}"
tier = var.tier
}
annotations = {
"reloader.stakater.com/search" = "true"
}
}
spec {
replicas = 1
@ -94,3 +99,119 @@ module "ingress" {
}
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

@ -1,5 +1,6 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "credentials" { type = map(any) }
# To create a new deployment:
/**
@ -26,20 +27,24 @@ module "tls_secret" {
# 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
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
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)
}

View file

@ -111,6 +111,7 @@ variable "clickhouse_password" { type = string }
variable "clickhouse_postgres_password" { type = string }
variable "wealthfolio_password_hash" { type = string }
variable "aiostreams_database_connection_string" { type = string }
variable "actualbudget_credentials" { type = map(any) }
variable "defcon_level" {
@ -552,7 +553,7 @@ module "nginx-ingress" {
module "crowdsec" {
source = "./crowdsec"
tier = local.tiers.cluster
tier = local.tiers.core
for_each = contains(local.active_modules, "crowdsec") ? { crowdsec = true } : {}
tls_secret_name = var.tls_secret_name
homepage_username = var.homepage_credentials["crowdsec"]["username"]
@ -809,6 +810,7 @@ module "actualbudget" {
for_each = contains(local.active_modules, "actualbudget") ? { actualbudget = true } : {}
tls_secret_name = var.tls_secret_name
tier = local.tiers.edge
credentials = var.actualbudget_credentials
depends_on = [null_resource.core_services]
}

View file

@ -82,7 +82,11 @@ module "idrac" {
port = 443
tls_secret_name = var.tls_secret_name
backend_protocol = "HTTPS"
depends_on = [kubernetes_namespace.reverse-proxy]
extra_annotations = {
# authentik causes 413; we don't need the header below
"nginx.ingress.kubernetes.io/auth-response-headers" : null
}
depends_on = [kubernetes_namespace.reverse-proxy]
}
# Can either listen on https or http; can't do both :/
@ -96,23 +100,10 @@ module "tp-link-gateway" {
backend_protocol = "HTTPS"
depends_on = [kubernetes_namespace.reverse-proxy]
protected = true
# Doesn't work due to 413 due to GA/authentik cookie
# additional_configuration_snippet = <<-EOF
# # 1. Try to extract the sysauth cookie and its value
# # This regex looks for 'sysauth=' followed by everything until a semicolon or end of string
# set $sysauth_only "";
# if ($http_cookie ~* "sysauth=([^;]+)") {
# set $sysauth_only "sysauth=$1";
# }
# # 2. Overwrite the Cookie header.
# # If sysauth was found, only it is sent. If not found, no cookies are sent.
# proxy_set_header Cookie $sysauth_only;
# EOF
# extra_annotations = {
# client-header-buffer-size : "16k"
# large-client-header-buffers : "4 16k"
# }
extra_annotations = {
# authentik causes 413; we don't need the header below
"nginx.ingress.kubernetes.io/auth-response-headers" : null
}
}
# https://truenas.viktorbarzin.me/

View file

@ -30,7 +30,7 @@ resource "kubernetes_deployment" "tuya-bridge" {
}
}
spec {
replicas = 1
replicas = 3
selector {
match_labels = {
app = "tuya-bridge"

Binary file not shown.

Binary file not shown.