Add Nextcloud deployment and configuration
- Introduced Nextcloud module with Kubernetes resources including deployment, service, ingress, and cron job. - Configured Apache settings for Nextcloud with SSL support and compression. - Created secrets for mail and admin credentials. - Added necessary environment variables for Nextcloud configuration. - Removed unused Scaleway access and secret keys from secrets and variables. - Updated CoreDNS module to support custom host overrides. - Implemented backup bucket policies and lifecycle rules for Scaleway object storage. - Enhanced IAM policies and applications for backup and email services. - Added outputs for backup bucket and API keys.
This commit is contained in:
@@ -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 $*"
|
||||||
@@ -15,6 +15,7 @@ module "dns" {
|
|||||||
source = "../../modules/apps/coredns"
|
source = "../../modules/apps/coredns"
|
||||||
|
|
||||||
forward_dns_servers = local.dns_nameservers
|
forward_dns_servers = local.dns_nameservers
|
||||||
|
override_hosts = local.override_hosts
|
||||||
zones = local.zones
|
zones = local.zones
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,3 +24,16 @@ module "reverse_proxy" {
|
|||||||
|
|
||||||
services = local.reverse_proxy_services
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ locals {
|
|||||||
"185.253.5.0"
|
"185.253.5.0"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
override_hosts = [
|
||||||
|
{
|
||||||
|
name = "cloud.alexpires.me"
|
||||||
|
ip = "10.19.4.136"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
zones = [
|
zones = [
|
||||||
{
|
{
|
||||||
fqdn = "${local.lab_domain}"
|
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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
||||||
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_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
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
|
variable "scaleway_project_id" {
|
||||||
|
description = "Scaleway Project Id"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ module "mail" {
|
|||||||
relay_smtp_host = local.scaleway_smtp_host
|
relay_smtp_host = local.scaleway_smtp_host
|
||||||
relay_smtp_port = 465
|
relay_smtp_port = 465
|
||||||
relay_smtp_username = var.scaleway_project_id
|
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
|
fetch_emails_schedule = local.fetch_emails_schedule
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ module "gitea" {
|
|||||||
smtp_host = local.scaleway_smtp_host
|
smtp_host = local.scaleway_smtp_host
|
||||||
smtp_port = local.scaleway_smtp_port
|
smtp_port = local.scaleway_smtp_port
|
||||||
smtp_user = var.scaleway_project_id
|
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
|
secret_key = var.gitea_secret_key
|
||||||
internal_token = var.gitea_internal_token
|
internal_token = var.gitea_internal_token
|
||||||
disable_ssh = false
|
disable_ssh = false
|
||||||
@@ -108,11 +108,11 @@ module "sftpgo" {
|
|||||||
smtp_host = local.scaleway_smtp_host
|
smtp_host = local.scaleway_smtp_host
|
||||||
smtp_port = local.scaleway_smtp_port
|
smtp_port = local.scaleway_smtp_port
|
||||||
smtp_username = var.scaleway_project_id
|
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}"
|
from_email = "sftpgo@${local.primary_domain}"
|
||||||
|
|
||||||
access_key = scaleway_iam_api_key.sftpgo_app_api.access_key
|
access_key = local.sftpgo_app_api_access_key
|
||||||
secret_key = scaleway_iam_api_key.sftpgo_app_api.secret_key
|
secret_key = local.sftpgo_app_api_secret_key
|
||||||
}
|
}
|
||||||
|
|
||||||
module "trivy" {
|
module "trivy" {
|
||||||
@@ -124,7 +124,7 @@ module "trivy" {
|
|||||||
smtp_host = local.scaleway_smtp_host
|
smtp_host = local.scaleway_smtp_host
|
||||||
smtp_port = local.scaleway_smtp_port
|
smtp_port = local.scaleway_smtp_port
|
||||||
smtp_username = var.scaleway_project_id
|
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}"
|
from_email = "trivy@${local.primary_domain}"
|
||||||
to_email = "c.alexandre.pires@${local.primary_domain}"
|
to_email = "c.alexandre.pires@${local.primary_domain}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ module "mail_backup" {
|
|||||||
|
|
||||||
scaleway_organization_id = var.scaleway_organization_id
|
scaleway_organization_id = var.scaleway_organization_id
|
||||||
scaleway_project_id = var.scaleway_organization_id
|
scaleway_project_id = var.scaleway_organization_id
|
||||||
access_key = scaleway_iam_api_key.backup_app_api.access_key
|
access_key = local.backup_app_api_access_key
|
||||||
secret_key = scaleway_iam_api_key.backup_app_api.secret_key
|
secret_key = local.backup_app_api_secret_key
|
||||||
bucket_name = scaleway_object_bucket.backup.name
|
bucket_name = local.backup_bucket_name
|
||||||
|
|
||||||
retention_days = local.local_backup_retention_days
|
retention_days = local.local_backup_retention_days
|
||||||
cron_schedule = local.mail_files_backup_cron_schedule
|
cron_schedule = local.mail_files_backup_cron_schedule
|
||||||
@@ -26,9 +26,9 @@ module "gitea_backup" {
|
|||||||
|
|
||||||
scaleway_organization_id = var.scaleway_organization_id
|
scaleway_organization_id = var.scaleway_organization_id
|
||||||
scaleway_project_id = var.scaleway_organization_id
|
scaleway_project_id = var.scaleway_organization_id
|
||||||
access_key = scaleway_iam_api_key.backup_app_api.access_key
|
access_key = local.backup_app_api_access_key
|
||||||
secret_key = scaleway_iam_api_key.backup_app_api.secret_key
|
secret_key = local.backup_app_api_secret_key
|
||||||
bucket_name = scaleway_object_bucket.backup.name
|
bucket_name = local.backup_bucket_name
|
||||||
|
|
||||||
retention_days = local.local_backup_retention_days
|
retention_days = local.local_backup_retention_days
|
||||||
cron_schedule = local.gitea_files_backup_cron_schedule
|
cron_schedule = local.gitea_files_backup_cron_schedule
|
||||||
@@ -46,9 +46,9 @@ module "sftpgo_backup" {
|
|||||||
|
|
||||||
scaleway_organization_id = var.scaleway_organization_id
|
scaleway_organization_id = var.scaleway_organization_id
|
||||||
scaleway_project_id = var.scaleway_organization_id
|
scaleway_project_id = var.scaleway_organization_id
|
||||||
access_key = scaleway_iam_api_key.backup_app_api.access_key
|
access_key = local.backup_app_api_access_key
|
||||||
secret_key = scaleway_iam_api_key.backup_app_api.secret_key
|
secret_key = local.backup_app_api_secret_key
|
||||||
bucket_name = scaleway_object_bucket.backup.name
|
bucket_name = local.backup_bucket_name
|
||||||
|
|
||||||
retention_days = local.local_backup_retention_days
|
retention_days = local.local_backup_retention_days
|
||||||
cron_schedule = local.sftpgo_files_backup_cron_schedule
|
cron_schedule = local.sftpgo_files_backup_cron_schedule
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -44,7 +44,6 @@ locals {
|
|||||||
|
|
||||||
# backup
|
# backup
|
||||||
local_backup_retention_days = 2
|
local_backup_retention_days = 2
|
||||||
cloud_backup_retention_days = 3
|
|
||||||
mail_backup_path = "${local.persistent_folder}/backup.mail"
|
mail_backup_path = "${local.persistent_folder}/backup.mail"
|
||||||
gitea_backup_path = "${local.persistent_folder}/backup.gitea"
|
gitea_backup_path = "${local.persistent_folder}/backup.gitea"
|
||||||
sftpgo_backup_path = "${local.persistent_folder}/backup.sftpgo"
|
sftpgo_backup_path = "${local.persistent_folder}/backup.sftpgo"
|
||||||
@@ -108,43 +107,47 @@ locals {
|
|||||||
"Connection" = "upgrade"
|
"Connection" = "upgrade"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
# {
|
|
||||||
# private = true
|
|
||||||
# path = "/tools/gitea"
|
|
||||||
# upstream = "http://10.19.4.136:8000"
|
|
||||||
# rewrite = "^/tools/gitea/(.*)$ /$1 break"
|
|
||||||
# },
|
|
||||||
{
|
{
|
||||||
path = "/"
|
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 = "/"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backup_bucket_name = data.terraform_remote_state.scaleway.outputs.backup_bucket_name
|
||||||
# VPS configuration
|
backup_app_api_secret_key = data.terraform_remote_state.scaleway.outputs.backup_app_api_secret_key
|
||||||
instance_ips = [
|
backup_app_api_access_key = data.terraform_remote_state.scaleway.outputs.backup_app_api_access_key
|
||||||
"${local.vps_1.ip}/32",
|
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
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data "scaleway_account_project" "default" {
|
data "terraform_remote_state" "scaleway" {
|
||||||
project_id = var.scaleway_project_id
|
|
||||||
organization_id = var.scaleway_organization_id
|
|
||||||
}
|
|
||||||
|
|
||||||
data "terraform_remote_state" "contabo" {
|
|
||||||
backend = "s3"
|
backend = "s3"
|
||||||
config = {
|
config = {
|
||||||
bucket = "a13labs.infra.eu"
|
bucket = "a13labs.infra.eu"
|
||||||
key = "contabo.core.infra.tfstate"
|
key = "scaleway.core.infra.tfstate"
|
||||||
region = "eu-west-1"
|
region = "eu-west-1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ terraform {
|
|||||||
source = "hashicorp/kubernetes"
|
source = "hashicorp/kubernetes"
|
||||||
version = "2.36.0"
|
version = "2.36.0"
|
||||||
}
|
}
|
||||||
scaleway = {
|
|
||||||
source = "scaleway/scaleway"
|
|
||||||
version = "~>2.13"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,11 +30,4 @@ provider "kubernetes" {
|
|||||||
insecure = true
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -11,18 +11,6 @@ variable "gitea_mysql_password" {
|
|||||||
sensitive = true
|
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" {
|
variable "wireguard_private_key" {
|
||||||
description = "Wireguard public key"
|
description = "Wireguard public key"
|
||||||
type = string
|
type = string
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY
|
||||||
AWS_SECRET_ACCESS_KEY=$AWS_SECRET_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_project_id=$SCALEWAY_PROJECT_ID
|
||||||
TF_VAR_scaleway_user_id=$SCALEWAY_USER_ID
|
|
||||||
TF_VAR_scaleway_organization_id=$SCALEWAY_ORGANIZATION_ID
|
TF_VAR_scaleway_organization_id=$SCALEWAY_ORGANIZATION_ID
|
||||||
TF_VAR_mysql_root_password=$MYSQL_ROOT_PASSWORD
|
TF_VAR_mysql_root_password=$MYSQL_ROOT_PASSWORD
|
||||||
TF_VAR_wordpress_mysql_password=$MYSQL_WORDPRESS_PASSWORD
|
TF_VAR_wordpress_mysql_password=$MYSQL_WORDPRESS_PASSWORD
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
variable "scaleway_user_id" {
|
|
||||||
description = "Scaleway User Id"
|
|
||||||
type = string
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "scaleway_project_id" {
|
variable "scaleway_project_id" {
|
||||||
description = "Scaleway Project Id"
|
description = "Scaleway Project Id"
|
||||||
type = string
|
type = string
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ locals {
|
|||||||
"${local.vps_1.ip}/32",
|
"${local.vps_1.ip}/32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
cloud_backup_retention_days = 3
|
||||||
|
|
||||||
vps_1 = {
|
vps_1 = {
|
||||||
id = data.terraform_remote_state.contabo.outputs.instances[0].id
|
id = data.terraform_remote_state.contabo.outputs.instances[0].id
|
||||||
name = data.terraform_remote_state.contabo.outputs.instances[0].name
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,14 +2,6 @@ resource "scaleway_iam_application" "backup_app" {
|
|||||||
name = "k8s_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" {
|
resource "scaleway_iam_policy" "object_read_write_backup" {
|
||||||
name = "K8s backup app policy"
|
name = "K8s backup app policy"
|
||||||
description = "Gives k8s backup job access to object storage in project"
|
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" {
|
resource "scaleway_iam_policy" "email_full_access" {
|
||||||
name = "Email full access policy"
|
name = "Email full access policy"
|
||||||
description = "Gives access to transactional email in project"
|
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" {
|
resource "scaleway_iam_policy" "object_read_write_sftpgo" {
|
||||||
name = "SFtpGo app policy"
|
name = "SFtpGo app policy"
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
locals {
|
locals {
|
||||||
configfile = templatefile("${path.module}/resources/Corefile.tpl", {
|
configfile = templatefile("${path.module}/resources/Corefile.tpl", {
|
||||||
zones = var.zones
|
zones = var.zones
|
||||||
|
override_hosts = length(var.override_hosts) > 0
|
||||||
|
hosts = var.override_hosts
|
||||||
forward_dns_servers = join(" ", var.forward_dns_servers)
|
forward_dns_servers = join(" ", var.forward_dns_servers)
|
||||||
})
|
})
|
||||||
configfile_checksum = md5(local.configfile)
|
configfile_checksum = md5(local.configfile)
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
.:53 {
|
.:53 {
|
||||||
|
%{ if override_hosts ~}
|
||||||
|
hosts {
|
||||||
|
%{ for h in hosts ~}
|
||||||
|
${h.ip} ${h.name}
|
||||||
|
%{ endfor ~}
|
||||||
|
fallthrough
|
||||||
|
}
|
||||||
|
%{ endif ~}
|
||||||
errors
|
errors
|
||||||
health {
|
health {
|
||||||
lameduck 5s
|
lameduck 5s
|
||||||
|
|||||||
@@ -10,6 +10,15 @@ variable "forward_dns_servers" {
|
|||||||
default = ["8.8.8.8", "8.8.4.4"]
|
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" {
|
variable "zones" {
|
||||||
description = "Zones to be managed by coredns"
|
description = "Zones to be managed by coredns"
|
||||||
type = list(object({
|
type = list(object({
|
||||||
|
|||||||
@@ -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))
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
output "namespace" {
|
||||||
|
description = "value of namespace"
|
||||||
|
value = kubernetes_namespace.nextcloud.metadata[0].name
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = "~>1.8"
|
||||||
|
required_providers {
|
||||||
|
kubernetes = {
|
||||||
|
source = "hashicorp/kubernetes"
|
||||||
|
version = "2.36.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<IfModule mod_deflate.c>
|
||||||
|
# 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
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Do not compress images
|
||||||
|
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|woff|woff2)$ no-gzip
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
MaxRequestWorkers 10
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<VirtualHost *:443>
|
||||||
|
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
|
||||||
|
</VirtualHost>
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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")
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -136,12 +136,14 @@ resource "kubernetes_ingress_v1" "reverse-proxy_ingress" {
|
|||||||
"kubernetes.io/ingress.class" = "public"
|
"kubernetes.io/ingress.class" = "public"
|
||||||
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
|
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
|
||||||
},
|
},
|
||||||
|
each.value.custom_ingress_annotations,
|
||||||
each.value.tls ? {
|
each.value.tls ? {
|
||||||
"nginx.org/ssl-services" = format("reverse-proxy-%s", replace(each.key, ".", "-"))
|
"nginx.org/ssl-services" = format("reverse-proxy-%s", replace(each.key, ".", "-"))
|
||||||
"nginx.org/ssl-redirect" = "true"
|
"nginx.org/ssl-redirect" = "true"
|
||||||
"nginx.org/redirect-to-https" = "true"
|
"nginx.org/redirect-to-https" = "true"
|
||||||
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTPS"
|
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTPS"
|
||||||
} : {})
|
} : {}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
spec {
|
spec {
|
||||||
tls {
|
tls {
|
||||||
|
|||||||
@@ -29,13 +29,15 @@ variable "issuer_name" {
|
|||||||
variable "services" {
|
variable "services" {
|
||||||
description = "A list of services to be deployed"
|
description = "A list of services to be deployed"
|
||||||
type = map(object({
|
type = map(object({
|
||||||
fqdn = list(string)
|
fqdn = list(string)
|
||||||
upstream = optional(string, "")
|
custom_ingress_annotations = optional(map(string), {})
|
||||||
resolver = optional(string, "")
|
annotations = optional(map(string), {})
|
||||||
default_headers = optional(map(string), {}),
|
upstream = optional(string, "")
|
||||||
http_port = optional(number, 80)
|
resolver = optional(string, "")
|
||||||
https_port = optional(number, 443)
|
default_headers = optional(map(string), {}),
|
||||||
tls = optional(bool, false)
|
http_port = optional(number, 80)
|
||||||
|
https_port = optional(number, 443)
|
||||||
|
tls = optional(bool, false)
|
||||||
locations = optional(list(object({
|
locations = optional(list(object({
|
||||||
path = string,
|
path = string,
|
||||||
headers = optional(map(string), {}),
|
headers = optional(map(string), {}),
|
||||||
|
|||||||
@@ -13,3 +13,7 @@ output "root_crendentials_name" {
|
|||||||
output "app_crendentials_name" {
|
output "app_crendentials_name" {
|
||||||
value = kubernetes_secret.app_password.metadata[0].name
|
value = kubernetes_secret.app_password.metadata[0].name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "db_name" {
|
||||||
|
value = var.app_name
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user