From 14dc3fdefd9075517a4e8dae0b851c9e747ecc14 Mon Sep 17 00:00:00 2001 From: JulienAldon Date: Sun, 11 Jan 2026 16:43:06 +0100 Subject: [PATCH] Add first module : Gitea app --- .gitignore | 40 ++++ main.tf | 60 +++++ modules/apps/gitea/cloud-init/service.yaml | 85 +++++++ modules/apps/gitea/install.sh | 209 ++++++++++++++++++ .../apps/gitea/lib/scripts/create-backup.sh | 10 + modules/apps/gitea/lib/scripts/env.sh | 12 + .../apps/gitea/lib/scripts/install-gitea.sh | 90 ++++++++ .../apps/gitea/lib/scripts/restore-backup.sh | 62 ++++++ modules/apps/gitea/lib/services/gitea.service | 42 ++++ .../gitea/lib/services/restore-backup.service | 11 + .../gitea/lib/services/weekly-backup.service | 10 + .../gitea/lib/services/weekly-backup.timer | 9 + modules/apps/gitea/main.tf | 34 +++ modules/apps/gitea/variables.tf | 52 +++++ modules/vm/cloud-init/meta_data | 0 modules/vm/main.tf | 78 +++++++ modules/vm/outputs.tf | 7 + modules/vm/variables.tf | 56 +++++ terraform.tfvars.example | 4 + variables.tf | 19 ++ 20 files changed, 890 insertions(+) create mode 100644 .gitignore create mode 100644 main.tf create mode 100644 modules/apps/gitea/cloud-init/service.yaml create mode 100644 modules/apps/gitea/install.sh create mode 100644 modules/apps/gitea/lib/scripts/create-backup.sh create mode 100644 modules/apps/gitea/lib/scripts/env.sh create mode 100644 modules/apps/gitea/lib/scripts/install-gitea.sh create mode 100644 modules/apps/gitea/lib/scripts/restore-backup.sh create mode 100644 modules/apps/gitea/lib/services/gitea.service create mode 100644 modules/apps/gitea/lib/services/restore-backup.service create mode 100644 modules/apps/gitea/lib/services/weekly-backup.service create mode 100644 modules/apps/gitea/lib/services/weekly-backup.timer create mode 100644 modules/apps/gitea/main.tf create mode 100644 modules/apps/gitea/variables.tf create mode 100644 modules/vm/cloud-init/meta_data create mode 100644 modules/vm/main.tf create mode 100644 modules/vm/outputs.tf create mode 100644 modules/vm/variables.tf create mode 100644 terraform.tfvars.example create mode 100644 variables.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e35890 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Created by https://www.toptal.com/developers/gitignore/api/terraform +# Edit at https://www.toptal.com/developers/gitignore?templates=terraform + +### Terraform ### +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +# End of https://www.toptal.com/developers/gitignore/api/terraform diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..9ad1604 --- /dev/null +++ b/main.tf @@ -0,0 +1,60 @@ +terraform { + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "0.42.0" + } + } +} + +provider "proxmox" { + endpoint = var.proxmox_endpoint + api_token = var.proxmox_api_token + insecure = true + + ssh { + agent = true + username = "root" + } +} + +# module "bookshelf" { +# source = "./modules/vm" + +# providers = {} + +# name = "bookshelf" +# hostname = "bookshelf" +# domain = "aldon.fr" +# vm_id = 210 +# node_name = "mop" + +# template_id = 103 + +# cores = 1 +# memory = 1024 +# disk_size = 16 + +# ssh_public_key = var.ssh_public_key +# proxmox_host_ip = var.proxmox_host_ip +# } + +module "gitea" { + source = "./modules/apps/gitea" + providers = {} + + name = "gitea" + hostname = "gitea" + domain = "aldon.fr" + vm_id = 212 + node_name = "mop" + + template_id = 103 + + cores = 2 + memory = 2048 + disk_size = 16 + + ssh_public_key = var.ssh_public_key + proxmox_host_ip = var.proxmox_host_ip +} diff --git a/modules/apps/gitea/cloud-init/service.yaml b/modules/apps/gitea/cloud-init/service.yaml new file mode 100644 index 0000000..b621a9f --- /dev/null +++ b/modules/apps/gitea/cloud-init/service.yaml @@ -0,0 +1,85 @@ +#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 + - docker.io + - docker-compose + - curl + - unzip + - postgresql + - postgresql-client + +write_files: + - path: /etc/fstab + permissions: "0644" + content: | + ${proxmox_host_ip}:/main/backups /backups nfs defaults,_netdev 0 0 + - path: /opt/gitea/env.sh + permissions: "0644" + content: | + ${environment-setup-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/weekly-backup.timer + permissions: "0644" + content: | + ${create-backup-timer} + - path: /etc/systemd/system/weekly-backup.service + permissions: "0644" + content: | + ${create-backup-service} + - path: /etc/systemd/system/gitea.service + permissions: "0644" + content: | + ${gitea-service} + - path: /opt/gitea/install-gitea.sh + permissions: "0755" + content: | + ${install-gitea-script} + +runcmd: + # Backup setup + - mkdir -p /backups + - mount -t nfs ${proxmox_host_ip}:/main/backups /backups + - systemctl enable --now weekly-backup.timer + # Docker setup + - systemctl enable docker + - systemctl start docker + - usermod -aG docker ${hostname} + # gitea setup + - /opt/gitea/install-gitea.sh + +final_message: | + Base system ready for ${hostname} \ No newline at end of file diff --git a/modules/apps/gitea/install.sh b/modules/apps/gitea/install.sh new file mode 100644 index 0000000..eeb3880 --- /dev/null +++ b/modules/apps/gitea/install.sh @@ -0,0 +1,209 @@ +#!/bin/bash +set -euo pipefail + +sudo apt install postgresql postgresql-client unzip -y + +GITEA_HOME="/var/lib/gitea" +GITEA_CONF="$GITEA_HOME/app.ini" +GITEA_USER="git" +GITEA_VERSION="1.25.3" +GITEA_BINARY="/usr/local/bin/gitea" +GITEA_SERVICE="/etc/systemd/system/gitea.service" +DB_NAME="giteadb" +DB_USER="gitea" +GITEA_BACKUPS_DIR="/backups/gitea" + +# Gitea user +if ! id -u $GITEA_USER >/dev/null 2>&1; then + adduser \ + --system \ + --shell /bin/bash \ + --gecos 'Git Version Control' \ + --group \ + --disabled-password \ + --home /home/git \ + $GITEA_USER +fi +echo "---- Gitea user created ----" + +# Gitea folder structure +mkdir -p $GITEA_HOME/{custom,data,log} +chown -R $GITEA_USER:$GITEA_USER $GITEA_HOME +chmod -R 750 $GITEA_HOME + +if [ ! -f $GITEA_BINARY ]; then + wget -O /tmp/gitea "https://dl.gitea.com/gitea/$GITEA_VERSION/gitea-$GITEA_VERSION-linux-amd64" + chmod +x /tmp/gitea + mv /tmp/gitea $GITEA_BINARY +fi +echo "---- Gitea folder structure created ----" + +# Postgres first config +DB_PASS=$(openssl rand -base64 12) +sudo -u postgres psql < /usr/local/bin/restore-backup.sh </dev/null | sort | tail -n1) +# Restore backup database, data, repos, logs if exist +if [ -n "\$LATEST_BACKUP" ] && [ -f "\$LATEST_BACKUP" ]; then + TMP_DIR=$(mktemp -d) + unzip -o \$LATEST_BACKUP -d \$TMP_DIR + if [ -d \$TMP_DIR/data ]; then + cp -a \$TMP_DIR/data/* /var/lib/gitea/data/ + fi + if [ -d \$TMP_DIR/log ]; then + cp -a \$TMP_DIR/log/* /var/lib/gitea/log/ + fi + if [ -d \$TMP_DIR/repos ]; then + cp -aH \$TMP_DIR/repos/. /var/lib/gitea/data/repositories/ + fi + chown -R $GITEA_USER:$GITEA_USER $GITEA_HOME + sudo -u postgres psql -d $DB_NAME < \$TMP_DIR/gitea-db.sql + sudo -u postgres psql </dev/null 2>&1; then + echo "---- Backup found, restoring Gitea ----" + /usr/local/bin/restore-backup.sh +else + echo "---- No backup found in $GITEA_BACKUPS_DIR, skipping restore ----" +fi + +# Save restore backup service +cat > /etc/systemd/system/weekly-backup.service < /usr/local/bin/backup.sh < /etc/systemd/system/weekly-backup.service < /etc/systemd/system/weekly-backup.timer < "$GITEA_CONF" < "$GITEA_SERVICE" +${GITEA_SERVICE_CONTENT} +EOF + systemctl daemon-reload + systemctl enable gitea +fi + +# Enable timer for backup +sudo systemctl enable --now weekly-backup.timer +sudo systemctl status weekly-backup.timer + +systemctl is-active --quiet gitea || systemctl start gitea +echo "---- Gitea installation completed ----" \ No newline at end of file diff --git a/modules/apps/gitea/lib/scripts/create-backup.sh b/modules/apps/gitea/lib/scripts/create-backup.sh new file mode 100644 index 0000000..9726781 --- /dev/null +++ b/modules/apps/gitea/lib/scripts/create-backup.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -euo pipefail + +source /opt/gitea/env.sh + +TIMESTAMP=$(date +'%Y-%m-%d_%H%M%S') + +sudo -u "$GITEA_USER" gitea dump -c "$GITEA_HOME/app.ini" -f $GITEA_BACKUPS_DIR/gitea-dump-\$TIMESTAMP.zip + +ls -1dt $GITEA_BACKUPS_DIR/gitea-dump-*.zip | tail -n +5 | xargs -r rm -f diff --git a/modules/apps/gitea/lib/scripts/env.sh b/modules/apps/gitea/lib/scripts/env.sh new file mode 100644 index 0000000..10ef664 --- /dev/null +++ b/modules/apps/gitea/lib/scripts/env.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euo pipefail + +GITEA_HOME="/var/lib/gitea" +GITEA_CONF="$GITEA_HOME/app.ini" +GITEA_USER="git" +GITEA_VERSION="1.25.3" +GITEA_BINARY="/usr/local/bin/gitea" +GITEA_SERVICE="/etc/systemd/system/gitea.service" +DB_NAME="giteadb" +DB_USER="gitea" +GITEA_BACKUPS_DIR="/backups/gitea" diff --git a/modules/apps/gitea/lib/scripts/install-gitea.sh b/modules/apps/gitea/lib/scripts/install-gitea.sh new file mode 100644 index 0000000..629961f --- /dev/null +++ b/modules/apps/gitea/lib/scripts/install-gitea.sh @@ -0,0 +1,90 @@ +#!/bin/bash +set -euo pipefail + +source /opt/gitea/env.sh + +# Gitea user +if ! id -u $GITEA_USER >/dev/null 2>&1; then + adduser \ + --system \ + --shell /bin/bash \ + --gecos 'Git Version Control' \ + --group \ + --disabled-password \ + --home /home/git \ + $GITEA_USER +fi +echo "---- Gitea user created ----" + +# Gitea folder structure +mkdir -p $GITEA_HOME/{custom,data,log} +chown -R $GITEA_USER:$GITEA_USER $GITEA_HOME +chmod -R 750 $GITEA_HOME + +if [ ! -f $GITEA_BINARY ]; then + wget -O /tmp/gitea "https://dl.gitea.com/gitea/$GITEA_VERSION/gitea-$GITEA_VERSION-linux-amd64" + chmod +x /tmp/gitea + mv /tmp/gitea $GITEA_BINARY +fi +echo "---- Gitea folder structure created ----" + +# Postgres initial config +DB_PASS=$(openssl rand -base64 12) +sudo -u postgres psql </dev/null 2>&1; then + echo "---- Backup found, restoring Gitea ----" + /usr/local/bin/restore-backup.sh +else + echo "---- No backup found in $GITEA_BACKUPS_DIR, skipping restore ----" +fi + +sudo chown -R $GITEA_USER:$GITEA_USER $GITEA_BACKUPS_DIR +sudo chmod -R 770 $GITEA_BACKUPS_DIR + +GITEA_SECRET_KEY=$("$GITEA_BINARY" generate secret SECRET_KEY) +GITEA_JWT_SECRET=$("$GITEA_BINARY" generate secret JWT_SECRET) +GITEA_INTERNAL_TOKEN=$("$GITEA_BINARY" generate secret INTERNAL_TOKEN) + +mkdir -p $(dirname "$GITEA_CONF") +cat > "$GITEA_CONF" </dev/null | sort | tail -n1) + +if [ -n "$LATEST_BACKUP" ] && [ -f "$LATEST_BACKUP" ]; then + TMP_DIR=$(mktemp -d) + unzip -o $LATEST_BACKUP -d $TMP_DIR + [ -d $TMP_DIR/data ] && cp -a $TMP_DIR/data/* /var/lib/gitea/data/ + [ -d $TMP_DIR/log ] && cp -a $TMP_DIR/log/* /var/lib/gitea/log/ + [ -d $TMP_DIR/repos ] && cp -aH $TMP_DIR/repos/. /var/lib/gitea/data/repositories/ + chown -R $GITEA_USER:$GITEA_USER $GITEA_HOME + sudo -u postgres psql -d $DB_NAME < $TMP_DIR/gitea-db.sql + sudo -u postgres psql -d "$DB_NAME" <