feat(id.tjo.space): changes

This commit is contained in:
Tine 2025-03-07 12:13:53 +01:00
parent 0bc4bdc5a0
commit 87029ef290
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
15 changed files with 172 additions and 78 deletions

12
.gitignore vendored
View file

@ -1,11 +1,9 @@
# Encrypted environment variables
env
*.env
!root/**/*.env
# ---> Dot ENV
.env
# Encrypted ssh keys
ssh
*.ssh
# ---> Secrets
**/secrets.env
!**/secrets.env.encrypted
# ---> Terraform
# Local .terraform directories

4
example.env Normal file
View file

@ -0,0 +1,4 @@
TF_VAR_hcloud_token=your_hcloud_token
TF_VAR_dnsimple_token=your_dnsimple_token
TF_VAR_dnsimple_account_id=your_dnsimple_account_id

View file

@ -0,0 +1,23 @@
AUTHENTIK_DISABLE_UPDATE_CHECK: false
AUTHENTIK_ERROR_REPORTING__ENABLED: false
AUTHENTIK_DISABLE_STARTUP_ANALYTICS: true
AUTHENTIK_AVATARS: initials
# AUTHENTIK_SECRET_KEY: "via secrets.env file"
AUTHENTIK_IMPERSONATION: "false"
AUTHENTIK_REDIS__HOST: valkey
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: id.tjo.space
AUTHENTIK_POSTGRESQL__NAME: id.tjo.space
# AUTHENTIK_POSTGRESQL__PASSWORD: "via secrets.env file"
AUTHENTIK_EMAIL__HOST: mail.tjo.space
AUTHENTIK_EMAIL__PORT: "587"
AUTHENTIK_EMAIL__USE_TLS: "true"
AUTHENTIK_EMAIL__FROM: id@tjo.space
AUTHENTIK_EMAIL__USERNAME: id@tjo.space
# AUTHENTIK_EMAIL__PASSWORD: "via secrets.env file"

View file

@ -2,7 +2,7 @@
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
{$DOMAIN_NAME}
next.id.tjo.space
respond /tjo-space/status "OK"

72
id.tjo.space/configure.sh Executable file
View file

@ -0,0 +1,72 @@
#!/bin/bash
set -euo pipefail
SERVICE_DIR="/root/service"
mkdir -p ${SERVICE_DIR}
cd ${SERVICE_DIR}
echo "== Fetch Source Code (from git)"
# Clone if not yet cloned
if [ ! -d .git ]; then
git clone \
--depth 1 \
--no-checkout \
--filter=tree:0 \
https://github.com/tjo-space/tjo-space-infrastructure.git .
git sparse-checkout set --no-cone /id.tjo.space
git checkout
else
git fetch --depth=1
git reset --hard origin/main
fi
echo "=== Configure Firewall"
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow 636/tcp # LDAPS
ufw --force enable
echo "=== Copy Configuration Files"
rsync -a id.tjo.space/containers/ /etc/containers/systemd/
rsync -a id.tjo.space/configs/ /etc/
systemctl daemon-reload
echo "=== Read Secrets"
age -d -i /etc/age/key.txt id.tjo.space/secrets.env.encrypted >id.tjo.space/secrets.env
set -a && source id.tjo.space/secrets.env && set +a
echo "=== Setup Caddy"
systemctl start caddy
echo "=== Setup Postgresql"
cat <<EOF >/etc/postgresql/secrets.env
POSTGRES_PASSWORD=${POSTGRESQL_PASSWORD}
EOF
systemctl start postgresql
echo "=== Setup Redis"
systemctl start redis
echo "=== Setup Authentik Server"
cat <<EOF >/etc/authentik/secrets.env
AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
AUTHENTIK_EMAIL__PASSWORD=${AUTHENTIK_EMAIL__PASSWORD}
AUTHENTIK_POSTGRESQL__PASSWORD=${POSTGRESQL_PASSWORD}
EOF
systemctl start authentik-server
echo "=== Setup Authentik Worker"
systemctl start authentik-worker
echo "=== Setup Authentik LDAP"
cat <<EOF >/etc/authentik/ldap.secrets.env
AUTHENTIK_TOKEN=${AUTHENTIK_LDAP_TOKEN}
EOF
systemctl start authentik-ldap

View file

@ -3,6 +3,9 @@ Description=An Authentik LDAP Server
[Container]
Image=ghcr.io/goauthentik/ldap:2025.2.1
Environment=AUTHENTIK_HOST=https://next.id.tjo.space
Environment=AUTHENTIK_INSECURE=false
EnvironmentFile=/etc/authentik/ldap.secrets.env
[Service]
Restart=always

View file

@ -3,6 +3,9 @@ Description=An Authentik Server
[Container]
Image=ghcr.io/goauthentik/authentik:2025.2.1
EnvironmentFile=/etc/authentik/authentik.env
EnvironmentFile=/etc/authentik/secrets.env
Volume=/media:/srv/authentik/media
[Service]
Restart=always

View file

@ -4,6 +4,8 @@ Description=An Authentik Worker
[Container]
Image=ghcr.io/goauthentik/authentik:2025.2.1
Exec=worker
EnvironmentFile=/etc/authentik/authentik.env
EnvironmentFile=/etc/authentik/secrets.env
[Service]
Restart=always

View file

@ -5,7 +5,7 @@ Description=A Caddy Container
Image=docker.io/caddy:2.9
PublishPort=443:443
PublishPort=80:80
Volume=/etc/caddy:/etc/caddy
Volume=/etc/caddy:/etc/caddy:ro
EnvironmentFile=/etc/caddy/env
[Service]

View file

@ -3,7 +3,10 @@ Description=A Postgresql Container
[Container]
Image=docker.io/postgresql:17.4
Volime=/var/lib/postgresql/data:/srv/postgresql/data
Volume=/var/lib/postgresql/data:/srv/postgresql/data
EnvironmentFile=/etc/postgresql/secrets.env
Environment=POSTGRES_USER=id.tjo.space
Environment=POSTGRES_DB=id.tjo.space
[Service]
Restart=always

View file

@ -1,51 +0,0 @@
#!/bin/bash
set -euo pipefail
SERVICE_DIR="/root/service"
mkdir -p ${SERVICE_DIR}
cd ${SERVICE_DIR}
echo "== Fetch Source Code (from git)"
# Clone if not yet cloned
if [ ! -d .git ]; then
git clone \
--depth 1 \
--no-checkout \
--filter=tree:0 \
https://github.com/tjo-space/tjo-space-infrastructure.git .
git sparse-checkout set --no-cone /id.tjo.space
git checkout
else
git fetch --depth=1
git reset --hard origin/main
fi
echo "=== Installing Dependencies"
DEBIAN_FRONTEND=noninteractive apt update -y
DEBIAN_FRONTEND=noninteractive apt install -y \
rsync \
jq \
podman
echo "=== Configure Firewall"
ufw allow 22/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow 636/tcp # LDAPS
ufw --force enable
echo "== Configure Metadata"
DOMAIN_NAME=$(jq -r ".domain" /etc/tjo.space/meta.json)
echo "=== Copy Configuration Files"
rsync -av id.tjo.space/containers/ /etc/containers/systemd/
rsync -av id.tjo.space/configs/ /etc/
systemctl daemon-reload
echo "=== Setup Caddy"
cat <<EOF >/etc/caddy/env
DOMAIN_NAME=${DOMAIN_NAME}
EOF
systemctl start caddy

View file

@ -1,6 +1,19 @@
default:
@just --list
secrets-encrypt:
#!/usr/bin/env sh
age --encrypt \
-r age1cl3d4wtrrqrgldmrzpu53q2mk60r7hrhrymsrwss8s57z4mdv9fst4a55h \
-r age1a4t9l73au9fqfk0x5kw6v06ewwpl0lurw73f3m60c5ly58r3hp5q6shdfr \
secrets.env > secrets.env.encrypted
secrets-decrypt:
#!/usr/bin/env sh
age --decrypt \
-i ${HOME}/.config/sops/age/keys.txt \
secrets.env.encrypted > secrets.env
apply:
#!/usr/bin/env sh
cd {{source_directory()}}/terraform
@ -17,20 +30,24 @@ outputs:
cd {{source_directory()}}/terraform
tofu output
ssh node:
provision node:
#!/usr/bin/env sh
set -eou pipefail
pushd {{source_directory()}}/terraform > /dev/null
IPV4=$(tofu output -json | jq -r '.ipv4[{{node}}]')
IPV4=$(tofu output -json | jq -r '.ipv4.value["{{node}}"]')
popd > /dev/null
ssh root@${IPV4}
echo "= Provision node: {{node}} (${IPV4})"
cat provision.sh | ssh -o StrictHostKeyChecking=no root@${IPV4} 'sudo bash -s'
configure node:
#!/usr/bin/env sh
set -eou pipefail
pushd {{source_directory()}}/terraform > /dev/null
IPV4=$(tofu output -json | jq -r '.ipv4[{{node}}]')
IPV4=$(tofu output -json | jq -r '.ipv4.value["{{node}}"]')
popd > /dev/null
echo "= Provisioning id.tjo.space"
cat install.sh | ssh root@${IPV4} 'sudo bash -s'
echo "= Configuring node: {{node}} (${IPV4})"
cat configure.sh | ssh -o StrictHostKeyChecking=no root@${IPV4} 'sudo bash -s'

16
id.tjo.space/provision.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/bash
set -euo pipefail
pushd "$(mktemp -d)"
echo "=== Installing Dependencies"
DEBIAN_FRONTEND=noninteractive apt update -y
DEBIAN_FRONTEND=noninteractive apt install -y \
rsync \
jq \
podman \
age
echo "=== Generating Age Key"
mkdir -p /etc/age
age-keygen -o /etc/age/key.txt

Binary file not shown.

View file

@ -40,6 +40,9 @@ resource "hcloud_server" "main" {
- path: /etc/tjo.space/meta.json
encoding: base64
content: ${base64encode(jsonencode(each.value.meta))}
- path: /tmp/provision.sh
encoding: base64
content: ${base64encode(file("${path.module}/../provision.sh"))}
packages:
- git
- curl
@ -51,7 +54,9 @@ resource "hcloud_server" "main" {
filename: /swapfile
size: 512M
runcmd:
- "curl -sL https://raw.githubusercontent.com/tjo-space/tjo-space-infrastructure/refs/heads/main/id.tjo.space/install.sh | bash"
- "chmod +x /tmp/provision.sh"
- "/tmp/provision.sh"
- "rm /tmp/provision.sh"
EOF
}
@ -65,13 +70,12 @@ resource "dnsimple_zone_record" "a" {
ttl = 300
}
# Podman is PITA!
#resource "dnsimple_zone_record" "aaaa" {
# for_each = local.nodes
#
# zone_name = "tjo.space"
# name = trimsuffix(each.value.meta.domain, ".tjo.space")
# value = hcloud_server.main[each.key].ipv6_address
# type = "AAAA"
# ttl = 300
#}
resource "dnsimple_zone_record" "aaaa" {
for_each = local.nodes
zone_name = "tjo.space"
name = trimsuffix(each.value.meta.domain, ".tjo.space")
value = hcloud_server.main[each.key].ipv6_address
type = "AAAA"
ttl = 300
}