diff --git a/bin/occ b/bin/occ
new file mode 100755
index 0000000..b0b128d
--- /dev/null
+++ b/bin/occ
@@ -0,0 +1,3 @@
+#!/bin/bash
+POD_NAME=$(kubectl get pods -n nextcloud -l app=nextcloud -o jsonpath="{.items[0].metadata.name}")
+kubectl -n nextcloud exec -it $POD_NAME -- /bin/su -s /bin/bash www-data -c "/var/www/html/occ $*"
\ No newline at end of file
diff --git a/terraform/apps/dev-01/apps.tf b/terraform/apps/dev-01/apps.tf
index b1ee77f..46f2f9c 100644
--- a/terraform/apps/dev-01/apps.tf
+++ b/terraform/apps/dev-01/apps.tf
@@ -15,6 +15,7 @@ module "dns" {
source = "../../modules/apps/coredns"
forward_dns_servers = local.dns_nameservers
+ override_hosts = local.override_hosts
zones = local.zones
}
@@ -23,3 +24,16 @@ module "reverse_proxy" {
services = local.reverse_proxy_services
}
+
+
+module "nextcloud" {
+ source = "../../modules/apps/nextcloud"
+
+ fqdn = local.nextcloud_fqdn
+ persistent_folder = local.persistent_folder
+ app_config = local.nextcloud_config
+ db_credentials_are_secrets = true
+
+ tls_enabled = true
+ issuer = local.internal_issuer
+}
diff --git a/terraform/apps/dev-01/config.tf b/terraform/apps/dev-01/config.tf
index c5386a6..4b7a5b0 100644
--- a/terraform/apps/dev-01/config.tf
+++ b/terraform/apps/dev-01/config.tf
@@ -16,6 +16,13 @@ locals {
"185.253.5.0"
]
+ override_hosts = [
+ {
+ name = "cloud.alexpires.me"
+ ip = "10.19.4.136"
+ },
+ ]
+
zones = [
{
fqdn = "${local.lab_domain}"
@@ -88,4 +95,40 @@ locals {
}
}
+ scaleway_smtp_host = "smtp.tem.scw.cloud"
+
+ nextcloud_fqdn = "cloud.alexpires.me"
+ nextcloud_db_passwd = var.nextcloud_db_passwd
+ nextcloud_db_root_password = var.nextcloud_db_root_password
+ nextcloud_db_path = "${local.persistent_folder}/mysql/nextcloud"
+ backup_folder = "/mnt/usb/backups/nextcloud"
+ nextcloud_config = {
+ mail_from = "cloud"
+ mail_domain = "alexpires.me"
+ smtp_user = var.scaleway_project_id
+ smtp_password = local.mail_app_api_secret_key
+ smtp_host = local.scaleway_smtp_host
+ admin_password = var.nextcloud_admin_password
+ db_host = module.nextcloud_db.host
+ db_name = module.nextcloud_db.db_name
+ db_user = module.nextcloud_db.app_crendentials_name
+ db_password = module.nextcloud_db.app_crendentials_name
+ }
+
+ backup_retention_days = 3
+ backup_cron_schedule = "0 2 * * *" # Daily at 2 AM
+
+ backup_bucket_name = data.terraform_remote_state.scaleway.outputs.backup_bucket_name
+ backup_app_api_secret_key = data.terraform_remote_state.scaleway.outputs.backup_app_api_secret_key
+ backup_app_api_access_key = data.terraform_remote_state.scaleway.outputs.backup_app_api_access_key
+ mail_app_api_secret_key = data.terraform_remote_state.scaleway.outputs.mail_app_api_secret_key
+}
+
+data "terraform_remote_state" "scaleway" {
+ backend = "s3"
+ config = {
+ bucket = "a13labs.infra.eu"
+ key = "scaleway.core.infra.tfstate"
+ region = "eu-west-1"
+ }
}
diff --git a/terraform/apps/dev-01/databases.tf b/terraform/apps/dev-01/databases.tf
new file mode 100644
index 0000000..6cecc58
--- /dev/null
+++ b/terraform/apps/dev-01/databases.tf
@@ -0,0 +1,17 @@
+module "nextcloud_db" {
+ source = "../../modules/db/mariadb"
+
+ namespace = module.nextcloud.namespace
+ app_name = "nextcloud"
+
+ app_password = local.nextcloud_db_passwd
+ root_password = local.nextcloud_db_root_password
+ retention_days = local.backup_retention_days
+ cron_schedule = local.backup_cron_schedule
+
+ database_folder = local.nextcloud_db_path
+ backup_folder = local.backup_folder
+
+ tls_enabled = true
+ issuer = local.internal_issuer
+}
diff --git a/terraform/apps/dev-01/secrets.tf b/terraform/apps/dev-01/secrets.tf
index 8b13789..70bcf54 100644
--- a/terraform/apps/dev-01/secrets.tf
+++ b/terraform/apps/dev-01/secrets.tf
@@ -1 +1,17 @@
+variable "nextcloud_db_passwd" {
+ description = "Password for the Nextcloud database"
+ type = string
+ sensitive = true
+}
+variable "nextcloud_db_root_password" {
+ description = "Root password for the Nextcloud database"
+ type = string
+ sensitive = true
+}
+
+variable "nextcloud_admin_password" {
+ description = "Password for the Nextcloud admin user"
+ type = string
+ sensitive = true
+}
diff --git a/terraform/apps/dev-01/sectool.env b/terraform/apps/dev-01/sectool.env
index 865ddf9..794536d 100644
--- a/terraform/apps/dev-01/sectool.env
+++ b/terraform/apps/dev-01/sectool.env
@@ -1,2 +1,6 @@
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY
+TF_VAR_nextcloud_db_passwd=$MYSQL_NEXTCLOUD_PASSWORD
+TF_VAR_nextcloud_db_root_password=$MYSQL_ROOT_PASSWORD
+TF_VAR_nextcloud_admin_password=$NEXTCLOUD_ADMIN_PASSWORD
+TF_VAR_scaleway_project_id=$SCALEWAY_PROJECT_ID
diff --git a/terraform/apps/dev-01/variables.tf b/terraform/apps/dev-01/variables.tf
index 8b13789..e1ff0dc 100644
--- a/terraform/apps/dev-01/variables.tf
+++ b/terraform/apps/dev-01/variables.tf
@@ -1 +1,4 @@
-
+variable "scaleway_project_id" {
+ description = "Scaleway Project Id"
+ type = string
+}
diff --git a/terraform/apps/prod-01/apps.tf b/terraform/apps/prod-01/apps.tf
index 6da7328..babbad2 100644
--- a/terraform/apps/prod-01/apps.tf
+++ b/terraform/apps/prod-01/apps.tf
@@ -46,7 +46,7 @@ module "mail" {
relay_smtp_host = local.scaleway_smtp_host
relay_smtp_port = 465
relay_smtp_username = var.scaleway_project_id
- relay_smtp_password = scaleway_iam_api_key.mail_app_api.secret_key
+ relay_smtp_password = local.mail_app_api_secret_key
fetch_emails_schedule = local.fetch_emails_schedule
@@ -84,7 +84,7 @@ module "gitea" {
smtp_host = local.scaleway_smtp_host
smtp_port = local.scaleway_smtp_port
smtp_user = var.scaleway_project_id
- smtp_passwd = scaleway_iam_api_key.mail_app_api.secret_key
+ smtp_passwd = local.mail_app_api_secret_key
secret_key = var.gitea_secret_key
internal_token = var.gitea_internal_token
disable_ssh = false
@@ -108,11 +108,11 @@ module "sftpgo" {
smtp_host = local.scaleway_smtp_host
smtp_port = local.scaleway_smtp_port
smtp_username = var.scaleway_project_id
- smtp_password = scaleway_iam_api_key.mail_app_api.secret_key
+ smtp_password = local.mail_app_api_secret_key
from_email = "sftpgo@${local.primary_domain}"
- access_key = scaleway_iam_api_key.sftpgo_app_api.access_key
- secret_key = scaleway_iam_api_key.sftpgo_app_api.secret_key
+ access_key = local.sftpgo_app_api_access_key
+ secret_key = local.sftpgo_app_api_secret_key
}
module "trivy" {
@@ -124,7 +124,7 @@ module "trivy" {
smtp_host = local.scaleway_smtp_host
smtp_port = local.scaleway_smtp_port
smtp_username = var.scaleway_project_id
- smtp_password = scaleway_iam_api_key.mail_app_api.secret_key
+ smtp_password = local.mail_app_api_secret_key
from_email = "trivy@${local.primary_domain}"
to_email = "c.alexandre.pires@${local.primary_domain}"
}
diff --git a/terraform/apps/prod-01/backups.tf b/terraform/apps/prod-01/backups.tf
index 8bdd6e5..5385110 100644
--- a/terraform/apps/prod-01/backups.tf
+++ b/terraform/apps/prod-01/backups.tf
@@ -7,9 +7,9 @@ module "mail_backup" {
scaleway_organization_id = var.scaleway_organization_id
scaleway_project_id = var.scaleway_organization_id
- access_key = scaleway_iam_api_key.backup_app_api.access_key
- secret_key = scaleway_iam_api_key.backup_app_api.secret_key
- bucket_name = scaleway_object_bucket.backup.name
+ access_key = local.backup_app_api_access_key
+ secret_key = local.backup_app_api_secret_key
+ bucket_name = local.backup_bucket_name
retention_days = local.local_backup_retention_days
cron_schedule = local.mail_files_backup_cron_schedule
@@ -26,9 +26,9 @@ module "gitea_backup" {
scaleway_organization_id = var.scaleway_organization_id
scaleway_project_id = var.scaleway_organization_id
- access_key = scaleway_iam_api_key.backup_app_api.access_key
- secret_key = scaleway_iam_api_key.backup_app_api.secret_key
- bucket_name = scaleway_object_bucket.backup.name
+ access_key = local.backup_app_api_access_key
+ secret_key = local.backup_app_api_secret_key
+ bucket_name = local.backup_bucket_name
retention_days = local.local_backup_retention_days
cron_schedule = local.gitea_files_backup_cron_schedule
@@ -46,9 +46,9 @@ module "sftpgo_backup" {
scaleway_organization_id = var.scaleway_organization_id
scaleway_project_id = var.scaleway_organization_id
- access_key = scaleway_iam_api_key.backup_app_api.access_key
- secret_key = scaleway_iam_api_key.backup_app_api.secret_key
- bucket_name = scaleway_object_bucket.backup.name
+ access_key = local.backup_app_api_access_key
+ secret_key = local.backup_app_api_secret_key
+ bucket_name = local.backup_bucket_name
retention_days = local.local_backup_retention_days
cron_schedule = local.sftpgo_files_backup_cron_schedule
diff --git a/terraform/apps/prod-01/buckets.tf b/terraform/apps/prod-01/buckets.tf
deleted file mode 100644
index 88a350e..0000000
--- a/terraform/apps/prod-01/buckets.tf
+++ /dev/null
@@ -1,130 +0,0 @@
-resource "random_string" "bucket_suffix" {
- length = 8
- lower = true
- upper = false
- special = false
-}
-
-resource "scaleway_object_bucket" "backup" {
- name = "a13labs-backup-${random_string.bucket_suffix.result}"
- project_id = var.scaleway_project_id
- region = "fr-par"
-
- lifecycle_rule {
- id = "gitea-clean"
- prefix = "gitea-backup/"
- enabled = true
-
- expiration {
- days = local.cloud_backup_retention_days
- }
- }
-
- lifecycle_rule {
- id = "wordpress-clean"
- prefix = "wordpress-backup/"
- enabled = true
-
- expiration {
- days = local.cloud_backup_retention_days
- }
- }
-
- lifecycle_rule {
- id = "mail-clean"
- prefix = "mail-backup/"
- enabled = true
-
- expiration {
- days = local.cloud_backup_retention_days
- }
- }
-}
-
-resource "scaleway_object_bucket_policy" "backup" {
- bucket = scaleway_object_bucket.backup.name
- policy = jsonencode({
- Version = "2023-04-17",
- Id = "AllowAccess",
- Statement = [
- {
- Effect = "Allow"
- Action = [
- "s3:*",
- ]
- Principal = {
- SCW = "user_id:${var.scaleway_user_id}"
- }
- Resource = [
- scaleway_object_bucket.backup.name,
- "${scaleway_object_bucket.backup.name}/*",
- ]
- },
- {
- Effect = "Allow"
- Action = [
- "s3:*",
- ]
- Principal = {
- SCW = "application_id:${scaleway_iam_application.backup_app.id}"
- }
- Resource = [
- scaleway_object_bucket.backup.name,
- "${scaleway_object_bucket.backup.name}/*",
- ],
- Condition = {
- IpAddress = {
- "aws:SourceIp" = local.instance_ips
- }
- },
- },
- ]
- })
-}
-
-resource "scaleway_object_bucket" "sftpgo" {
- name = "a13labs-sftpgo-${random_string.bucket_suffix.result}"
- project_id = var.scaleway_project_id
- region = "fr-par"
-}
-
-resource "scaleway_object_bucket_policy" "sftpgo" {
- bucket = scaleway_object_bucket.sftpgo.name
- policy = jsonencode({
- Version = "2023-04-17",
- Id = "AllowAccess",
- Statement = [
- {
- Effect = "Allow"
- Action = [
- "s3:*",
- ]
- Principal = {
- SCW = "user_id:${var.scaleway_user_id}"
- }
- Resource = [
- scaleway_object_bucket.sftpgo.name,
- "${scaleway_object_bucket.sftpgo.name}/*",
- ]
- },
- {
- Effect = "Allow"
- Action = [
- "s3:*",
- ]
- Principal = {
- SCW = "application_id:${scaleway_iam_application.sftpgo_app.id}"
- }
- Resource = [
- scaleway_object_bucket.sftpgo.name,
- "${scaleway_object_bucket.sftpgo.name}/*",
- ],
- Condition = {
- IpAddress = {
- "aws:SourceIp" = local.instance_ips
- }
- },
- },
- ]
- })
-}
diff --git a/terraform/apps/prod-01/config.tf b/terraform/apps/prod-01/config.tf
index d4a7a95..be23b4a 100644
--- a/terraform/apps/prod-01/config.tf
+++ b/terraform/apps/prod-01/config.tf
@@ -44,7 +44,6 @@ locals {
# backup
local_backup_retention_days = 2
- cloud_backup_retention_days = 3
mail_backup_path = "${local.persistent_folder}/backup.mail"
gitea_backup_path = "${local.persistent_folder}/backup.gitea"
sftpgo_backup_path = "${local.persistent_folder}/backup.sftpgo"
@@ -108,43 +107,47 @@ locals {
"Connection" = "upgrade"
}
},
- # {
- # private = true
- # path = "/tools/gitea"
- # upstream = "http://10.19.4.136:8000"
- # rewrite = "^/tools/gitea/(.*)$ /$1 break"
- # },
{
path = "/"
},
]
},
+ "nextcloud" = {
+ http_port = 8081
+ https_port = 8444
+ custom_ingress_annotations = {
+ "nginx.ingress.kubernetes.io/proxy-body-size" = "4G"
+ "nginx.ingress.kubernetes.io/proxy-request-buffering" = "on"
+ "nginx.ingress.kubernetes.io/proxy-buffer-size" = "32k"
+ "nginx.ingress.kubernetes.io/proxy-buffers-number" = "16"
+ }
+ tls = true
+ custom_snippet = file("${path.module}/resources/nextcloud.conf")
+ resolver = "10.19.4.136"
+ fqdn = ["cloud.alexpires.me"]
+ upstream = "https://cloud.alexpires.me"
+ locations = [
+ {
+ path = "/"
+ },
+ ]
+ },
+
}
-
- # VPS configuration
- instance_ips = [
- "${local.vps_1.ip}/32",
- ]
-
- vps_1 = {
- id = data.terraform_remote_state.contabo.outputs.instances[0].id
- name = data.terraform_remote_state.contabo.outputs.instances[0].name
- ip = data.terraform_remote_state.contabo.outputs.instances[0].ip_config[0].v4[0].ip
- }
-
+ backup_bucket_name = data.terraform_remote_state.scaleway.outputs.backup_bucket_name
+ backup_app_api_secret_key = data.terraform_remote_state.scaleway.outputs.backup_app_api_secret_key
+ backup_app_api_access_key = data.terraform_remote_state.scaleway.outputs.backup_app_api_access_key
+ mail_app_api_secret_key = data.terraform_remote_state.scaleway.outputs.mail_app_api_secret_key
+ sftpgo_app_api_access_key = data.terraform_remote_state.scaleway.outputs.sftpgo_app_api_access_key
+ sftpgo_app_api_secret_key = data.terraform_remote_state.scaleway.outputs.sftpgo_app_api_secret_key
}
-data "scaleway_account_project" "default" {
- project_id = var.scaleway_project_id
- organization_id = var.scaleway_organization_id
-}
-
-data "terraform_remote_state" "contabo" {
+data "terraform_remote_state" "scaleway" {
backend = "s3"
config = {
bucket = "a13labs.infra.eu"
- key = "contabo.core.infra.tfstate"
+ key = "scaleway.core.infra.tfstate"
region = "eu-west-1"
}
}
diff --git a/terraform/apps/prod-01/provider.tf b/terraform/apps/prod-01/provider.tf
index a38af38..ba14014 100644
--- a/terraform/apps/prod-01/provider.tf
+++ b/terraform/apps/prod-01/provider.tf
@@ -21,10 +21,6 @@ terraform {
source = "hashicorp/kubernetes"
version = "2.36.0"
}
- scaleway = {
- source = "scaleway/scaleway"
- version = "~>2.13"
- }
}
}
@@ -34,11 +30,4 @@ provider "kubernetes" {
insecure = true
}
-provider "scaleway" {
- zone = "fr-par-2"
- region = "fr-par"
- access_key = var.scaleway_access_key
- secret_key = var.scaleway_secret_key
- organization_id = var.scaleway_organization_id
-}
diff --git a/terraform/apps/prod-01/resources/nextcloud.conf b/terraform/apps/prod-01/resources/nextcloud.conf
new file mode 100644
index 0000000..10fd3d0
--- /dev/null
+++ b/terraform/apps/prod-01/resources/nextcloud.conf
@@ -0,0 +1,32 @@
+server_tokens off;
+proxy_hide_header X-Powered-By;
+
+location = /.well-known/webfinger {
+ return 301 $scheme://$host/index.php/.well-known/webfinger;
+}
+
+location = /.well-known/nodeinfo {
+ return 301 $scheme://$host/index.php/.well-known/nodeinfo;
+}
+
+location = /.well-known/carddav {
+ return 301 $scheme://$host/remote.php/dav;
+}
+
+location = /.well-known/caldav {
+ return 301 $scheme://$host/remote.php/dav;
+}
+
+location = /robots.txt {
+ allow all;
+ log_not_found off;
+ access_log off;
+}
+
+location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
+ deny all;
+}
+
+location ~ ^/(?:autotest|occ|issue|indie|db_|console) {
+ deny all;
+}
\ No newline at end of file
diff --git a/terraform/apps/prod-01/secrets.tf b/terraform/apps/prod-01/secrets.tf
index 0588c8c..c5f5400 100644
--- a/terraform/apps/prod-01/secrets.tf
+++ b/terraform/apps/prod-01/secrets.tf
@@ -11,18 +11,6 @@ variable "gitea_mysql_password" {
sensitive = true
}
-variable "scaleway_access_key" {
- description = "Scaleway Access key"
- type = string
- sensitive = true
-}
-
-variable "scaleway_secret_key" {
- description = "Scaleway Secret key"
- type = string
- sensitive = true
-}
-
variable "wireguard_private_key" {
description = "Wireguard public key"
type = string
diff --git a/terraform/apps/prod-01/sectool.env b/terraform/apps/prod-01/sectool.env
index 76df3bf..e2ab170 100644
--- a/terraform/apps/prod-01/sectool.env
+++ b/terraform/apps/prod-01/sectool.env
@@ -1,9 +1,6 @@
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY
-TF_VAR_scaleway_access_key=$SCALEWAY_ACCESS_KEY
-TF_VAR_scaleway_secret_key=$SCALEWAY_SECRET_KEY
TF_VAR_scaleway_project_id=$SCALEWAY_PROJECT_ID
-TF_VAR_scaleway_user_id=$SCALEWAY_USER_ID
TF_VAR_scaleway_organization_id=$SCALEWAY_ORGANIZATION_ID
TF_VAR_mysql_root_password=$MYSQL_ROOT_PASSWORD
TF_VAR_wordpress_mysql_password=$MYSQL_WORDPRESS_PASSWORD
diff --git a/terraform/apps/prod-01/variables.tf b/terraform/apps/prod-01/variables.tf
index 3c1f094..0251eec 100644
--- a/terraform/apps/prod-01/variables.tf
+++ b/terraform/apps/prod-01/variables.tf
@@ -1,8 +1,3 @@
-variable "scaleway_user_id" {
- description = "Scaleway User Id"
- type = string
-}
-
variable "scaleway_project_id" {
description = "Scaleway Project Id"
type = string
diff --git a/terraform/iac/scaleway/buckets.tf b/terraform/iac/scaleway/buckets.tf
index 82b6475..220c439 100644
--- a/terraform/iac/scaleway/buckets.tf
+++ b/terraform/iac/scaleway/buckets.tf
@@ -43,3 +43,125 @@ resource "scaleway_object_bucket_policy" "policy" {
]
})
}
+
+resource "random_string" "bucket_suffix" {
+ length = 8
+ lower = true
+ upper = false
+ special = false
+}
+
+resource "scaleway_object_bucket" "backup" {
+ name = "a13labs-backup-${random_string.bucket_suffix.result}"
+ project_id = var.scaleway_project_id
+ region = "fr-par"
+
+ lifecycle_rule {
+ id = "gitea-clean"
+ prefix = "gitea-backup/"
+ enabled = true
+
+ expiration {
+ days = local.cloud_backup_retention_days
+ }
+ }
+
+ lifecycle_rule {
+ id = "mail-clean"
+ prefix = "mail-backup/"
+ enabled = true
+
+ expiration {
+ days = local.cloud_backup_retention_days
+ }
+ }
+}
+
+resource "scaleway_object_bucket_policy" "backup" {
+ bucket = scaleway_object_bucket.backup.name
+ policy = jsonencode({
+ Version = "2023-04-17",
+ Id = "AllowAccess",
+ Statement = [
+ {
+ Effect = "Allow"
+ Action = [
+ "s3:*",
+ ]
+ Principal = {
+ SCW = "user_id:${var.scaleway_user_id}"
+ }
+ Resource = [
+ scaleway_object_bucket.backup.name,
+ "${scaleway_object_bucket.backup.name}/*",
+ ]
+ },
+ {
+ Effect = "Allow"
+ Action = [
+ "s3:*",
+ ]
+ Principal = {
+ SCW = "application_id:${scaleway_iam_application.backup_app.id}"
+ }
+ Resource = [
+ scaleway_object_bucket.backup.name,
+ "${scaleway_object_bucket.backup.name}/*",
+ ],
+ Condition = {
+ IpAddress = {
+ "aws:SourceIp" = local.instance_ips
+ }
+ },
+ },
+ ]
+ })
+}
+
+resource "scaleway_object_bucket" "sftpgo" {
+ name = "a13labs-sftpgo-${random_string.bucket_suffix.result}"
+ project_id = var.scaleway_project_id
+ region = "fr-par"
+}
+
+resource "scaleway_object_bucket_policy" "sftpgo" {
+ bucket = scaleway_object_bucket.sftpgo.name
+ policy = jsonencode({
+ Version = "2023-04-17",
+ Id = "AllowAccess",
+ Statement = [
+ {
+ Effect = "Allow"
+ Action = [
+ "s3:*",
+ ]
+ Principal = {
+ SCW = "user_id:${var.scaleway_user_id}"
+ }
+ Resource = [
+ scaleway_object_bucket.sftpgo.name,
+ "${scaleway_object_bucket.sftpgo.name}/*",
+ ]
+ },
+ {
+ Effect = "Allow"
+ Action = [
+ "s3:*",
+ ]
+ Principal = {
+ SCW = "application_id:${scaleway_iam_application.sftpgo_app.id}"
+ }
+ Resource = [
+ scaleway_object_bucket.sftpgo.name,
+ "${scaleway_object_bucket.sftpgo.name}/*",
+ ],
+ Condition = {
+ IpAddress = {
+ "aws:SourceIp" = local.instance_ips
+ }
+ },
+ },
+ ]
+ })
+}
+
diff --git a/terraform/iac/scaleway/config.tf b/terraform/iac/scaleway/config.tf
index 5fe00ad..813a871 100644
--- a/terraform/iac/scaleway/config.tf
+++ b/terraform/iac/scaleway/config.tf
@@ -3,6 +3,8 @@ locals {
"${local.vps_1.ip}/32",
]
+ cloud_backup_retention_days = 3
+
vps_1 = {
id = data.terraform_remote_state.contabo.outputs.instances[0].id
name = data.terraform_remote_state.contabo.outputs.instances[0].name
@@ -19,3 +21,7 @@ data "terraform_remote_state" "contabo" {
}
}
+data "scaleway_account_project" "default" {
+ project_id = var.scaleway_project_id
+ organization_id = var.scaleway_organization_id
+}
diff --git a/terraform/apps/prod-01/iam.tf b/terraform/iac/scaleway/iam.tf
similarity index 99%
rename from terraform/apps/prod-01/iam.tf
rename to terraform/iac/scaleway/iam.tf
index 4529a99..504efb8 100644
--- a/terraform/apps/prod-01/iam.tf
+++ b/terraform/iac/scaleway/iam.tf
@@ -2,14 +2,6 @@ resource "scaleway_iam_application" "backup_app" {
name = "k8s_backup_app"
}
-resource "scaleway_iam_application" "mail_app" {
- name = "mail_app"
-}
-
-resource "scaleway_iam_application" "sftpgo_app" {
- name = "sftpgo_app"
-}
-
resource "scaleway_iam_policy" "object_read_write_backup" {
name = "K8s backup app policy"
description = "Gives k8s backup job access to object storage in project"
@@ -26,6 +18,10 @@ resource "scaleway_iam_policy" "object_read_write_backup" {
}
}
+resource "scaleway_iam_application" "mail_app" {
+ name = "mail_app"
+}
+
resource "scaleway_iam_policy" "email_full_access" {
name = "Email full access policy"
description = "Gives access to transactional email in project"
@@ -39,6 +35,9 @@ resource "scaleway_iam_policy" "email_full_access" {
}
}
+resource "scaleway_iam_application" "sftpgo_app" {
+ name = "sftpgo_app"
+}
resource "scaleway_iam_policy" "object_read_write_sftpgo" {
name = "SFtpGo app policy"
diff --git a/terraform/iac/scaleway/outputs.tf b/terraform/iac/scaleway/outputs.tf
new file mode 100644
index 0000000..8486678
--- /dev/null
+++ b/terraform/iac/scaleway/outputs.tf
@@ -0,0 +1,34 @@
+output "backup_bucket_name" {
+ description = "The name of the backup bucket."
+ value = scaleway_object_bucket.backup.name
+}
+
+output "backup_app_api_secret_key" {
+ description = "The secret key for the backup API."
+ value = scaleway_iam_api_key.backup_app_api.secret_key
+ sensitive = true
+}
+
+output "backup_app_api_access_key" {
+ description = "The access key for the backup API."
+ value = scaleway_iam_api_key.backup_app_api.access_key
+ sensitive = true
+}
+
+output "mail_app_api_secret_key" {
+ description = "The secret key for the mail app API."
+ value = scaleway_iam_api_key.mail_app_api.secret_key
+ sensitive = true
+}
+
+output "sftpgo_app_api_access_key" {
+ description = "The access key for the SFTPGo app API."
+ value = scaleway_iam_api_key.sftpgo_app_api.access_key
+ sensitive = true
+}
+
+output "sftpgo_app_api_secret_key" {
+ description = "The secret key for the SFTPGo app API."
+ value = scaleway_iam_api_key.sftpgo_app_api.secret_key
+ sensitive = true
+}
diff --git a/terraform/modules/apps/coredns/config.tf b/terraform/modules/apps/coredns/config.tf
index 12195f5..ccf6790 100644
--- a/terraform/modules/apps/coredns/config.tf
+++ b/terraform/modules/apps/coredns/config.tf
@@ -2,6 +2,8 @@
locals {
configfile = templatefile("${path.module}/resources/Corefile.tpl", {
zones = var.zones
+ override_hosts = length(var.override_hosts) > 0
+ hosts = var.override_hosts
forward_dns_servers = join(" ", var.forward_dns_servers)
})
configfile_checksum = md5(local.configfile)
diff --git a/terraform/modules/apps/coredns/resources/Corefile.tpl b/terraform/modules/apps/coredns/resources/Corefile.tpl
index be170ae..84ff828 100644
--- a/terraform/modules/apps/coredns/resources/Corefile.tpl
+++ b/terraform/modules/apps/coredns/resources/Corefile.tpl
@@ -1,4 +1,12 @@
.:53 {
+%{ if override_hosts ~}
+ hosts {
+%{ for h in hosts ~}
+ ${h.ip} ${h.name}
+%{ endfor ~}
+ fallthrough
+ }
+%{ endif ~}
errors
health {
lameduck 5s
diff --git a/terraform/modules/apps/coredns/variables.tf b/terraform/modules/apps/coredns/variables.tf
index 4241c9d..b587f79 100644
--- a/terraform/modules/apps/coredns/variables.tf
+++ b/terraform/modules/apps/coredns/variables.tf
@@ -10,6 +10,15 @@ variable "forward_dns_servers" {
default = ["8.8.8.8", "8.8.4.4"]
}
+variable "override_hosts" {
+ description = "Override hosts"
+ type = list(object({
+ ip = string
+ name = string
+ }))
+ default = []
+}
+
variable "zones" {
description = "Zones to be managed by coredns"
type = list(object({
diff --git a/terraform/modules/apps/nextcloud/config.tf b/terraform/modules/apps/nextcloud/config.tf
new file mode 100644
index 0000000..2e402b8
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/config.tf
@@ -0,0 +1,90 @@
+locals {
+ persistent_folder = var.persistent_folder
+
+ database_credentials = {
+ MYSQL_USER = {
+ key = "username"
+ name = var.app_config.db_user
+ }
+
+ MYSQL_PASSWORD = {
+ key = "password"
+ name = var.app_config.db_password
+ }
+ }
+
+ nextcloud_env_vars = merge({
+ # Database configuration
+ MYSQL_DATABASE = var.app_config.db_name
+ MYSQL_HOST = var.app_config.db_host
+
+ # Email configuration
+ SMTP_HOST = var.app_config.smtp_host
+ SMTP_SECURE = var.app_config.smtp_secure
+ SMTP_PORT = var.app_config.smtp_port
+ MAIL_FROM_ADDRESS = var.app_config.mail_from
+ MAIL_DOMAIN = var.app_config.mail_domain
+ SMTP_AUTHTYPE = "PLAIN"
+
+ # Redis configuration
+ REDIS_HOST = "redis"
+
+ # General
+ NEXTCLOUD_TRUSTED_DOMAINS = var.fqdn
+ TRUSTED_PROXIES = join(" ", ["10.1.0.0/16"])
+ OVERWRITEHOST = var.fqdn
+ OVERWRITEPROTOCOL = "https"
+ OVERWRITECLIURL = "https://${var.fqdn}"
+
+ # PHP
+ PHP_MEMORY_LIMIT = "512M"
+ }, var.db_credentials_are_secrets ? {} : local.database_credentials)
+
+ nextcloud_secrets = merge({
+
+ SMTP_NAME = {
+ key = "username"
+ name = kubernetes_secret.nextcloud_mail_credentials.metadata[0].name
+ }
+
+ SMTP_PASSWORD = {
+ key = "password"
+ name = kubernetes_secret.nextcloud_mail_credentials.metadata[0].name
+ }
+
+ NEXTCLOUD_ADMIN_USER = {
+ key = "username"
+ name = kubernetes_secret.nextcloud_admin_credentials.metadata[0].name
+ }
+
+ NEXTCLOUD_ADMIN_PASSWORD = {
+ key = "password"
+ name = kubernetes_secret.nextcloud_admin_credentials.metadata[0].name
+ }
+ }, var.db_credentials_are_secrets ? local.database_credentials : {})
+
+
+ nextcloud_data = "${local.persistent_folder}/nextcloud"
+
+ apache_confs = {
+ for f in fileset("${path.module}/resources/apache2/conf-enabled/", "*.conf") :
+ "${f}" => file("${path.module}/resources/apache2/conf-enabled//${f}")
+ }
+ apache_mods_load = {
+ for f in fileset("${path.module}/resources/apache2/mods-enabled/", "*.cload") :
+ "${f}" => file("${path.module}/resources/apache2/mods-enabled//${f}")
+ }
+ apache_mods_conf = {
+ for f in fileset("${path.module}/resources/apache2/mods-enabled/", "*.conf") :
+ "${f}" => file("${path.module}/resources/apache2/mods-enabled//${f}")
+ }
+ apache_sites = {
+ for f in fileset("${path.module}/resources/apache2/sites-enabled/", "*.conf") :
+ "${f}" => file("${path.module}/resources/apache2/sites-enabled//${f}")
+ }
+
+ apache_confs_checksum = sha256(jsonencode(local.apache_confs))
+ apache_sites_checksum = sha256(jsonencode(local.apache_sites))
+ apache_mods_load_checksum = sha256(jsonencode(local.apache_mods_load))
+ apache_mods_conf_checksum = sha256(jsonencode(local.apache_mods_conf))
+}
diff --git a/terraform/modules/apps/nextcloud/cron.tf b/terraform/modules/apps/nextcloud/cron.tf
new file mode 100644
index 0000000..7a14224
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/cron.tf
@@ -0,0 +1,54 @@
+resource "kubernetes_cron_job_v1" "nextcloud_cron_apache" {
+ depends_on = [
+ kubernetes_deployment.nextcloud_apache
+ ]
+ metadata {
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ name = "cronjob-trigger"
+ }
+ spec {
+ schedule = "*/15 * * * *"
+ concurrency_policy = "Forbid"
+ failed_jobs_history_limit = 2
+ successful_jobs_history_limit = 2
+ job_template {
+ metadata {
+ labels = {
+ app = "cronjob-trigger"
+ }
+ }
+ spec {
+ backoff_limit = 1
+ parallelism = 1
+ completions = 1
+ active_deadline_seconds = 300
+ template {
+ metadata {
+ labels = {
+ app = "cronjob-trigger"
+ }
+ }
+ spec {
+ container {
+ name = "nextcloud"
+ image = "nextcloud:${var.tag}"
+
+ command = ["curl"]
+ args = ["--fail", "-L", "http://http/cron.php"]
+ security_context {
+ allow_privilege_escalation = false
+ }
+ }
+ restart_policy = "Never"
+ termination_grace_period_seconds = 30
+ }
+ }
+ }
+ }
+ }
+ lifecycle {
+ replace_triggered_by = [
+ kubernetes_deployment.nextcloud_apache
+ ]
+ }
+}
diff --git a/terraform/modules/apps/nextcloud/ingress.tf b/terraform/modules/apps/nextcloud/ingress.tf
new file mode 100644
index 0000000..958f055
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/ingress.tf
@@ -0,0 +1,67 @@
+resource "kubernetes_service" "nextcloud_apache" {
+ metadata {
+ name = "http"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ spec {
+ port {
+ port = var.tls_enabled ? 443 : 80
+ target_port = var.tls_enabled ? 443 : 80
+ }
+ selector = {
+ app = "nextcloud"
+ }
+ cluster_ip = "None"
+ }
+}
+
+resource "kubernetes_ingress_v1" "nextcloud_ingress" {
+ depends_on = [
+ kubernetes_deployment.nextcloud_apache
+ ]
+ metadata {
+ name = "ingress"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+
+ annotations = merge({
+ "kubernetes.io/ingress.class" = "public"
+ "cert-manager.io/cluster-issuer" = "letsencrypt-prod"
+ "kubernetes.io/tls-acme" = "true"
+ "nginx.ingress.kubernetes.io/ssl-redirect" = "true"
+ "nginx.ingress.kubernetes.io/proxy-body-size" = "4G"
+ "nginx.ingress.kubernetes.io/proxy-request-buffering" = "on"
+ "nginx.ingress.kubernetes.io/proxy-buffer-size" = "32k"
+ "nginx.ingress.kubernetes.io/proxy-buffers-number" = "16"
+ "nginx.ingress.kubernetes.io/server-snippet" = file("${path.module}/resources/nextcloud-server-snippet.conf")
+ },
+ var.tls_enabled ? {
+ "nginx.org/ssl-services" = "http"
+ "nginx.org/ssl-redirect" = "true"
+ "nginx.org/redirect-to-https" = "true"
+ "nginx.ingress.kubernetes.io/backend-protocol" = "HTTPS"
+ } : {}
+ )
+ }
+ spec {
+ tls {
+ hosts = [var.fqdn]
+ secret_name = "nextcloud-tls"
+ }
+ rule {
+ host = var.fqdn
+ http {
+ path {
+ backend {
+ service {
+ name = "http"
+ port {
+ number = var.tls_enabled ? 443 : 80
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/terraform/modules/apps/nextcloud/main.tf b/terraform/modules/apps/nextcloud/main.tf
new file mode 100644
index 0000000..f3add72
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/main.tf
@@ -0,0 +1,285 @@
+resource "kubernetes_namespace" "nextcloud" {
+ metadata {
+ annotations = {
+ name = "nextcloud"
+ }
+
+ labels = {
+ name = "nextcloud"
+ }
+
+ name = "nextcloud"
+ }
+}
+
+resource "kubernetes_manifest" "internal_cert" {
+ count = var.tls_enabled ? 1 : 0
+ manifest = {
+ apiVersion = "cert-manager.io/v1"
+ kind = "Certificate"
+ metadata = {
+ name = "internal-cert"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ spec = {
+ secretName = "internal-cert"
+ issuerRef = {
+ name = var.issuer
+ kind = "ClusterIssuer"
+ }
+ commonName = var.fqdn
+ dnsNames = [var.fqdn]
+ }
+ }
+}
+
+resource "kubernetes_config_map" "apache_confs" {
+ metadata {
+ name = "nextcloud-apache-confs"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ data = local.apache_confs
+}
+
+resource "kubernetes_config_map" "apache_mods_load" {
+ metadata {
+ name = "nextcloud-apache-mods-load"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ data = local.apache_mods_load
+}
+
+resource "kubernetes_config_map" "apache_mods_conf" {
+ metadata {
+ name = "nextcloud-apache-mods-enabled"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ data = local.apache_mods_conf
+}
+
+resource "kubernetes_config_map" "apache_sites" {
+ metadata {
+ name = "nextcloud-apache-sites"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ data = local.apache_sites
+}
+
+resource "kubernetes_service_account" "nextcloud_service_account" {
+
+ metadata {
+ name = "nextcloud-app-sa"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+
+ automount_service_account_token = false
+}
+
+
+resource "kubernetes_deployment" "nextcloud_apache" {
+
+ depends_on = [
+ kubernetes_deployment.nextcloud_redis
+ ]
+
+ metadata {
+ name = "nextcloud-app"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ spec {
+ selector {
+ match_labels = {
+ app = "nextcloud"
+ }
+ }
+ strategy {
+ type = "Recreate"
+ }
+ template {
+ metadata {
+ labels = {
+ app = "nextcloud"
+ }
+ annotations = {
+ "checksum/apache_confs" = local.apache_confs_checksum
+ "checksum/apache_sites" = local.apache_sites_checksum
+ "checksum/apache_mods_load" = local.apache_mods_load_checksum
+ "checksum/apache_mods_conf" = local.apache_mods_conf_checksum
+ }
+ }
+ spec {
+ service_account_name = kubernetes_service_account.nextcloud_service_account.metadata[0].name
+
+ container {
+ name = "nextcloud"
+ image = "nextcloud:${var.tag}"
+ image_pull_policy = "Always"
+
+ resources {
+ requests = {
+ memory = "200Mi"
+ }
+ }
+
+ readiness_probe {
+ http_get {
+ port = "http"
+ path = "/status.php"
+ }
+ initial_delay_seconds = 30
+ period_seconds = 10
+ success_threshold = 1
+ failure_threshold = 3
+ }
+
+ liveness_probe {
+ tcp_socket {
+ port = "http"
+ }
+ initial_delay_seconds = 5
+ period_seconds = 10
+ success_threshold = 1
+ failure_threshold = 3
+ }
+
+ dynamic "env" {
+ for_each = local.nextcloud_env_vars
+ content {
+ name = env.key
+ value = env.value
+ }
+ }
+
+ security_context {
+ allow_privilege_escalation = false
+ }
+
+ dynamic "env" {
+ for_each = local.nextcloud_secrets
+ content {
+ name = env.key
+ value_from {
+ secret_key_ref {
+ key = env.value.key
+ name = env.value.name
+ }
+ }
+ }
+ }
+ port {
+ container_port = 80
+ name = "http"
+ }
+ dynamic "port" {
+ for_each = var.tls_enabled ? [1] : []
+ content {
+ container_port = 443
+ name = "https"
+ }
+ }
+ volume_mount {
+ mount_path = "/var/www/html"
+ name = "html-data"
+ }
+ dynamic "volume_mount" {
+ for_each = local.apache_confs
+ content {
+ mount_path = "/etc/apache2/conf-enabled/${volume_mount.key}"
+ name = "apache-confs"
+ sub_path = volume_mount.key
+ read_only = true
+ }
+ }
+ dynamic "volume_mount" {
+ for_each = local.apache_sites
+ content {
+ mount_path = "/etc/apache2/sites-enabled/${volume_mount.key}"
+ name = "apache-sites"
+ sub_path = volume_mount.key
+ read_only = true
+ }
+ }
+ dynamic "volume_mount" {
+ for_each = local.apache_mods_load
+ content {
+ mount_path = "/etc/apache2/mods-enabled/${volume_mount.key}"
+ name = "apache-mods-load"
+ sub_path = volume_mount.key
+ read_only = true
+ }
+ }
+ dynamic "volume_mount" {
+ for_each = local.apache_mods_conf
+ content {
+ mount_path = "/etc/apache2/mods-enabled/${volume_mount.key}"
+ name = "apache-mods-conf"
+ sub_path = volume_mount.key
+ read_only = true
+ }
+ }
+ dynamic "volume_mount" {
+ for_each = var.tls_enabled ? [1] : []
+ content {
+ mount_path = "/etc/ssl/certs/private"
+ name = "internal-cert"
+ read_only = true
+ }
+ }
+ }
+ volume {
+ name = "html-data"
+ host_path {
+ path = local.nextcloud_data
+ }
+ }
+ volume {
+ name = "apache-confs"
+ config_map {
+ name = kubernetes_config_map.apache_confs.metadata[0].name
+ }
+ }
+ volume {
+ name = "apache-sites"
+ config_map {
+ name = kubernetes_config_map.apache_sites.metadata[0].name
+ }
+ }
+ volume {
+ name = "apache-mods-load"
+ config_map {
+ name = kubernetes_config_map.apache_mods_load.metadata[0].name
+ }
+ }
+ volume {
+ name = "apache-mods-conf"
+ config_map {
+ name = kubernetes_config_map.apache_mods_conf.metadata[0].name
+ }
+ }
+ dynamic "volume" {
+ for_each = var.tls_enabled ? [1] : []
+ content {
+ name = "internal-cert"
+ secret {
+ secret_name = kubernetes_manifest.internal_cert[0].manifest["metadata"]["name"]
+ items {
+ key = "tls.crt"
+ path = "tls.crt"
+ }
+ items {
+ key = "tls.key"
+ path = "tls.key"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ lifecycle {
+ replace_triggered_by = [
+ kubernetes_deployment.nextcloud_redis
+ ]
+ }
+}
+
diff --git a/terraform/modules/apps/nextcloud/outputs.tf b/terraform/modules/apps/nextcloud/outputs.tf
new file mode 100644
index 0000000..ac68835
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/outputs.tf
@@ -0,0 +1,4 @@
+output "namespace" {
+ description = "value of namespace"
+ value = kubernetes_namespace.nextcloud.metadata[0].name
+}
diff --git a/terraform/modules/apps/nextcloud/provider.tf b/terraform/modules/apps/nextcloud/provider.tf
new file mode 100644
index 0000000..2eaa508
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/provider.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = "~>1.8"
+ required_providers {
+ kubernetes = {
+ source = "hashicorp/kubernetes"
+ version = "2.36.0"
+ }
+ }
+}
diff --git a/terraform/modules/apps/nextcloud/redis.tf b/terraform/modules/apps/nextcloud/redis.tf
new file mode 100644
index 0000000..63da2f6
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/redis.tf
@@ -0,0 +1,76 @@
+resource "kubernetes_service" "nextcloud_redis" {
+ metadata {
+ name = "redis"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ spec {
+ port {
+ port = 6379
+ name = "redis"
+ }
+ selector = {
+ app = "redis"
+ }
+ cluster_ip = "None"
+ }
+}
+
+resource "kubernetes_deployment" "nextcloud_redis" {
+ metadata {
+ name = "redis"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ spec {
+ selector {
+ match_labels = {
+ app = "redis"
+ }
+ }
+ strategy {
+ type = "RollingUpdate"
+ }
+ template {
+ metadata {
+ labels = {
+ app = "redis"
+ }
+ }
+ spec {
+ container {
+ name = "redis"
+ image = "redis:latest"
+
+ security_context {
+ allow_privilege_escalation = false
+ }
+
+ readiness_probe {
+ tcp_socket {
+ port = "redis"
+ }
+ initial_delay_seconds = 10
+ period_seconds = 15
+ success_threshold = 1
+ failure_threshold = 3
+ }
+
+ liveness_probe {
+ tcp_socket {
+ port = "redis"
+ }
+ initial_delay_seconds = 10
+ period_seconds = 15
+ success_threshold = 1
+ failure_threshold = 3
+ }
+
+ port {
+ container_port = 6379
+ name = "redis"
+ protocol = "TCP"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/terraform/modules/apps/nextcloud/resources/apache2/conf-enabled/99-compression.conf b/terraform/modules/apps/nextcloud/resources/apache2/conf-enabled/99-compression.conf
new file mode 100644
index 0000000..2366fb1
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/resources/apache2/conf-enabled/99-compression.conf
@@ -0,0 +1,14 @@
+
+ # Enable compression for the following content types
+ AddOutputFilterByType DEFLATE text/html
+ AddOutputFilterByType DEFLATE text/css
+ AddOutputFilterByType DEFLATE application/javascript
+ AddOutputFilterByType DEFLATE application/x-javascript
+ AddOutputFilterByType DEFLATE application/json
+ AddOutputFilterByType DEFLATE application/xml
+ AddOutputFilterByType DEFLATE image/svg+xml
+ AddOutputFilterByType DEFLATE text/xml
+
+
+# Do not compress images
+SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|woff|woff2)$ no-gzip
diff --git a/terraform/modules/apps/nextcloud/resources/apache2/conf-enabled/99-nextcloudworkers.conf b/terraform/modules/apps/nextcloud/resources/apache2/conf-enabled/99-nextcloudworkers.conf
new file mode 100644
index 0000000..72e34fe
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/resources/apache2/conf-enabled/99-nextcloudworkers.conf
@@ -0,0 +1 @@
+MaxRequestWorkers 10
\ No newline at end of file
diff --git a/terraform/modules/apps/nextcloud/resources/apache2/mods-enabled/ssl.conf b/terraform/modules/apps/nextcloud/resources/apache2/mods-enabled/ssl.conf
new file mode 100644
index 0000000..4456743
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/resources/apache2/mods-enabled/ssl.conf
@@ -0,0 +1,86 @@
+LoadModule socache_shmcb_module /usr/lib/apache2/modules/mod_socache_shmcb.so
+LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
+
+# Pseudo Random Number Generator (PRNG):
+# Configure one or more sources to seed the PRNG of the SSL library.
+# The seed data should be of good random quality.
+# WARNING! On some platforms /dev/random blocks if not enough entropy
+# is available. This means you then cannot use the /dev/random device
+# because it would lead to very long connection times (as long as
+# it requires to make more entropy available). But usually those
+# platforms additionally provide a /dev/urandom device which doesn't
+# block. So, if available, use this one instead. Read the mod_ssl User
+# Manual for more details.
+#
+SSLRandomSeed startup builtin
+SSLRandomSeed startup file:/dev/urandom 512
+SSLRandomSeed connect builtin
+SSLRandomSeed connect file:/dev/urandom 512
+
+##
+## SSL Global Context
+##
+## All SSL configuration in this context applies both to
+## the main server and all SSL-enabled virtual hosts.
+##
+
+#
+# Some MIME-types for downloading Certificates and CRLs
+#
+AddType application/x-x509-ca-cert .crt
+AddType application/x-pkcs7-crl .crl
+
+# Pass Phrase Dialog:
+# Configure the pass phrase gathering process.
+# The filtering dialog program (`builtin' is a internal
+# terminal dialog) has to provide the pass phrase on stdout.
+SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase
+
+# Inter-Process Session Cache:
+# Configure the SSL Session Cache: First the mechanism
+# to use and second the expiring timeout (in seconds).
+# (The mechanism dbm has known memory leaks and should not be used).
+#SSLSessionCache dbm:${APACHE_RUN_DIR}/ssl_scache
+SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
+SSLSessionCacheTimeout 300
+
+# Semaphore:
+# Configure the path to the mutual exclusion semaphore the
+# SSL engine uses internally for inter-process synchronization.
+# (Disabled by default, the global Mutex directive consolidates by default
+# this)
+#Mutex file:${APACHE_LOCK_DIR}/ssl_mutex ssl-cache
+
+
+# SSL Cipher Suite:
+# List the ciphers that the client is permitted to negotiate. See the
+# ciphers(1) man page from the openssl package for list of all available
+# options.
+# Enable only secure ciphers:
+SSLCipherSuite HIGH:!aNULL
+
+# SSL server cipher order preference:
+# Use server priorities for cipher algorithm choice.
+# Clients may prefer lower grade encryption. You should enable this
+# option if you want to enforce stronger encryption, and can afford
+# the CPU cost, and did not override SSLCipherSuite in a way that puts
+# insecure ciphers first.
+# Default: Off
+#SSLHonorCipherOrder on
+
+# The protocols to enable.
+# Available values: all, SSLv3, TLSv1, TLSv1.1, TLSv1.2
+# SSL v2 is no longer supported
+SSLProtocol all -SSLv3
+
+# Allow insecure renegotiation with clients which do not yet support the
+# secure renegotiation protocol. Default: Off
+#SSLInsecureRenegotiation on
+
+# Whether to forbid non-SNI clients to access name based virtual hosts.
+# Default: Off
+#SSLStrictSNIVHostCheck On
+
+# Warning: Session Tickets require regular reloading of the server!
+# Make sure you do this (e.g. via logrotate) before changing this setting!
+SSLSessionTickets off
diff --git a/terraform/modules/apps/nextcloud/resources/apache2/sites-enabled/999-default.conf b/terraform/modules/apps/nextcloud/resources/apache2/sites-enabled/999-default.conf
new file mode 100644
index 0000000..662f3d6
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/resources/apache2/sites-enabled/999-default.conf
@@ -0,0 +1,11 @@
+
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www/html
+
+ ErrorLog ${APACHE_LOG_DIR}/error.log
+ CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+ SSLEngine on
+ SSLCertificateFile /etc/ssl/certs/private/tls.crt
+ SSLCertificateKeyFile /etc/ssl/certs/private/tls.key
+
\ No newline at end of file
diff --git a/terraform/modules/apps/nextcloud/resources/enable_ssl.sh b/terraform/modules/apps/nextcloud/resources/enable_ssl.sh
new file mode 100644
index 0000000..e69de29
diff --git a/terraform/modules/apps/nextcloud/resources/nextcloud-server-snippet.conf b/terraform/modules/apps/nextcloud/resources/nextcloud-server-snippet.conf
new file mode 100644
index 0000000..10fd3d0
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/resources/nextcloud-server-snippet.conf
@@ -0,0 +1,32 @@
+server_tokens off;
+proxy_hide_header X-Powered-By;
+
+location = /.well-known/webfinger {
+ return 301 $scheme://$host/index.php/.well-known/webfinger;
+}
+
+location = /.well-known/nodeinfo {
+ return 301 $scheme://$host/index.php/.well-known/nodeinfo;
+}
+
+location = /.well-known/carddav {
+ return 301 $scheme://$host/remote.php/dav;
+}
+
+location = /.well-known/caldav {
+ return 301 $scheme://$host/remote.php/dav;
+}
+
+location = /robots.txt {
+ allow all;
+ log_not_found off;
+ access_log off;
+}
+
+location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
+ deny all;
+}
+
+location ~ ^/(?:autotest|occ|issue|indie|db_|console) {
+ deny all;
+}
\ No newline at end of file
diff --git a/terraform/modules/apps/nextcloud/secrets.tf b/terraform/modules/apps/nextcloud/secrets.tf
new file mode 100644
index 0000000..4b123a8
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/secrets.tf
@@ -0,0 +1,24 @@
+resource "kubernetes_secret" "nextcloud_mail_credentials" {
+ metadata {
+ name = "nextcloud-mail-credentials"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ data = {
+ username = var.app_config.smtp_user
+ password = var.app_config.smtp_password
+ }
+ type = "Opaque"
+}
+
+resource "kubernetes_secret" "nextcloud_admin_credentials" {
+ metadata {
+ name = "nextcloud-admin-credentials"
+ namespace = kubernetes_namespace.nextcloud.metadata[0].name
+ }
+ data = {
+ username = var.app_config.admin_username
+ password = var.app_config.admin_password
+ }
+ type = "Opaque"
+}
+
diff --git a/terraform/modules/apps/nextcloud/variables.tf b/terraform/modules/apps/nextcloud/variables.tf
new file mode 100644
index 0000000..e93ae7b
--- /dev/null
+++ b/terraform/modules/apps/nextcloud/variables.tf
@@ -0,0 +1,52 @@
+variable "persistent_folder" {
+ description = "The path to the persistent folder"
+ type = string
+}
+
+variable "tag" {
+ description = "The version of the websites to install"
+ type = string
+ default = "30-apache"
+}
+
+variable "fqdn" {
+ description = "The fully qualified domain name for the Rustdesk server"
+ type = string
+}
+
+variable "tls_enabled" {
+ description = "Enable TLS for the SFTPGo server"
+ type = bool
+ default = true
+}
+
+variable "issuer" {
+ description = "The issuer for the certificate"
+ type = string
+ default = "internal-ca"
+}
+
+variable "db_credentials_are_secrets" {
+ description = "set to true if the database credentials are secrets"
+ type = bool
+ default = false
+}
+
+variable "app_config" {
+ description = "The configuration for the SFTPGo server"
+ type = object({
+ mail_from = string
+ mail_domain = string
+ smtp_user = string
+ smtp_password = string
+ smtp_host = string
+ admin_password = string
+ db_host = string
+ db_name = string
+ db_user = string
+ db_password = string
+ smtp_port = optional(number, 465)
+ smtp_secure = optional(string, "ssl")
+ admin_username = optional(string, "admin")
+ })
+}
diff --git a/terraform/modules/apps/nginx-reverse-proxy/main.tf b/terraform/modules/apps/nginx-reverse-proxy/main.tf
index 78b38d8..62f02bc 100644
--- a/terraform/modules/apps/nginx-reverse-proxy/main.tf
+++ b/terraform/modules/apps/nginx-reverse-proxy/main.tf
@@ -136,12 +136,14 @@ resource "kubernetes_ingress_v1" "reverse-proxy_ingress" {
"kubernetes.io/ingress.class" = "public"
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
},
+ each.value.custom_ingress_annotations,
each.value.tls ? {
"nginx.org/ssl-services" = format("reverse-proxy-%s", replace(each.key, ".", "-"))
"nginx.org/ssl-redirect" = "true"
"nginx.org/redirect-to-https" = "true"
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTPS"
- } : {})
+ } : {}
+ )
}
spec {
tls {
diff --git a/terraform/modules/apps/nginx-reverse-proxy/variables.tf b/terraform/modules/apps/nginx-reverse-proxy/variables.tf
index 83f5fcf..b105017 100644
--- a/terraform/modules/apps/nginx-reverse-proxy/variables.tf
+++ b/terraform/modules/apps/nginx-reverse-proxy/variables.tf
@@ -29,13 +29,15 @@ variable "issuer_name" {
variable "services" {
description = "A list of services to be deployed"
type = map(object({
- fqdn = list(string)
- upstream = optional(string, "")
- resolver = optional(string, "")
- default_headers = optional(map(string), {}),
- http_port = optional(number, 80)
- https_port = optional(number, 443)
- tls = optional(bool, false)
+ fqdn = list(string)
+ custom_ingress_annotations = optional(map(string), {})
+ annotations = optional(map(string), {})
+ upstream = optional(string, "")
+ resolver = optional(string, "")
+ default_headers = optional(map(string), {}),
+ http_port = optional(number, 80)
+ https_port = optional(number, 443)
+ tls = optional(bool, false)
locations = optional(list(object({
path = string,
headers = optional(map(string), {}),
diff --git a/terraform/modules/db/mariadb/outputs.tf b/terraform/modules/db/mariadb/outputs.tf
index 4940974..5b08838 100644
--- a/terraform/modules/db/mariadb/outputs.tf
+++ b/terraform/modules/db/mariadb/outputs.tf
@@ -13,3 +13,7 @@ output "root_crendentials_name" {
output "app_crendentials_name" {
value = kubernetes_secret.app_password.metadata[0].name
}
+
+output "db_name" {
+ value = var.app_name
+}