Add(module): add girasol module
Add(module): add amap module Add(module): add common lib and services Add(module): add base structure for keycloak Add(module): add base structure for rocket Add(module): add n8n and windmill modules Add(docker): add install docker script in common module Add(template): add root for aldon.fr and mathieu.wiki in traefik.service template
This commit is contained in:
76
main.tf
76
main.tf
@@ -24,6 +24,7 @@ locals {
|
||||
gitea = module.gitea.traefik_service
|
||||
fefan = module.fefan.traefik_service
|
||||
listmonk = module.listmonk.traefik_service
|
||||
amap = module.amap.traefik_service
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,16 +178,87 @@ module "listmonk" {
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
}
|
||||
|
||||
module "amap" {
|
||||
source = "./modules/apps/amap"
|
||||
providers = {}
|
||||
vm_ip_address = "192.168.1.96"
|
||||
depends_on = [
|
||||
module.gitea
|
||||
]
|
||||
|
||||
name = "amap"
|
||||
hostname = "amap"
|
||||
domain = "aldon.fr"
|
||||
vm_id = 217
|
||||
node_name = "mop"
|
||||
|
||||
template_id = 103
|
||||
|
||||
cores = 1
|
||||
memory = 1024
|
||||
balloon = 1024
|
||||
disk_size = 16
|
||||
|
||||
ssh_public_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
}
|
||||
|
||||
# module "n8n" {
|
||||
# source = "./modules/apps/n8n"
|
||||
# providers = {}
|
||||
# vm_ip_address = "192.168.1.94"
|
||||
# depends_on = []
|
||||
|
||||
# name = "n8n"
|
||||
# hostname = "n8n"
|
||||
# domain = "mathieu.wiki"
|
||||
# vm_id = 215
|
||||
# node_name = "mop"
|
||||
|
||||
# template_id = 103
|
||||
|
||||
# cores = 1
|
||||
# memory = 1024
|
||||
# balloon = 512
|
||||
# disk_size = 16
|
||||
|
||||
# ssh_public_key = var.ssh_public_key
|
||||
# proxmox_host_ip = var.proxmox_host_ip
|
||||
# }
|
||||
|
||||
# module "windmill" {
|
||||
# source = "./modules/apps/windmill"
|
||||
# providers = {}
|
||||
# vm_ip_address = "192.168.1.94"
|
||||
# depends_on = []
|
||||
|
||||
# name = "windmill"
|
||||
# hostname = "windmill"
|
||||
# domain = "aldon.fr"
|
||||
# vm_id = 215
|
||||
# node_name = "mop"
|
||||
|
||||
# template_id = 103
|
||||
|
||||
# cores = 1
|
||||
# memory = 2048
|
||||
# balloon = 1024
|
||||
# disk_size = 16
|
||||
|
||||
# ssh_public_key = var.ssh_public_key
|
||||
# proxmox_host_ip = var.proxmox_host_ip
|
||||
# }
|
||||
|
||||
# module "keycloak" {
|
||||
# source = "./modules/apps/keycloak"
|
||||
# providers = {}
|
||||
# vm_ip_address = "192.168.1.94"
|
||||
# vm_ip_address = "192.168.1.95"
|
||||
# depends_on = []
|
||||
|
||||
# name = "keycloak"
|
||||
# hostname = "keycloak"
|
||||
# domain = "aldon.fr"
|
||||
# vm_id = 215
|
||||
# vm_id = 216
|
||||
# node_name = "mop"
|
||||
|
||||
# template_id = 103
|
||||
|
||||
36
modules/apps/amap/.env.example
Normal file
36
modules/apps/amap/.env.example
Normal file
@@ -0,0 +1,36 @@
|
||||
# Environment files
|
||||
ENV_FILE_LOCATION=/opt/environment/.env
|
||||
|
||||
# gitea act_runner
|
||||
ACT_RUNNER_VERSION=0.2.13
|
||||
ACT_RUNNER_LOCATION=/usr/local/bin
|
||||
ACT_RUNNER_USER=act_runner
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN=<gitea-repository-runner-token>
|
||||
USERNAME=amap
|
||||
|
||||
# gitea instance
|
||||
GITEA_INSTANCE_URL=https://gitea.aldon.fr
|
||||
GITEA_SERVICE_APPLICATION_TOKEN=<gitea-auth-token>
|
||||
GITEA_SERVICE_REPOSITORY=mop/amap
|
||||
GITEA_WORKFLOW_NAME=deploy.yaml
|
||||
|
||||
# Applicaiton specifics
|
||||
DB_USER=postgres
|
||||
DB_PASS=
|
||||
DB_NAME=amap
|
||||
DB_HOST=localhost
|
||||
ORIGINS=https://amap.aldon.fr
|
||||
SECRET_KEY=
|
||||
VITE_API_URL=https://amap.aldon.fr/api
|
||||
KEYCLOAK_SERVER=https://keycloak.aldon.fr
|
||||
KEYCLOAK_REALM=aldon.fr
|
||||
KEYCLOAK_CLIENT_ID=
|
||||
KEYCLOAK_CLIENT_SECRET=
|
||||
KEYCLOAK_REDIRECT_URI=https://amap.aldon.fr/api/auth/callback
|
||||
MAX_AGE=3600
|
||||
DEBUG=True
|
||||
|
||||
# Backup specifics
|
||||
SERVICE_BACKUPS_DIR=/backups/amap
|
||||
SERVICE_BACKUPS_PREFIX=amap-dump
|
||||
SERVICE_BACKUPS_EXTENSION=sql
|
||||
90
modules/apps/amap/cloud-init/service.yaml
Normal file
90
modules/apps/amap/cloud-init/service.yaml
Normal file
@@ -0,0 +1,90 @@
|
||||
#cloud-config
|
||||
hostname: ${hostname}
|
||||
local-hostname: ${hostname}
|
||||
fqdn: ${hostname}.${domain}
|
||||
manage_etc_hosts: true
|
||||
|
||||
users:
|
||||
- default
|
||||
- name: ${hostname}
|
||||
groups: sudo
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
ssh_authorized_keys:
|
||||
- ${ssh_key}
|
||||
|
||||
disable_root: true
|
||||
|
||||
package_update: true
|
||||
package_upgrade: false
|
||||
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- curl
|
||||
- jq
|
||||
- postgresql-client
|
||||
|
||||
mounts:
|
||||
- [ "192.168.1.12:/main/backups", "/backups", "nfs", "defaults,_netdev,x-systemd.requires=network-online.target", "0", "0" ]
|
||||
|
||||
write_files:
|
||||
- path: /opt/environment/.env
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /opt/${hostname}/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${restore-backup-script}
|
||||
- path: /etc/systemd/system/restore-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${restore-backup-service}
|
||||
- path: /usr/local/bin/backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${create-backup-script}
|
||||
- path: /etc/systemd/system/create-backup.timer
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-timer}
|
||||
- path: /etc/systemd/system/create-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-service}
|
||||
- path: /etc/systemd/system/act_runner.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${act_runner-service}
|
||||
- path: /opt/${hostname}/install-runner.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${act_runner-install-script}
|
||||
- path: /opt/${hostname}/install-service.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${service-install-script}
|
||||
|
||||
runcmd:
|
||||
# Backup setup
|
||||
- mkdir -p /backups
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Docker setup
|
||||
- /opt/${hostname}/install-docker.sh
|
||||
# Act_runner install
|
||||
- /opt/${hostname}/install-runner.sh
|
||||
- systemctl daemon-reload
|
||||
- systemctl enable act_runner.service
|
||||
- systemctl start act_runner.service
|
||||
# ${hostname} install
|
||||
- /opt/${hostname}/install-service.sh
|
||||
|
||||
|
||||
final_message: |
|
||||
Base system ready for ${hostname}
|
||||
10
modules/apps/amap/lib/scripts/create-backup.sh
Normal file
10
modules/apps/amap/lib/scripts/create-backup.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
TIMESTAMP=$(date +'%Y-%m-%d_%H%M%S')
|
||||
|
||||
sudo -u $USERNAME docker exec -i amap-database-1 pg_dump -F c -U $DB_USER -d $DB_NAME > $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-$TIMESTAMP.$SERVICE_BACKUPS_EXTENSION
|
||||
|
||||
ls -1dt $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION | tail -n +5 | xargs -r rm -f
|
||||
10
modules/apps/amap/lib/scripts/restore-backup.sh
Normal file
10
modules/apps/amap/lib/scripts/restore-backup.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
LATEST_BACKUP=$(ls -1 $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION 2>/dev/null | sort | tail -n1)
|
||||
|
||||
if [ -n "$LATEST_BACKUP" ] && [ -f "$LATEST_BACKUP" ]; then
|
||||
sudo -u $USERNAME docker exec -i amap-database-1 pg_restore --clean --if-exists -U "$DB_USER" -v -d "$DB_NAME" < $LATEST_BACKUP
|
||||
fi
|
||||
0
modules/apps/amap/lib/services/.gitkeep
Normal file
0
modules/apps/amap/lib/services/.gitkeep
Normal file
41
modules/apps/amap/main.tf
Normal file
41
modules/apps/amap/main.tf
Normal file
@@ -0,0 +1,41 @@
|
||||
module "vm" {
|
||||
source = "../../vm"
|
||||
name = var.name
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
vm_id = var.vm_id
|
||||
node_name = var.node_name
|
||||
vm_ip_address = var.vm_ip_address
|
||||
|
||||
template_id = var.template_id
|
||||
|
||||
cores = var.cores
|
||||
memory = var.memory
|
||||
disk_size = var.disk_size
|
||||
|
||||
ssh_public_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
|
||||
cloudinit_config = templatefile(
|
||||
"${path.module}/cloud-init/service.yaml",
|
||||
{
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
ssh_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
restore-backup-script = indent(6, file("${path.module}/lib/scripts/restore-backup.sh"))
|
||||
restore-backup-service = indent(6, file("${path.module}/../common/services/docker/restore-backup.service"))
|
||||
create-backup-script = indent(6, file("${path.module}/lib/scripts/create-backup.sh"))
|
||||
create-backup-service = indent(6, file("${path.module}}/../common/services/docker/create-backup.service"))
|
||||
create-backup-timer = indent(6, file("${path.module}/../common/services/create-backup.timer"))
|
||||
|
||||
act_runner-service = indent(6, file("${path.module}/../common/services/act_runner.service"))
|
||||
act_runner-install-script = indent(6, file("${path.module}/../common/scripts/install-runner.sh"))
|
||||
|
||||
service-install-script = indent(6, file("${path.module}/../common/scripts/install-service-ci.sh"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
)
|
||||
}
|
||||
9
modules/apps/amap/output.tf
Normal file
9
modules/apps/amap/output.tf
Normal file
@@ -0,0 +1,9 @@
|
||||
output "traefik_service" {
|
||||
value = [{
|
||||
domain = var.domain
|
||||
name = var.name
|
||||
host = "${var.hostname}"
|
||||
ip = var.vm_ip_address
|
||||
port = 80
|
||||
}]
|
||||
}
|
||||
71
modules/apps/amap/variables.tf
Normal file
71
modules/apps/amap/variables.tf
Normal file
@@ -0,0 +1,71 @@
|
||||
variable "name" {
|
||||
description = "Virtual Machine name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_id" {
|
||||
description = "Virtual Machine id"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "node_name" {
|
||||
description = "Proxmox node name"
|
||||
type = string
|
||||
default = "mop"
|
||||
}
|
||||
|
||||
variable "cores" {
|
||||
description = "Number of CPU cores for this virtual machine"
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "memory" {
|
||||
description = "Memory RAM for this virtual machine"
|
||||
type = number
|
||||
default = 2048
|
||||
}
|
||||
|
||||
variable "balloon" {
|
||||
description = "Minimum vm memory, using ballooning devide to reach Proxmox node memory target."
|
||||
type = number
|
||||
default = 1024
|
||||
}
|
||||
|
||||
variable "template_id" {
|
||||
description = "Virtual machine template ID"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
description = "Public SSH key for cloud-init user"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "hostname" {
|
||||
description = "Virtual Machine hostname (<service-name>)"
|
||||
type = string
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
description = "Virtual Machine domain (example.fr)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
description = "Disk size for the virtual machine"
|
||||
type = number
|
||||
default = 10
|
||||
}
|
||||
|
||||
variable "proxmox_host_ip" {
|
||||
description = "Proxmox host base ip"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_ip_address" {
|
||||
description = "Virtual machine ip"
|
||||
type = string
|
||||
}
|
||||
@@ -21,8 +21,6 @@ package_upgrade: false
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- docker.io
|
||||
- docker-compose
|
||||
- curl
|
||||
- jq
|
||||
|
||||
@@ -34,6 +32,10 @@ write_files:
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /opt/${hostname}/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
@@ -73,9 +75,7 @@ runcmd:
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Docker setup
|
||||
- systemctl enable docker
|
||||
- systemctl start docker
|
||||
- usermod -aG docker ${hostname}
|
||||
- /opt/${hostname}/install-docker.sh
|
||||
# Act_runner install
|
||||
- /opt/${hostname}/install-runner.sh
|
||||
- systemctl daemon-reload
|
||||
|
||||
@@ -33,6 +33,7 @@ module "vm" {
|
||||
act_runner-install-script = indent(6, file("${path.module}/../common/scripts/install-runner.sh"))
|
||||
|
||||
service-install-script = indent(6, file("${path.module}/../common/scripts/install-service-ci.sh"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
|
||||
23
modules/apps/common/scripts/install-docker.sh
Normal file
23
modules/apps/common/scripts/install-docker.sh
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
sudo apt update -y
|
||||
sudo install -m 0755 -d /etc/apt/keyrings
|
||||
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
|
||||
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||||
|
||||
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
|
||||
Types: deb
|
||||
URIs: https://download.docker.com/linux/debian
|
||||
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
|
||||
Components: stable
|
||||
Signed-By: /etc/apt/keyrings/docker.asc
|
||||
EOF
|
||||
|
||||
sudo apt update -y
|
||||
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
usermod -aG docker $HOSTNAME
|
||||
@@ -21,8 +21,6 @@ package_upgrade: false
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- docker.io
|
||||
- docker-compose
|
||||
- curl
|
||||
- jq
|
||||
|
||||
@@ -34,6 +32,10 @@ write_files:
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /opt/${hostname}/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
@@ -73,9 +75,7 @@ runcmd:
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Docker setup
|
||||
- systemctl enable docker
|
||||
- systemctl start docker
|
||||
- usermod -aG docker ${hostname}
|
||||
- /opt/${hostname}/install-docker.sh
|
||||
# Act_runner install
|
||||
- /opt/${hostname}/install-runner.sh
|
||||
- systemctl daemon-reload
|
||||
|
||||
@@ -33,6 +33,7 @@ module "vm" {
|
||||
act_runner-install-script = indent(6, file("${path.module}/../common/scripts/install-runner.sh"))
|
||||
|
||||
service-install-script = indent(6, file("${path.module}/../common/scripts/install-service-ci.sh"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Environment files
|
||||
ENV_FILE_LOCATION=/opt/environment/.env
|
||||
USERNAME=gateway
|
||||
|
||||
# Application Specifics
|
||||
#openssl rand -hex 20
|
||||
@@ -8,4 +9,9 @@ TRAEFIK_BINARY=/usr/local/bin/traefik
|
||||
TRAEFIK_USER=traefik
|
||||
TRAEFIK_CONF=/home/traefik/traefik.yml
|
||||
GATEWAY_REPOSITORY=/Mop/gateway
|
||||
DYNAMIC_CONFIG_LOCATION=/home/gateway/services.yaml
|
||||
DYNAMIC_CONFIG_LOCATION=/home/gateway/services.yaml
|
||||
|
||||
# Backup specifics
|
||||
SERVICE_BACKUPS_DIR=/backups/gateway
|
||||
SERVICE_BACKUPS_PREFIX=gateway-dump
|
||||
SERVICE_BACKUPS_EXTENSION=db
|
||||
@@ -24,6 +24,9 @@ packages:
|
||||
- curl
|
||||
- nginx
|
||||
|
||||
mounts:
|
||||
- [ "192.168.1.12:/main/backups", "/backups", "nfs", "defaults,_netdev,x-systemd.requires=network-online.target", "0", "0" ]
|
||||
|
||||
write_files:
|
||||
- path: /opt/environment/.env
|
||||
permissions: "0644"
|
||||
@@ -33,6 +36,14 @@ write_files:
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-traefik-script}
|
||||
- path: /opt/gateway/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /opt/gateway/install-crowdsec.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-crowdsec-script}
|
||||
- path: /etc/systemd/system/traefik.service
|
||||
permissions: "0755"
|
||||
content: |
|
||||
@@ -40,15 +51,47 @@ write_files:
|
||||
- path: /usr/share/nginx/error-pages/502.html
|
||||
permissions: "0644"
|
||||
content: |
|
||||
{nginx-error-502}
|
||||
${nginx-error-502}
|
||||
- path: /etc/nginx/sites-available/default
|
||||
permissions: "0644"
|
||||
content: |
|
||||
{nginx-error-configuration}
|
||||
${nginx-error-configuration}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${restore-backup-script}
|
||||
- path: /etc/systemd/system/restore-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${restore-backup-service}
|
||||
- path: /usr/local/bin/backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${create-backup-script}
|
||||
- path: /etc/systemd/system/create-backup.timer
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-timer}
|
||||
- path: /etc/systemd/system/create-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-service}
|
||||
|
||||
bootcmd:
|
||||
- hostnamectl set-hostname ${hostname}
|
||||
|
||||
runcmd:
|
||||
# Backup setup
|
||||
- mkdir -p /backups
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Crowdsec / Terraform setup
|
||||
- /opt/gateway/install-docker.sh
|
||||
- /opt/gateway/install-crowdsec.sh
|
||||
- /opt/gateway/install-traefik.sh
|
||||
- ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled
|
||||
- systemctl start nginx.service
|
||||
- systemctl start restore-backup
|
||||
|
||||
final_message: |
|
||||
Base system ready for ${hostname}
|
||||
10
modules/apps/gateway/lib/scripts/create-backup.sh
Normal file
10
modules/apps/gateway/lib/scripts/create-backup.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
TIMESTAMP=$(date +'%Y-%m-%d_%H%M%S')
|
||||
|
||||
sudo -u $USERNAME docker cp crowdsec-metabase:/metabase-data/metabase.db/metabase.db.mv.db $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-$TIMESTAMP.$SERVICE_BACKUPS_EXTENSION
|
||||
|
||||
ls -1dt $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION | tail -n +5 | xargs -r rm -f
|
||||
17
modules/apps/gateway/lib/scripts/install-crowdsec.sh
Normal file
17
modules/apps/gateway/lib/scripts/install-crowdsec.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
set -e
|
||||
|
||||
sudo apt update
|
||||
sudo apt install -y curl gnupg lsb-release
|
||||
|
||||
sudo apt install crowdsec
|
||||
sudo cscli collections install crowdsecurity/traefik
|
||||
sudo cscli collections install crowdsecurity/http-cve
|
||||
sudo cscli collections install crowdsecurity/base-http-scenarios
|
||||
sudo cscli parsers install crowdsecurity/geoip-enrich
|
||||
|
||||
sudo systemctl enable crowdsec
|
||||
sudo systemctl restart crowdsec
|
||||
|
||||
sudo cscli hub update
|
||||
|
||||
cscli dashboard setup -l 0.0.0.0
|
||||
@@ -32,6 +32,10 @@ chown $TRAEFIK_USER:$TRAEFIK_USER /etc/traefik/acme.json
|
||||
chmod 600 /etc/traefik/acme.json
|
||||
setcap 'cap_net_bind_service=+ep' /usr/local/bin/traefik
|
||||
|
||||
sudo mkdir -p /var/log/traefik
|
||||
sudo touch /var/log/traefik/access.log
|
||||
sudo chown -R traefik:adm /var/log/traefik
|
||||
|
||||
cat > "$TRAEFIK_CONF" <<EOF
|
||||
entryPoints:
|
||||
web:
|
||||
@@ -47,7 +51,9 @@ api:
|
||||
insecure: false
|
||||
log:
|
||||
level: INFO
|
||||
accessLog: {}
|
||||
accessLog:
|
||||
filePath: "/var/log/traefik/access.log"
|
||||
bufferingSize: 100
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
@@ -58,4 +64,4 @@ certificatesResolvers:
|
||||
EOF
|
||||
|
||||
systemctl enable traefik.service
|
||||
systemctl start traefik.service
|
||||
systemctl start traefik.service
|
||||
10
modules/apps/gateway/lib/scripts/restore-backup.sh
Normal file
10
modules/apps/gateway/lib/scripts/restore-backup.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
LATEST_BACKUP=$(ls -1 $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION 2>/dev/null | sort | tail -n1)
|
||||
|
||||
if [ -n "$LATEST_BACKUP" ] && [ -f "$LATEST_BACKUP" ]; then
|
||||
sudo -u $USERNAME docker cp "$LATEST_BACKUP" "crowdsec-metabase:/metabase-data/metabase.db/metabase.db.mv.db"
|
||||
fi
|
||||
@@ -22,9 +22,16 @@ module "vm" {
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
ssh_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
traefik-service = indent(6, file("${path.module}/lib/services/traefik.service"))
|
||||
install-traefik-script = indent(6, file("${path.module}/lib/scripts/install-traefik.sh"))
|
||||
install-crowdsec-script = indent(6, file("${path.module}/lib/scripts/install-crowdsec.sh"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
restore-backup-script = indent(6, file("${path.module}/lib/scripts/restore-backup.sh"))
|
||||
restore-backup-service = indent(6, file("${path.module}/../common/services/docker/restore-backup.service"))
|
||||
create-backup-script = indent(6, file("${path.module}/lib/scripts/create-backup.sh"))
|
||||
create-backup-service = indent(6, file("${path.module}}/../common/services/docker/create-backup.service"))
|
||||
create-backup-timer = indent(6, file("${path.module}}/../common/services/create-backup.timer"))
|
||||
nginx-error-configuration = indent(6, file("${path.module}/lib/scripts/default"))
|
||||
nginx-error-502 = indent(6, file("${path.module}/lib/scripts/502.html"))
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
|
||||
22
modules/apps/girasol/.env.example
Normal file
22
modules/apps/girasol/.env.example
Normal file
@@ -0,0 +1,22 @@
|
||||
# Environment files
|
||||
ENV_FILE_LOCATION=/opt/environment/.env
|
||||
|
||||
# gitea act_runner
|
||||
ACT_RUNNER_VERSION=0.2.13
|
||||
ACT_RUNNER_LOCATION=/usr/local/bin
|
||||
ACT_RUNNER_USER=act_runner
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN=<gitea-repository-runner-token>
|
||||
USERNAME=girasol
|
||||
|
||||
# Gitea instance
|
||||
GITEA_INSTANCE_URL=https://gitea.aldon.fr
|
||||
GITEA_SERVICE_APPLICATION_TOKEN=<gitea-auth-token>
|
||||
GITEA_SERVICE_REPOSITORY=mop/girasol
|
||||
GITEA_WORKFLOW_NAME=deploy.yaml
|
||||
|
||||
# Application specifics
|
||||
|
||||
# Backup specifics
|
||||
SERVICE_BACKUPS_DIR=/backups/girasol
|
||||
SERVICE_BACKUPS_PREFIX=girasol-dump
|
||||
SERVICE_BACKUPS_EXTENSION=sql
|
||||
89
modules/apps/girasol/cloud-init/service.yaml
Normal file
89
modules/apps/girasol/cloud-init/service.yaml
Normal file
@@ -0,0 +1,89 @@
|
||||
#cloud-config
|
||||
hostname: ${hostname}
|
||||
local-hostname: ${hostname}
|
||||
fqdn: ${hostname}.${domain}
|
||||
manage_etc_hosts: true
|
||||
|
||||
users:
|
||||
- default
|
||||
- name: ${hostname}
|
||||
groups: sudo
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
ssh_authorized_keys:
|
||||
- ${ssh_key}
|
||||
|
||||
disable_root: true
|
||||
|
||||
package_update: true
|
||||
package_upgrade: false
|
||||
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- curl
|
||||
- jq
|
||||
|
||||
mounts:
|
||||
- [ "192.168.1.12:/main/backups", "/backups", "nfs", "defaults,_netdev,x-systemd.requires=network-online.target", "0", "0" ]
|
||||
|
||||
write_files:
|
||||
- path: /opt/environment/.env
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /opt/${hostname}/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${restore-backup-script}
|
||||
- path: /etc/systemd/system/restore-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${restore-backup-service}
|
||||
- path: /usr/local/bin/backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${create-backup-script}
|
||||
- path: /etc/systemd/system/create-backup.timer
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-timer}
|
||||
- path: /etc/systemd/system/create-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-service}
|
||||
- path: /etc/systemd/system/act_runner.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${act_runner-service}
|
||||
- path: /opt/${hostname}/install-runner.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${act_runner-install-script}
|
||||
- path: /opt/${hostname}/install-service.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${service-install-script}
|
||||
|
||||
runcmd:
|
||||
# Backup setup
|
||||
- mkdir -p /backups
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Docker setup
|
||||
- /opt/${hostname}/install-docker.sh
|
||||
# Act_runner install
|
||||
- /opt/${hostname}/install-runner.sh
|
||||
- systemctl daemon-reload
|
||||
- systemctl enable act_runner.service
|
||||
- systemctl start act_runner.service
|
||||
# ${hostname} install
|
||||
- /opt/${hostname}/install-service.sh
|
||||
|
||||
|
||||
final_message: |
|
||||
Base system ready for ${hostname}
|
||||
7
modules/apps/girasol/lib/create-backup.sh
Normal file
7
modules/apps/girasol/lib/create-backup.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
source /opt/environment/.env
|
||||
|
||||
TIMESTAMP=$(date +'%Y-%m-%d_%H%M%S')
|
||||
|
||||
# create backup file
|
||||
|
||||
ls -1dt $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION | tail -n +5 | xargs -r rm -f
|
||||
5
modules/apps/girasol/lib/restore-backup.sh
Normal file
5
modules/apps/girasol/lib/restore-backup.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
source /opt/environment/.env
|
||||
|
||||
LATEST_BACKUP=$(ls -1 $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION 2>/dev/null | sort | tail -n1)
|
||||
|
||||
# Restore backup file
|
||||
41
modules/apps/girasol/main.tf
Normal file
41
modules/apps/girasol/main.tf
Normal file
@@ -0,0 +1,41 @@
|
||||
module "vm" {
|
||||
source = "../../vm"
|
||||
name = var.name
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
vm_id = var.vm_id
|
||||
node_name = var.node_name
|
||||
vm_ip_address = var.vm_ip_address
|
||||
|
||||
template_id = var.template_id
|
||||
|
||||
cores = var.cores
|
||||
memory = var.memory
|
||||
disk_size = var.disk_size
|
||||
|
||||
ssh_public_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
|
||||
cloudinit_config = templatefile(
|
||||
"${path.module}/cloud-init/service.yaml",
|
||||
{
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
ssh_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
restore-backup-script = indent(6, file("${path.module}/lib/scripts/restore-backup.sh"))
|
||||
restore-backup-service = indent(6, file("${path.module}/../common/services/docker/restore-backup.service"))
|
||||
create-backup-script = indent(6, file("${path.module}/lib/scripts/create-backup.sh"))
|
||||
create-backup-service = indent(6, file("${path.module}}/../common/services/docker/create-backup.service"))
|
||||
create-backup-timer = indent(6, file("${path.module}/../common/services/create-backup.timer"))
|
||||
|
||||
act_runner-service = indent(6, file("${path.module}/../common/services/act_runner.service"))
|
||||
act_runner-install-script = indent(6, file("${path.module}/../common/scripts/install-runner.sh"))
|
||||
|
||||
service-install-script = indent(6, file("${path.module}/../common/scripts/install-service-ci.sh"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
)
|
||||
}
|
||||
9
modules/apps/girasol/output.tf
Normal file
9
modules/apps/girasol/output.tf
Normal file
@@ -0,0 +1,9 @@
|
||||
output "traefik_service" {
|
||||
value = [{
|
||||
domain = var.domain
|
||||
name = var.name
|
||||
host = "${var.hostname}"
|
||||
ip = var.vm_ip_address
|
||||
port = 80
|
||||
}]
|
||||
}
|
||||
71
modules/apps/girasol/variables.tf
Normal file
71
modules/apps/girasol/variables.tf
Normal file
@@ -0,0 +1,71 @@
|
||||
variable "name" {
|
||||
description = "Virtual Machine name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_id" {
|
||||
description = "Virtual Machine id"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "node_name" {
|
||||
description = "Proxmox node name"
|
||||
type = string
|
||||
default = "mop"
|
||||
}
|
||||
|
||||
variable "cores" {
|
||||
description = "Number of CPU cores for this virtual machine"
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "memory" {
|
||||
description = "Memory RAM for this virtual machine"
|
||||
type = number
|
||||
default = 2048
|
||||
}
|
||||
|
||||
variable "balloon" {
|
||||
description = "Minimum vm memory, using ballooning devide to reach Proxmox node memory target."
|
||||
type = number
|
||||
default = 1024
|
||||
}
|
||||
|
||||
variable "template_id" {
|
||||
description = "Virtual machine template ID"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
description = "Public SSH key for cloud-init user"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "hostname" {
|
||||
description = "Virtual Machine hostname (<service-name>)"
|
||||
type = string
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
description = "Virtual Machine domain (example.fr)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
description = "Disk size for the virtual machine"
|
||||
type = number
|
||||
default = 10
|
||||
}
|
||||
|
||||
variable "proxmox_host_ip" {
|
||||
description = "Proxmox host base ip"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_ip_address" {
|
||||
description = "Virtual machine ip"
|
||||
type = string
|
||||
}
|
||||
@@ -24,8 +24,6 @@ package_upgrade: false
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- docker.io
|
||||
- docker-compose
|
||||
- curl
|
||||
- unzip
|
||||
- postgresql
|
||||
@@ -39,6 +37,10 @@ write_files:
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /opt/${hostname}/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
@@ -74,9 +76,7 @@ runcmd:
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Docker setup
|
||||
- systemctl enable docker
|
||||
- systemctl start docker
|
||||
- usermod -aG docker ${hostname}
|
||||
- /opt/${hostname}/install-docker.sh
|
||||
# gitea setup
|
||||
- /opt/gitea/install-gitea.sh
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ module "vm" {
|
||||
|
||||
install-gitea-script = indent(6, file("${path.module}/lib/scripts/install-gitea.sh"))
|
||||
gitea-service = indent(6, file("${path.module}/lib/services/gitea.service"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
|
||||
22
modules/apps/keycloak/.env.example
Normal file
22
modules/apps/keycloak/.env.example
Normal file
@@ -0,0 +1,22 @@
|
||||
JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
|
||||
KC_PROXY_HEADERS=forwarded
|
||||
KC_HTTP_ENABLED=true
|
||||
KC_DB=postgres
|
||||
KC_DB_USERNAME=keycloak
|
||||
KC_DB_PASSWORD=<secret>
|
||||
KC_HOSTNAME=https://keycloak.aldon.fr
|
||||
|
||||
#Running behind reverse proxy that handles TLS
|
||||
KC_PROXY=edge
|
||||
|
||||
#Create admin account on first run
|
||||
KEYCLOAK_ADMIN=admin
|
||||
KEYCLOAK_ADMIN_PASSWORD=<secret>
|
||||
|
||||
KEYCLOAK_DIRECTORY=/home/keycloak/keycloak
|
||||
KEYCLOAK_VERSION=26.2.4
|
||||
|
||||
# Backup specifics
|
||||
SERVICE_BACKUPS_DIR=/backups/keycloak
|
||||
SERVICE_BACKUPS_PREFIX=keycloak-dump
|
||||
SERVICE_BACKUPS_EXTENSION=sql
|
||||
71
modules/apps/keycloak/cloud-init/service.yaml
Normal file
71
modules/apps/keycloak/cloud-init/service.yaml
Normal file
@@ -0,0 +1,71 @@
|
||||
#cloud-config
|
||||
hostname: ${hostname}
|
||||
local-hostname: ${hostname}
|
||||
fqdn: ${hostname}.${domain}
|
||||
manage_etc_hosts: true
|
||||
|
||||
users:
|
||||
- default
|
||||
- name: ${hostname}
|
||||
groups: sudo
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
ssh_authorized_keys:
|
||||
- ${ssh_key}
|
||||
|
||||
disable_root: true
|
||||
|
||||
package_update: true
|
||||
package_upgrade: false
|
||||
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- curl
|
||||
- unzip
|
||||
- openjdk-21-jdk-headless
|
||||
- postgresql
|
||||
- postgresql-contrib
|
||||
|
||||
mounts:
|
||||
- [ "192.168.1.12:/main/backups", "/backups", "nfs", "defaults,_netdev,x-systemd.requires=network-online.target", "0", "0" ]
|
||||
|
||||
write_files:
|
||||
- path: /opt/environment/.env
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${restore-backup-script}
|
||||
- path: /etc/systemd/system/restore-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${restore-backup-service}
|
||||
- path: /usr/local/bin/backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${create-backup-script}
|
||||
- path: /etc/systemd/system/create-backup.timer
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-timer}
|
||||
- path: /etc/systemd/system/create-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-service}
|
||||
- path: /etc/systemd/system/keycloak.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${keycloak-service}
|
||||
|
||||
runcmd:
|
||||
# Backup setup
|
||||
- mkdir -p /backups
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
|
||||
|
||||
final_message: |
|
||||
Base system ready for ${hostname}
|
||||
18
modules/apps/keycloak/lib/scripts/create-backup.sh
Normal file
18
modules/apps/keycloak/lib/scripts/create-backup.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
TIMESTAMP=$(date +'%Y-%m-%d_%H%M%S')
|
||||
|
||||
# Backup realms
|
||||
|
||||
sh $KEYCLOAK_DIRECTORY/kc.sh export --file $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-$TIMESTAMP.json
|
||||
|
||||
|
||||
# Backup database
|
||||
pg_dump -U keycloak -F c -b -v -f $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-$TIMESTAMP.$SERVICE_BACKUPS_EXTENSION
|
||||
|
||||
|
||||
ls -1dt $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION | tail -n +5 | xargs -r rm -f
|
||||
ls -1dt $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.json | tail -n +5 | xargs -r rm -f
|
||||
34
modules/apps/keycloak/lib/scripts/install-keycloak.sh
Normal file
34
modules/apps/keycloak/lib/scripts/install-keycloak.sh
Normal file
@@ -0,0 +1,34 @@
|
||||
#//bin/bash
|
||||
|
||||
# KEYCLOAK_DIRECTORY=/home/keycloak/keycloak
|
||||
# KEYCLOAK_VERSION: 26.2.4
|
||||
# KC_DB_PASSWORD
|
||||
# SERVICE_BACKUPS_DIR
|
||||
# SERVICE_BACKUPS_PREFIX
|
||||
# SERVICE_BACKUPS_EXTENSION
|
||||
|
||||
if [ ! -f $KEYCLOAK_DIRECTORY ]; then
|
||||
wget -O /tmp/keycloak.zip https://github.com/keycloak/keycloak/releases/download/$KEYCLOAK_VERSION/keycloak-$KEYCLOAK_VERSION.zip
|
||||
unzip -o /tmp/keycloak /tmp/keycloak.zip -d /tmp
|
||||
mv /tmp/keycloak $KEYCLOAK_DIRECTORY
|
||||
chmod o+x $KEYCLOAK_DIRECTORY/bin
|
||||
fi
|
||||
|
||||
groupadd keycloak
|
||||
|
||||
sudo -u postgres psql <<EOF
|
||||
CREATE DATABASE keycloak with encoding 'UTF8' TEMPLATE template0;
|
||||
CREATE USER keycloak WITH ENCRYPTED PASSWORD '$KC_DB_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;
|
||||
EOF
|
||||
|
||||
|
||||
if ls -1 "$SERVICE_BACKUPS_DIR"/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION >/dev/null 2>&1; then
|
||||
echo "---- Backup found, restoring Gitea ----"
|
||||
/usr/local/bin/restore-backup.sh
|
||||
else
|
||||
echo "---- No backup found in $SERVICE_BACKUPS_DIR, skipping restore ----"
|
||||
fi
|
||||
|
||||
sudo systemctl enable keycloak
|
||||
sudo systemctl start keycloak
|
||||
14
modules/apps/keycloak/lib/scripts/restore-backup.sh
Normal file
14
modules/apps/keycloak/lib/scripts/restore-backup.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
LATEST_BACKUP_DB=$(ls -1 $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION 2>/dev/null | sort | tail -n1)
|
||||
LATEST_BACKUP_REALMS=$(ls -1 $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.json 2>/dev/null | sort | tail -n1)
|
||||
|
||||
if [ -n "$LATEST_BACKUP_DB" ] && [ -f "$LATEST_BACKUP_DB" ]; then
|
||||
psql -U keycloak $KC_DB < $LATEST_BACKUP_DB
|
||||
fi
|
||||
|
||||
if [ -n "$LATEST_BACKUP_REALMS" ] && [ -f "$LATEST_BACKUP_REALMS" ]; then
|
||||
sh $KEYCLOAK_DIRECTORY/kc.sh import --file $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-$TIMESTAMP.json
|
||||
fi
|
||||
9
modules/apps/keycloak/lib/services/create-backup.service
Normal file
9
modules/apps/keycloak/lib/services/create-backup.service
Normal file
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Backup Service
|
||||
Wants=network.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=root
|
||||
ExecStart=/usr/local/bin/backup.sh
|
||||
17
modules/apps/keycloak/lib/services/keycloak.service
Normal file
17
modules/apps/keycloak/lib/services/keycloak.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Keycloak Authorization Server
|
||||
Requires=network.target
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
Type=idle
|
||||
User=keycloak
|
||||
Group=keycloak
|
||||
ExecStart=/home/keycloak/keycloak/bin/kc.sh start
|
||||
ExecStop=/home/keycloak/keycloak/bin/kc.sh stop
|
||||
Restart=always
|
||||
RestartSec=15
|
||||
EnvironmentFile=/opt/environment/.env
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Restore latest backup
|
||||
After=network.target postgresql.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=root
|
||||
ExecStart=/usr/local/bin/restore-backup.sh
|
||||
35
modules/apps/keycloak/main.tf
Normal file
35
modules/apps/keycloak/main.tf
Normal file
@@ -0,0 +1,35 @@
|
||||
module "vm" {
|
||||
source = "../../vm"
|
||||
name = var.name
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
vm_id = var.vm_id
|
||||
node_name = var.node_name
|
||||
vm_ip_address = var.vm_ip_address
|
||||
|
||||
template_id = var.template_id
|
||||
|
||||
cores = var.cores
|
||||
memory = var.memory
|
||||
disk_size = var.disk_size
|
||||
|
||||
ssh_public_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
|
||||
cloudinit_config = templatefile(
|
||||
"${path.module}/cloud-init/service.yaml",
|
||||
{
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
ssh_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
restore-backup-script = indent(6, file("${path.module}/lib/scripts/restore-backup.sh"))
|
||||
restore-backup-service = indent(6, file("${path.module}/lib/services/restore-backup.service"))
|
||||
create-backup-script = indent(6, file("${path.module}/lib/scripts/create-backup.sh"))
|
||||
create-backup-service = indent(6, file("${path.module}/lib/services/create-backup.service"))
|
||||
create-backup-timer = indent(6, file("${path.module}/../common/services/create-backup.timer"))
|
||||
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
)
|
||||
}
|
||||
9
modules/apps/keycloak/output.tf
Normal file
9
modules/apps/keycloak/output.tf
Normal file
@@ -0,0 +1,9 @@
|
||||
output "traefik_service" {
|
||||
value = [{
|
||||
domain = var.domain
|
||||
name = var.name
|
||||
host = "${var.hostname}"
|
||||
ip = var.vm_ip_address
|
||||
port = 8080
|
||||
}]
|
||||
}
|
||||
71
modules/apps/keycloak/variables.tf
Normal file
71
modules/apps/keycloak/variables.tf
Normal file
@@ -0,0 +1,71 @@
|
||||
variable "name" {
|
||||
description = "Virtual Machine name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_id" {
|
||||
description = "Virtual Machine id"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "node_name" {
|
||||
description = "Proxmox node name"
|
||||
type = string
|
||||
default = "mop"
|
||||
}
|
||||
|
||||
variable "cores" {
|
||||
description = "Number of CPU cores for this virtual machine"
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "memory" {
|
||||
description = "Memory RAM for this virtual machine"
|
||||
type = number
|
||||
default = 2048
|
||||
}
|
||||
|
||||
variable "balloon" {
|
||||
description = "Minimum vm memory, using ballooning devide to reach Proxmox node memory target."
|
||||
type = number
|
||||
default = 1024
|
||||
}
|
||||
|
||||
variable "template_id" {
|
||||
description = "Virtual machine template ID"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
description = "Public SSH key for cloud-init user"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "hostname" {
|
||||
description = "Virtual Machine hostname (<service-name>)"
|
||||
type = string
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
description = "Virtual Machine domain (example.fr)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
description = "Disk size for the virtual machine"
|
||||
type = number
|
||||
default = 10
|
||||
}
|
||||
|
||||
variable "proxmox_host_ip" {
|
||||
description = "Proxmox host base ip"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_ip_address" {
|
||||
description = "Virtual machine ip"
|
||||
type = string
|
||||
}
|
||||
0
modules/apps/n8n/.env.example
Normal file
0
modules/apps/n8n/.env.example
Normal file
91
modules/apps/n8n/cloud-init/service.yaml
Normal file
91
modules/apps/n8n/cloud-init/service.yaml
Normal file
@@ -0,0 +1,91 @@
|
||||
#cloud-config
|
||||
hostname: ${hostname}
|
||||
local-hostname: ${hostname}
|
||||
fqdn: ${hostname}.${domain}
|
||||
manage_etc_hosts: true
|
||||
|
||||
groups:
|
||||
- git
|
||||
|
||||
users:
|
||||
- default
|
||||
- name: ${hostname}
|
||||
groups: sudo,git
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
ssh_authorized_keys:
|
||||
- ${ssh_key}
|
||||
|
||||
disable_root: true
|
||||
|
||||
package_update: true
|
||||
package_upgrade: false
|
||||
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- curl
|
||||
- ca-certificates
|
||||
- gnupg
|
||||
- unzip
|
||||
- postgresql
|
||||
- postgresql-client
|
||||
|
||||
mounts:
|
||||
- [ "192.168.1.12:/main/backups", "/backups", "nfs", "defaults,_netdev,x-systemd.requires=network-online.target", "0", "0" ]
|
||||
|
||||
write_files:
|
||||
- path: /opt/environment/.env
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${restore-backup-script}
|
||||
- path: /etc/systemd/system/restore-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${restore-backup-service}
|
||||
- path: /usr/local/bin/backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${create-backup-script}
|
||||
- path: /etc/systemd/system/create-backup.timer
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-timer}
|
||||
- path: /etc/systemd/system/create-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-service}
|
||||
- path: /opt/n8n/install-n8n.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-n8n-script}
|
||||
- path: /opt/n8n/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /home/n8n/docker-compose.yaml
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${n8n-docker-compose}
|
||||
- path: /home/n8n/init-data.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${n8n-init-data}
|
||||
|
||||
|
||||
runcmd:
|
||||
# Docker install
|
||||
- /opt/n8n/install-docker.sh
|
||||
# Backup setup
|
||||
- mkdir -p /backups
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Install n8n
|
||||
- /opt/n8n/install-n8n.sh
|
||||
|
||||
final_message: |
|
||||
Base system ready for ${hostname}
|
||||
10
modules/apps/n8n/lib/scripts/create-backup.sh
Normal file
10
modules/apps/n8n/lib/scripts/create-backup.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
TIMESTAMP=$(date +'%Y-%m-%d_%H%M%S')
|
||||
|
||||
sudo -u $USERNAME docker exec -i n8n-postgres-1 pg_dump -F c -U $DB_USER -d $DB_NAME > $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-$TIMESTAMP.$SERVICE_BACKUPS_EXTENSION
|
||||
|
||||
ls -1dt $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION | tail -n +5 | xargs -r rm -f
|
||||
8
modules/apps/n8n/lib/scripts/init-data.sh
Normal file
8
modules/apps/n8n/lib/scripts/init-data.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||
CREATE USER $POSTGRES_NON_ROOT_USER WITH PASSWORD '$POSTGRES_NON_ROOT_PASSWORD';
|
||||
CREATE DATABASE $POSTGRES_DB;
|
||||
GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_DB TO $POSTGRES_NON_ROOT_USER;
|
||||
EOSQL
|
||||
11
modules/apps/n8n/lib/scripts/install-n8n.sh
Normal file
11
modules/apps/n8n/lib/scripts/install-n8n.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
#https://docs.n8n.io/hosting/installation/docker/#using-with-postgresql
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
cd $SERVICE_WORKDIR
|
||||
cp /opt/environment/.env $SERVICE_WORKDIR/.env
|
||||
docker-compose up -d
|
||||
10
modules/apps/n8n/lib/scripts/restore-backup.sh
Normal file
10
modules/apps/n8n/lib/scripts/restore-backup.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
LATEST_BACKUP=$(ls -1 $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION 2>/dev/null | sort | tail -n1)
|
||||
|
||||
if [ -n "$LATEST_BACKUP" ] && [ -f "$LATEST_BACKUP" ]; then
|
||||
sudo -u $USERNAME docker exec -i n8n-postgres-1 pg_restore --clean --if-exists -U "$DB_USER" -v -d "$DB_NAME" < $LATEST_BACKUP
|
||||
fi
|
||||
54
modules/apps/n8n/lib/services/docker-compose.yaml
Normal file
54
modules/apps/n8n/lib/services/docker-compose.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
volumes:
|
||||
db_storage:
|
||||
n8n_storage:
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
restart: always
|
||||
environment:
|
||||
- POSTGRES_USER=${POSTGRES_USER}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- POSTGRES_DB=${POSTGRES_DB}
|
||||
- POSTGRES_NON_ROOT_USER=${POSTGRES_NON_ROOT_USER}
|
||||
- POSTGRES_NON_ROOT_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
|
||||
volumes:
|
||||
- db_storage:/var/lib/postgresql/data
|
||||
- ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
n8n:
|
||||
image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
|
||||
restart: always
|
||||
environment:
|
||||
- DB_TYPE=postgresdb
|
||||
- DB_POSTGRESDB_HOST=postgres
|
||||
- DB_POSTGRESDB_PORT=5432
|
||||
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
|
||||
- DB_POSTGRESDB_USER=${POSTGRES_USER}
|
||||
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- N8N_RUNNERS_MODE=external
|
||||
- N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
|
||||
- N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
|
||||
ports:
|
||||
- 5678:5678
|
||||
links:
|
||||
- postgres
|
||||
volumes:
|
||||
- n8n_storage:/home/node/.n8n
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
||||
n8n-runner:
|
||||
image: n8nio/runners:${N8N_VERSION}
|
||||
restart: always
|
||||
environment:
|
||||
- N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
|
||||
- N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
|
||||
depends_on:
|
||||
- n8n
|
||||
39
modules/apps/n8n/main.tf
Normal file
39
modules/apps/n8n/main.tf
Normal file
@@ -0,0 +1,39 @@
|
||||
module "vm" {
|
||||
source = "../../vm"
|
||||
name = var.name
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
vm_id = var.vm_id
|
||||
node_name = var.node_name
|
||||
vm_ip_address = var.vm_ip_address
|
||||
|
||||
template_id = var.template_id
|
||||
|
||||
cores = var.cores
|
||||
memory = var.memory
|
||||
disk_size = var.disk_size
|
||||
|
||||
ssh_public_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
|
||||
cloudinit_config = templatefile(
|
||||
"${path.module}/cloud-init/service.yaml",
|
||||
{
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
ssh_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
restore-backup-script = indent(6, file("${path.module}/lib/scripts/restore-backup.sh"))
|
||||
restore-backup-service = indent(6, file("${path.module}/../common/services/docker/restore-backup.service"))
|
||||
create-backup-script = indent(6, file("${path.module}/lib/scripts/create-backup.sh"))
|
||||
create-backup-timer = indent(6, file("${path.module}/../common/services/create-backup.timer"))
|
||||
create-backup-service = indent(6, file("${path.module}/../common/services/docker/create-backup.service"))
|
||||
|
||||
install-n8n-script = indent(6, file("${path.module}/lib/scripts/install-n8n.sh"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
n8n-docker-compose = indent(6, file("${path.module}/lib/services/docker-compose.yaml"))
|
||||
n8n-init-data = indent(6, file("${path.module}/lib/scripts/init-data.sh"))
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
)
|
||||
}
|
||||
9
modules/apps/n8n/output.tf
Normal file
9
modules/apps/n8n/output.tf
Normal file
@@ -0,0 +1,9 @@
|
||||
output "traefik_service" {
|
||||
value = [{
|
||||
domain = var.domain
|
||||
name = var.name
|
||||
host = "${var.hostname}"
|
||||
ip = var.vm_ip_address
|
||||
port = 5678
|
||||
}]
|
||||
}
|
||||
71
modules/apps/n8n/variables.tf
Normal file
71
modules/apps/n8n/variables.tf
Normal file
@@ -0,0 +1,71 @@
|
||||
variable "name" {
|
||||
description = "Virtual Machine name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_id" {
|
||||
description = "Virtual Machine id"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "node_name" {
|
||||
description = "Proxmox node name"
|
||||
type = string
|
||||
default = "mop"
|
||||
}
|
||||
|
||||
variable "cores" {
|
||||
description = "Number of CPU cores for this virtual machine"
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "memory" {
|
||||
description = "Memory RAM for this virtual machine"
|
||||
type = number
|
||||
default = 2048
|
||||
}
|
||||
|
||||
variable "balloon" {
|
||||
description = "Minimum vm memory, using ballooning devide to reach Proxmox node memory target."
|
||||
type = number
|
||||
default = 1024
|
||||
}
|
||||
|
||||
variable "template_id" {
|
||||
description = "Virtual machine template ID"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
description = "Public SSH key for cloud-init user"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "hostname" {
|
||||
description = "Virtual Machine hostname (<service-name>)"
|
||||
type = string
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
description = "Virtual Machine domain (example.fr)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
description = "Disk size for the virtual machine"
|
||||
type = number
|
||||
default = 10
|
||||
}
|
||||
|
||||
variable "proxmox_host_ip" {
|
||||
description = "Proxmox host base ip"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_ip_address" {
|
||||
description = "Virtual machine ip"
|
||||
type = string
|
||||
}
|
||||
0
modules/apps/rocket/main.tf
Normal file
0
modules/apps/rocket/main.tf
Normal file
0
modules/apps/rocket/output.tf
Normal file
0
modules/apps/rocket/output.tf
Normal file
0
modules/apps/rocket/variables.tf
Normal file
0
modules/apps/rocket/variables.tf
Normal file
15
modules/apps/windmill/.env.example
Normal file
15
modules/apps/windmill/.env.example
Normal file
@@ -0,0 +1,15 @@
|
||||
# Environment files
|
||||
ENV_FILE_LOCATION=/opt/environment/.env
|
||||
|
||||
# Application specifics
|
||||
DATABASE_URL=postgres://postgres:changeme@db/windmill?sslmode=disable
|
||||
DB_USER=postgres
|
||||
DB_NAME=windmill
|
||||
DB_PASS=
|
||||
WM_IMAGE=ghcr.io/windmill-labs/windmill:main
|
||||
SERVICE_WORKDIR=/home/windmill
|
||||
|
||||
# Backup specifics
|
||||
SERVICE_BACKUPS_DIR=/backups/windmill
|
||||
SERVICE_BACKUPS_PREFIX=windmill-dump
|
||||
SERVICE_BACKUPS_EXTENSION=dump
|
||||
89
modules/apps/windmill/cloud-init/service.yaml
Normal file
89
modules/apps/windmill/cloud-init/service.yaml
Normal file
@@ -0,0 +1,89 @@
|
||||
#cloud-config
|
||||
hostname: ${hostname}
|
||||
local-hostname: ${hostname}
|
||||
fqdn: ${hostname}.${domain}
|
||||
manage_etc_hosts: true
|
||||
|
||||
groups:
|
||||
- git
|
||||
|
||||
users:
|
||||
- default
|
||||
- name: ${hostname}
|
||||
groups: sudo,git
|
||||
shell: /bin/bash
|
||||
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||
ssh_authorized_keys:
|
||||
- ${ssh_key}
|
||||
|
||||
disable_root: true
|
||||
|
||||
package_update: true
|
||||
package_upgrade: false
|
||||
|
||||
packages:
|
||||
- git
|
||||
- nfs-common
|
||||
- curl
|
||||
- unzip
|
||||
- postgresql
|
||||
- postgresql-client
|
||||
|
||||
mounts:
|
||||
- [ "192.168.1.12:/main/backups", "/backups", "nfs", "defaults,_netdev,x-systemd.requires=network-online.target", "0", "0" ]
|
||||
|
||||
write_files:
|
||||
- path: /opt/environment/.env
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${env-file-content}
|
||||
- path: /opt/${hostname}/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-docker-script}
|
||||
- path: /usr/local/bin/restore-backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${restore-backup-script}
|
||||
- path: /etc/systemd/system/restore-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${restore-backup-service}
|
||||
- path: /usr/local/bin/backup.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${create-backup-script}
|
||||
- path: /etc/systemd/system/create-backup.timer
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-timer}
|
||||
- path: /etc/systemd/system/create-backup.service
|
||||
permissions: "0644"
|
||||
content: |
|
||||
${create-backup-service}
|
||||
- path: /opt/windmill/install-windmill.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${install-windmill-script}
|
||||
- path: /home/windmill/docker-compose.yaml
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${windmill-docker-compose}
|
||||
- path: /home/windmill/Caddyfile
|
||||
permissions: "0755"
|
||||
content: |
|
||||
${windmill-caddyfile}
|
||||
|
||||
|
||||
runcmd:
|
||||
# Backup setup
|
||||
- mkdir -p /backups
|
||||
- mount -t nfs ${proxmox_host_ip}:/main/backups /backups
|
||||
- systemctl enable --now create-backup.timer
|
||||
# Docker setup
|
||||
- /opt/${hostname}/install-docker.sh
|
||||
# windmill setup
|
||||
- /opt/windmill/install-windmill.sh
|
||||
|
||||
final_message: |
|
||||
Base system ready for ${hostname}
|
||||
15
modules/apps/windmill/lib/scripts/create-backup.sh
Normal file
15
modules/apps/windmill/lib/scripts/create-backup.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
#SERVICE_BACKUPS_DIR
|
||||
#SERVICE_BACKUPS_PREFIX
|
||||
#SERVICE_BACKUPS_EXTENSION
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
TIMESTAMP=$(date +'%Y-%m-%d_%H%M%S')
|
||||
|
||||
# docker exec $DB_SERVICE
|
||||
|
||||
ls -1dt $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION | tail -n +5 | xargs -r rm -f
|
||||
11
modules/apps/windmill/lib/scripts/install-windmill.sh
Normal file
11
modules/apps/windmill/lib/scripts/install-windmill.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
#https://www.windmill.dev/docs/advanced/self_host
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
cd $SERVICE_WORKDIR
|
||||
cp /opt/environment/.env $SERVICE_WORKDIR/.env
|
||||
docker-compose up -d
|
||||
20
modules/apps/windmill/lib/scripts/restore-backup.sh
Normal file
20
modules/apps/windmill/lib/scripts/restore-backup.sh
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
#USERNAME
|
||||
#SERVICE_BACKUPS_DIR
|
||||
#SERVICE_BACKUPS_PREFIX
|
||||
#SERVICE_BACKUPS_EXTENSION
|
||||
#DB_USER
|
||||
#DB_NAME
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source /opt/environment/.env
|
||||
|
||||
LATEST_BACKUP=$(ls -1 $SERVICE_BACKUPS_DIR/$SERVICE_BACKUPS_PREFIX-*.$SERVICE_BACKUPS_EXTENSION 2>/dev/null | sort | tail -n1)
|
||||
|
||||
if [ -n "$LATEST_BACKUP" ] && [ -f "$LATEST_BACKUP" ]; then
|
||||
systemctl stop listmonk
|
||||
sudo -u $USERNAME pg_restore --clean --if-exists -U "$DB_USER" -d "$DB_NAME" $LATEST_BACKUP
|
||||
systemctl start listmonk
|
||||
fi
|
||||
35
modules/apps/windmill/lib/services/Caddyfile
Normal file
35
modules/apps/windmill/lib/services/Caddyfile
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
layer4 {
|
||||
:25 {
|
||||
proxy {
|
||||
to windmill_server:2525
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{$BASE_URL} {
|
||||
bind {$ADDRESS}
|
||||
|
||||
# LSP - Language Server Protocol for code intelligence (windmill_extra:3001)
|
||||
reverse_proxy /ws/* http://windmill_extra:3001
|
||||
|
||||
# Multiplayer - Real-time collaboration, Enterprise Edition (windmill_extra:3002)
|
||||
# Uncomment and set ENABLE_MULTIPLAYER=true in docker-compose.yml
|
||||
# reverse_proxy /ws_mp/* http://windmill_extra:3002
|
||||
|
||||
# Debugger - Interactive debugging via DAP WebSocket (windmill_extra:3003)
|
||||
# Set ENABLE_DEBUGGER=true in docker-compose.yml to enable
|
||||
handle_path /ws_debug/* {
|
||||
reverse_proxy http://windmill_extra:3003
|
||||
}
|
||||
|
||||
# Search indexer, Enterprise Edition (windmill_indexer:8002)
|
||||
# reverse_proxy /api/srch/* http://windmill_indexer:8002
|
||||
|
||||
# Default: Windmill server
|
||||
reverse_proxy /* http://windmill_server:8000
|
||||
|
||||
# TLS with custom certificates
|
||||
# tls /certs/cert.pem /certs/key.pem
|
||||
}
|
||||
222
modules/apps/windmill/lib/services/docker-compose.yaml
Normal file
222
modules/apps/windmill/lib/services/docker-compose.yaml
Normal file
@@ -0,0 +1,222 @@
|
||||
version: "3.7"
|
||||
|
||||
x-logging: &default-logging
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "${LOG_MAX_SIZE:-20m}"
|
||||
max-file: "${LOG_MAX_FILE:-10}"
|
||||
compress: "true"
|
||||
|
||||
services:
|
||||
db:
|
||||
deploy:
|
||||
# To use an external database, set replicas to 0 and set DATABASE_URL to the external database url in the .env file
|
||||
replicas: 1
|
||||
image: postgres:16
|
||||
shm_size: 1g
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
expose:
|
||||
- 5432
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${DB_PASS}
|
||||
POSTGRES_DB: ${DB_NAME}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
logging: *default-logging
|
||||
|
||||
windmill_server:
|
||||
image: ${WM_IMAGE}
|
||||
pull_policy: always
|
||||
deploy:
|
||||
replicas: 1
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- 8000
|
||||
- 2525
|
||||
environment:
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- MODE=server
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- worker_logs:/tmp/windmill/logs
|
||||
|
||||
logging: *default-logging
|
||||
|
||||
windmill_worker:
|
||||
image: ${WM_IMAGE}
|
||||
pull_policy: always
|
||||
deploy:
|
||||
replicas: 3
|
||||
resources:
|
||||
limits:
|
||||
cpus: "1"
|
||||
memory: 2048M
|
||||
# for GB, use syntax '2Gi'
|
||||
restart: unless-stopped
|
||||
# Uncomment to enable PID namespace isolation (recommended for security)
|
||||
# Requires privileged mode for --mount-proc flag
|
||||
# See: https://www.windmill.dev/docs/advanced/security_isolation
|
||||
# privileged: true
|
||||
environment:
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- MODE=worker
|
||||
- WORKER_GROUP=default
|
||||
# If running with non-root/non-windmill UID (e.g., user: "1001:1001"),
|
||||
# add: - HOME=/tmp
|
||||
# Uncomment to enable PID namespace isolation (requires privileged: true above)
|
||||
# - ENABLE_UNSHARE_PID=true
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
# to mount the worker folder to debug, KEEP_JOB_DIR=true and mount /tmp/windmill
|
||||
volumes:
|
||||
# mount the docker socket to allow to run docker containers from within the workers
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- worker_dependency_cache:/tmp/windmill/cache
|
||||
- worker_logs:/tmp/windmill/logs
|
||||
|
||||
logging: *default-logging
|
||||
|
||||
## This worker is specialized for "native" jobs. Native jobs run in-process and thus are much more lightweight than other jobs
|
||||
windmill_worker_native:
|
||||
# Use ghcr.io/windmill-labs/windmill-ee:main for the ee
|
||||
image: ${WM_IMAGE}
|
||||
pull_policy: always
|
||||
deploy:
|
||||
replicas: 1
|
||||
resources:
|
||||
limits:
|
||||
cpus: "1"
|
||||
memory: 2048M
|
||||
# for GB, use syntax '2Gi'
|
||||
restart: unless-stopped
|
||||
# Uncomment to enable PID namespace isolation (recommended for security)
|
||||
# Requires privileged mode for --mount-proc flag
|
||||
# See: https://www.windmill.dev/docs/advanced/security_isolation
|
||||
# privileged: true
|
||||
environment:
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- MODE=worker
|
||||
- WORKER_GROUP=native
|
||||
- NUM_WORKERS=8
|
||||
- SLEEP_QUEUE=200
|
||||
# Uncomment to enable PID namespace isolation (requires privileged: true above)
|
||||
# - ENABLE_UNSHARE_PID=true
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- worker_logs:/tmp/windmill/logs
|
||||
logging: *default-logging
|
||||
# This worker is specialized for reports or scraping jobs. It is assigned the "reports" worker group which has an init script that installs chromium and can be targeted by using the "chromium" worker tag.
|
||||
# windmill_worker_reports:
|
||||
# image: ${WM_IMAGE}
|
||||
# pull_policy: always
|
||||
# deploy:
|
||||
# replicas: 1
|
||||
# resources:
|
||||
# limits:
|
||||
# cpus: "1"
|
||||
# memory: 2048M
|
||||
# # for GB, use syntax '2Gi'
|
||||
# restart: unless-stopped
|
||||
# # Uncomment to enable PID namespace isolation (recommended for security)
|
||||
# # Requires privileged mode for --mount-proc flag
|
||||
# # See: https://www.windmill.dev/docs/advanced/security_isolation
|
||||
# # privileged: true
|
||||
# environment:
|
||||
# - DATABASE_URL=${DATABASE_URL}
|
||||
# - MODE=worker
|
||||
# - WORKER_GROUP=reports
|
||||
# # Uncomment to enable PID namespace isolation (requires privileged: true above)
|
||||
# # - ENABLE_UNSHARE_PID=true
|
||||
# depends_on:
|
||||
# db:
|
||||
# condition: service_healthy
|
||||
# # to mount the worker folder to debug, KEEP_JOB_DIR=true and mount /tmp/windmill
|
||||
# volumes:
|
||||
# # mount the docker socket to allow to run docker containers from within the workers
|
||||
# - /var/run/docker.sock:/var/run/docker.sock
|
||||
# - worker_dependency_cache:/tmp/windmill/cache
|
||||
# - worker_logs:/tmp/windmill/logs
|
||||
|
||||
# The indexer powers full-text job and log search, an EE feature.
|
||||
windmill_indexer:
|
||||
image: ${WM_IMAGE}
|
||||
pull_policy: always
|
||||
deploy:
|
||||
replicas: 0 # set to 1 to enable full-text job and log search
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- 8002
|
||||
environment:
|
||||
- PORT=8002
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
- MODE=indexer
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- windmill_index:/tmp/windmill/search
|
||||
- worker_logs:/tmp/windmill/logs
|
||||
logging: *default-logging
|
||||
|
||||
# Combined extra services: LSP, Multiplayer, and Debugger
|
||||
# Each service can be enabled/disabled via environment variables:
|
||||
# - ENABLE_LSP=true (default) - Language Server Protocol for code intelligence
|
||||
# - ENABLE_MULTIPLAYER=false - Real-time collaboration (Enterprise Edition)
|
||||
# - ENABLE_DEBUGGER=false - Interactive debugging via DAP WebSocket
|
||||
windmill_extra:
|
||||
image: ghcr.io/windmill-labs/windmill-extra:latest
|
||||
pull_policy: always
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- 3001 # LSP
|
||||
- 3002 # Multiplayer
|
||||
- 3003 # Debugger
|
||||
environment:
|
||||
- ENABLE_LSP=true
|
||||
- ENABLE_MULTIPLAYER=false # Set to true to enable multiplayer (Enterprise Edition)
|
||||
- ENABLE_DEBUGGER=true # Set to true to enable debugger
|
||||
- DEBUGGER_PORT=3003 # Debugger service port
|
||||
- ENABLE_NSJAIL=false # Set to true for nsjail sandboxing (requires privileged: true)
|
||||
- REQUIRE_SIGNED_DEBUG_REQUESTS=false # Set to true to require JWT tokens for debug sessions
|
||||
- WINDMILL_BASE_URL=http://windmill_server:8000
|
||||
volumes:
|
||||
- lsp_cache:/pyls/.cache
|
||||
logging: *default-logging
|
||||
|
||||
caddy:
|
||||
image: ghcr.io/windmill-labs/caddy-l4:latest
|
||||
restart: unless-stopped
|
||||
# Configure the mounted Caddyfile and the exposed ports or use another reverse proxy if needed
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
# - ./certs:/certs # Provide custom certificate files like cert.pem and key.pem to enable HTTPS - See the corresponding section in the Caddyfile
|
||||
ports:
|
||||
# To change the exposed port, simply change 80:80 to <desired_port>:80. No other changes needed
|
||||
- 80:80
|
||||
- 25:25
|
||||
# - 443:443 # Uncomment to enable HTTPS handling by Caddy
|
||||
environment:
|
||||
- BASE_URL=":80"
|
||||
# - BASE_URL=":443" # uncomment and comment line above to enable HTTPS via custom certificate and key files
|
||||
# - BASE_URL=mydomain.com # Uncomment and comment line above to enable HTTPS handling by Caddy
|
||||
logging: *default-logging
|
||||
|
||||
volumes:
|
||||
db_data: null
|
||||
worker_dependency_cache: null
|
||||
worker_logs: null
|
||||
worker_memory: null
|
||||
windmill_index: null
|
||||
lsp_cache: null
|
||||
caddy_data: null
|
||||
41
modules/apps/windmill/main.tf
Normal file
41
modules/apps/windmill/main.tf
Normal file
@@ -0,0 +1,41 @@
|
||||
module "vm" {
|
||||
source = "../../vm"
|
||||
name = var.name
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
vm_id = var.vm_id
|
||||
node_name = var.node_name
|
||||
vm_ip_address = var.vm_ip_address
|
||||
|
||||
template_id = var.template_id
|
||||
|
||||
cores = var.cores
|
||||
memory = var.memory
|
||||
disk_size = var.disk_size
|
||||
|
||||
ssh_public_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
|
||||
cloudinit_config = templatefile(
|
||||
"${path.module}/cloud-init/service.yaml",
|
||||
{
|
||||
hostname = var.hostname
|
||||
domain = var.domain
|
||||
ssh_key = var.ssh_public_key
|
||||
proxmox_host_ip = var.proxmox_host_ip
|
||||
restore-backup-script = indent(6, file("${path.module}/lib/scripts/restore-backup.sh"))
|
||||
restore-backup-service = indent(6, file("${path.module}/../common/services/docker/restore-backup.service"))
|
||||
create-backup-script = indent(6, file("${path.module}/lib/scripts/create-backup.sh"))
|
||||
create-backup-timer = indent(6, file("${path.module}/../common/services/create-backup.timer"))
|
||||
create-backup-service = indent(6, file("${path.module}/../common/services/docker/create-backup.service"))
|
||||
|
||||
install-windmill-script = indent(6, file("${path.module}/lib/scripts/install-windmill.sh"))
|
||||
|
||||
windmill-docker-compose = indent(6, file("${path.module}/lib/services/docker-compose.yaml"))
|
||||
windmill-caddyfile = indent(6, file("${path.module}/lib/services/Caddyfile"))
|
||||
install-docker-script = indent(6, file("${path.module}/../common/scripts/install-docker.sh"))
|
||||
|
||||
env-file-content = indent(6, file("${path.module}/.env"))
|
||||
}
|
||||
)
|
||||
}
|
||||
9
modules/apps/windmill/output.tf
Normal file
9
modules/apps/windmill/output.tf
Normal file
@@ -0,0 +1,9 @@
|
||||
output "traefik_service" {
|
||||
value = [{
|
||||
domain = var.domain
|
||||
name = var.name
|
||||
host = "${var.hostname}"
|
||||
ip = var.vm_ip_address
|
||||
port = 80
|
||||
}]
|
||||
}
|
||||
71
modules/apps/windmill/variables.tf
Normal file
71
modules/apps/windmill/variables.tf
Normal file
@@ -0,0 +1,71 @@
|
||||
variable "name" {
|
||||
description = "Virtual Machine name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_id" {
|
||||
description = "Virtual Machine id"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "node_name" {
|
||||
description = "Proxmox node name"
|
||||
type = string
|
||||
default = "mop"
|
||||
}
|
||||
|
||||
variable "cores" {
|
||||
description = "Number of CPU cores for this virtual machine"
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "memory" {
|
||||
description = "Memory RAM for this virtual machine"
|
||||
type = number
|
||||
default = 2048
|
||||
}
|
||||
|
||||
variable "balloon" {
|
||||
description = "Minimum vm memory, using ballooning devide to reach Proxmox node memory target."
|
||||
type = number
|
||||
default = 1024
|
||||
}
|
||||
|
||||
variable "template_id" {
|
||||
description = "Virtual machine template ID"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
description = "Public SSH key for cloud-init user"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "hostname" {
|
||||
description = "Virtual Machine hostname (<service-name>)"
|
||||
type = string
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "domain" {
|
||||
description = "Virtual Machine domain (example.fr)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "disk_size" {
|
||||
description = "Disk size for the virtual machine"
|
||||
type = number
|
||||
default = 10
|
||||
}
|
||||
|
||||
variable "proxmox_host_ip" {
|
||||
description = "Proxmox host base ip"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_ip_address" {
|
||||
description = "Virtual machine ip"
|
||||
type = string
|
||||
}
|
||||
@@ -56,6 +56,23 @@ http:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- redirect-errors
|
||||
mathieu:
|
||||
rule: "Host(`mathieu.wiki`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: noop
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
middlewares:
|
||||
- redirect-to-mathieu
|
||||
- redirect-errors
|
||||
mathieu-http:
|
||||
rule: "Host(`mathieu.wiki`)"
|
||||
entryPoints:
|
||||
- web
|
||||
middlewares:
|
||||
- redirect-to-mathieu
|
||||
service: noop
|
||||
wiki:
|
||||
rule: "Host(`benoit.mathieu.wiki`)"
|
||||
entryPoints:
|
||||
@@ -131,6 +148,11 @@ http:
|
||||
servers:
|
||||
- url: "http://127.0.0.1:8090"
|
||||
middlewares:
|
||||
redirect-to-mathieu:
|
||||
redirectRegex:
|
||||
regex: "^https?://mathieu.wiki/(.*)"
|
||||
replacement: "https://benoit.mathieu.wiki/$1"
|
||||
permanent: true
|
||||
redirect-to-aldon:
|
||||
redirectRegex:
|
||||
regex: "^https?://aldon.fr/(.*)"
|
||||
|
||||
Reference in New Issue
Block a user