diff --git a/.gitignore b/.gitignore index bcef331..3a4f7e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # Terraform directories -**/.terraform/ \ No newline at end of file +**/.terraform/ +**/terraform/ \ No newline at end of file diff --git a/home/ansible/ansible.cfg b/home/ansible/ansible.cfg new file mode 100644 index 0000000..a0e4d4f --- /dev/null +++ b/home/ansible/ansible.cfg @@ -0,0 +1,7 @@ +[defaults] +inventory = inventory.yml +host_key_checking = False +retry_files_enabled = False + +[ssh_connection] +ssh_args = -o ControlMaster=auto -o ControlPersist=60s \ No newline at end of file diff --git a/home/ansible/bootstrap-almalinux.yml b/home/ansible/bootstrap-almalinux.yml new file mode 100644 index 0000000..041a35a --- /dev/null +++ b/home/ansible/bootstrap-almalinux.yml @@ -0,0 +1,72 @@ +--- +- name: Bootstrap AlmaLinux server for Ansible management + hosts: caddy + become: yes + vars: + ansible_user: graham # Connect as graham initially + + tasks: + - name: Create ansible user + user: + name: ansible + uid: 10001 + shell: /bin/bash + home: /home/ansible + create_home: yes + state: present + + - name: Add ansible user to wheel group + user: + name: ansible + groups: wheel + append: yes + + - name: Ensure .ssh directory exists for ansible user + file: + path: /home/ansible/.ssh + state: directory + owner: ansible + group: ansible + mode: "0700" + + - name: Add ansible SSH key to ansible user + authorized_key: + user: ansible + key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFghGMnDdkfNC6JPEhMxrKhYDmNcXjHXp/y/mf3uLtzb graham@mbp14.local" + state: present + + - name: Add SSH keys from GitHub to graham user + authorized_key: + user: graham + key: "https://github.com/gmcintire.keys" + state: present + + - name: Configure passwordless sudo for ansible user + copy: + content: "ansible ALL=(ALL) NOPASSWD: ALL" + dest: /etc/sudoers.d/ansible + mode: "0440" + validate: "visudo -cf %s" + + - name: Install Python 3 (required for Ansible) + dnf: + name: + - python3 + - python3-pip + state: present + + - name: Set Python 3 as default python + alternatives: + name: python + link: /usr/bin/python + path: /usr/bin/python3 + + - name: Verify ansible user can sudo + command: sudo -u ansible sudo -l + changed_when: false + register: sudo_test + + - name: Show sudo verification + debug: + msg: "Ansible user sudo access verified" + when: sudo_test.rc == 0 \ No newline at end of file diff --git a/home/ansible/caddy-almalinux.yml b/home/ansible/caddy-almalinux.yml new file mode 100644 index 0000000..909b917 --- /dev/null +++ b/home/ansible/caddy-almalinux.yml @@ -0,0 +1,177 @@ +--- +- name: Configure Caddy reverse proxy with Tailscale on AlmaLinux 10 + hosts: caddy + become: yes + gather_facts: yes + strategy: free + vars: + tailscale_key: "{{ lookup('env', 'TAILSCALE_KEY') }}" + + tasks: + - name: Enable passwordless sudo on AlmaLinux + ansible.builtin.lineinfile: + path: /etc/sudoers + state: present + regexp: "^%wheel" + line: "%wheel ALL=(ALL) NOPASSWD: ALL" + validate: "visudo -cf %s" + + - name: Clean up repository files + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: + - /etc/yum.repos.d/caddy.repo + - /etc/yum.repos.d/tailscale-stable.repo + when: false # Only enable if you have issues + + - name: Check if EPEL is already installed + ansible.builtin.stat: + path: /etc/yum.repos.d/epel.repo + register: epel_check + + - name: Install EPEL repo + ansible.builtin.dnf: + name: epel-release + state: present + when: not epel_check.stat.exists + + - name: Check if Caddy COPR repo exists + ansible.builtin.stat: + path: /etc/yum.repos.d/_copr:copr.fedorainfracloud.org:group_caddy:caddy.repo + register: caddy_repo_check + + - name: Add Caddy COPR repository + ansible.builtin.command: + cmd: dnf copr enable -y @caddy/caddy + when: not caddy_repo_check.stat.exists + + - name: Install all required packages in one transaction + ansible.builtin.dnf: + state: present + name: + - caddy + - firewalld + - htop + - rsync + - tmux + - tar + - unzip + - python3-libsemanage + - python3-policycoreutils + update_cache: yes + + - name: Enable and start firewalld + service: + name: firewalld + state: started + enabled: yes + + - name: Configure firewall for Caddy + firewalld: + port: "{{ item }}" + permanent: yes + state: enabled + immediate: yes + loop: + - "80/tcp" + - "443/tcp" + - "22/tcp" + + - name: Check if Tailscale is installed + command: which tailscale + register: tailscale_check + changed_when: false + failed_when: false + + - name: Install Tailscale on AlmaLinux + block: + - name: Add Tailscale repository + yum_repository: + name: tailscale-stable + description: Tailscale stable + baseurl: https://pkgs.tailscale.com/stable/centos/9/$basearch + repo_gpgcheck: yes + gpgcheck: yes + enabled: yes + gpgkey: https://pkgs.tailscale.com/stable/centos/9/repo.gpg + + - name: Install Tailscale + dnf: + name: tailscale + state: present + + - name: Enable and start Tailscale daemon + service: + name: tailscaled + state: started + enabled: yes + when: tailscale_check.rc != 0 + + - name: Allow Tailscale through firewall + firewalld: + port: 41641/udp + permanent: yes + state: enabled + immediate: yes + + - name: Check if Tailscale is already authenticated + command: tailscale status --json + register: tailscale_status_check + changed_when: false + failed_when: false + + - name: Authenticate Tailscale + command: tailscale up --authkey="{{ tailscale_key }}" --accept-routes --hostname=caddy + when: + - tailscale_key is defined + - tailscale_key != "" + - tailscale_status_check.rc != 0 or (tailscale_status_check.stdout | from_json).BackendState != "Running" + register: tailscale_auth + failed_when: false + ignore_errors: yes + + - name: Get Tailscale status + command: tailscale status + register: tailscale_final_status + changed_when: false + failed_when: false + + - name: Show final Tailscale status + debug: + var: tailscale_final_status.stdout_lines + + - name: Enable and start Caddy + service: + name: caddy + state: started + enabled: yes + + - name: Deploy Caddyfile configuration + template: + src: templates/Caddyfile.j2 + dest: /etc/caddy/Caddyfile + owner: caddy + group: caddy + mode: "0644" + backup: yes + notify: reload caddy + + - name: SELinux - Allow Caddy to proxy + seboolean: + name: httpd_can_network_connect + state: yes + persistent: yes + + - name: SELinux - Allow Caddy to bind to ports + seport: + ports: "80,443" + proto: tcp + setype: http_port_t + state: present + + handlers: + - name: reload caddy + service: + name: caddy + state: reloaded \ No newline at end of file diff --git a/home/ansible/check-and-install-postgis.yml b/home/ansible/check-and-install-postgis.yml new file mode 100644 index 0000000..b2b47e6 --- /dev/null +++ b/home/ansible/check-and-install-postgis.yml @@ -0,0 +1,40 @@ +--- +- name: Check and Install PostGIS + hosts: lab02 + become: true + vars: + ct_id: 300 + + tasks: + - name: Check PostgreSQL version + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -c "SELECT version();" + register: pg_version + + - name: Update apt cache in container + command: pct exec {{ ct_id }} -- bash -c "apt-get update" + + - name: Search for PostGIS packages + command: pct exec {{ ct_id }} -- bash -c "apt-cache search postgis | grep postgresql" + register: postgis_packages + + - name: Display available packages + debug: + msg: | + PostgreSQL Version: + {{ pg_version.stdout }} + + Available PostGIS packages: + {{ postgis_packages.stdout }} + + - name: Install PostGIS (flexible version) + command: pct exec {{ ct_id }} -- bash -c "apt-get install -y postgis" + register: install_result + + - name: Enable PostGIS in APRS database + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;" + + - name: Display installation result + debug: + msg: "PostGIS installation completed!" \ No newline at end of file diff --git a/home/ansible/enable-postgis-simple.yml b/home/ansible/enable-postgis-simple.yml new file mode 100644 index 0000000..a223e45 --- /dev/null +++ b/home/ansible/enable-postgis-simple.yml @@ -0,0 +1,33 @@ +--- +- name: Enable PostGIS Extension + hosts: lab02 + become: true + vars: + ct_id: 300 + + tasks: + - name: Try to enable PostGIS extension + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;" + register: postgis_enable + ignore_errors: yes + + - name: Install PostGIS for PostgreSQL 15 if extension failed + command: pct exec {{ ct_id }} -- bash -c "apt-get install -y postgresql-15-postgis-3 || apt-get install -y postgis postgresql-postgis" + when: postgis_enable.rc != 0 + register: install_result + ignore_errors: yes + + - name: Try to enable PostGIS again if it was just installed + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;" + when: postgis_enable.rc != 0 + + - name: Show results + debug: + msg: | + {% if postgis_enable.rc == 0 %} + PostGIS extension enabled successfully! + {% else %} + PostGIS installation attempt: {{ install_result.stderr | default('') }} + {% endif %} \ No newline at end of file diff --git a/home/ansible/enable-postgis.yml b/home/ansible/enable-postgis.yml new file mode 100644 index 0000000..b93842a --- /dev/null +++ b/home/ansible/enable-postgis.yml @@ -0,0 +1,45 @@ +--- +- name: Enable PostGIS in APRS Database + hosts: lab02 + become: true + vars: + ct_id: 300 + + tasks: + - name: Check if PostGIS is installed + command: | + pct exec {{ ct_id }} -- dpkg -l | grep postgis + register: postgis_check + ignore_errors: yes + + - name: Install PostGIS if not present + command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3 postgresql-16-postgis-3-scripts + when: postgis_check.rc != 0 + + - name: Enable PostGIS extension in APRS database + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;" + register: postgis_result + + - name: Enable PostGIS topology extension + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis_topology;" + ignore_errors: yes + + - name: Verify PostGIS installation + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT PostGIS_Version();" + register: postgis_version + ignore_errors: yes + + - name: Display results + debug: + msg: | + PostGIS setup completed! + + Extension creation: {{ postgis_result.stdout | default('Done') }} + {% if postgis_version.rc == 0 %} + PostGIS Version: {{ postgis_version.stdout }} + {% else %} + Note: PostGIS may require package installation + {% endif %} \ No newline at end of file diff --git a/home/ansible/install-postgis.yml b/home/ansible/install-postgis.yml new file mode 100644 index 0000000..c77fd4d --- /dev/null +++ b/home/ansible/install-postgis.yml @@ -0,0 +1,35 @@ +--- +- name: Install PostGIS in PostgreSQL LXC + hosts: lab02 + become: true + vars: + ct_id: 300 + + tasks: + - name: Update apt cache + command: pct exec {{ ct_id }} -- apt-get update + + - name: Install PostGIS package + command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3 + + - name: Enable PostGIS extension in APRS database + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;" + + - name: Enable PostGIS topology extension + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis_topology;" + + - name: Verify PostGIS installation + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT PostGIS_Version();" + register: postgis_version + + - name: Display PostGIS version + debug: + msg: | + PostGIS has been installed successfully! + + Version: {{ postgis_version.stdout }} + + The APRS database now has spatial capabilities for location data. \ No newline at end of file diff --git a/home/ansible/inventory.yml b/home/ansible/inventory.yml index 605d653..c552bb2 100644 --- a/home/ansible/inventory.yml +++ b/home/ansible/inventory.yml @@ -38,17 +38,12 @@ all: ansible_python_interpreter: /usr/bin/python3 ansible_ssh_common_args: "-o StrictHostKeyChecking=no" k3s_version: v1.28.5+k3s1 - vultr: - hosts: - caddy: - ansible_host: "caddy.w5isp.com" - vars: - ansible_user: root # Initial connection as root to create users - ansible_python_interpreter: /usr/bin/python3 - ansible_ssh_common_args: "-o StrictHostKeyChecking=no" caddy_servers: hosts: caddy: + ansible_host: 204.110.191.212 vars: - ansible_user: root # Will switch to ansible user after creation - ansible_python_interpreter: /usr/bin/python3 \ No newline at end of file + ansible_user: ansible # Now using ansible user after bootstrap + ansible_ssh_private_key_file: "~/.ssh/ansible" + ansible_python_interpreter: /usr/bin/python3 + ansible_ssh_common_args: "-o StrictHostKeyChecking=no" \ No newline at end of file diff --git a/home/ansible/setup-aprs-database.yml b/home/ansible/setup-aprs-database.yml new file mode 100644 index 0000000..5ffb2bb --- /dev/null +++ b/home/ansible/setup-aprs-database.yml @@ -0,0 +1,50 @@ +--- +- name: Setup APRS Database in PostgreSQL LXC + hosts: lab02 + become: true + vars: + ct_id: 300 + + tasks: + - name: Create APRS database and user + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -c "CREATE USER aprs WITH PASSWORD 'xK9mP2vQ7sR3nL5w';" + ignore_errors: yes + register: create_user + + - name: Create APRS database + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -c "CREATE DATABASE aprs OWNER aprs;" + ignore_errors: yes + register: create_db + + - name: Grant privileges on APRS database + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "GRANT ALL PRIVILEGES ON DATABASE aprs TO aprs; GRANT ALL ON SCHEMA public TO aprs;" + + - name: Test APRS database connection + command: | + pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT current_database(), current_user;" + register: db_test + + - name: Display results + debug: + msg: | + APRS database setup completed! + + User creation: {{ 'Created' if create_user.rc == 0 else 'Already exists or failed' }} + Database creation: {{ 'Created' if create_db.rc == 0 else 'Already exists or failed' }} + + Connection details: + - Host: 10.0.19.5 + - Port: 5432 + - Database: aprs + - User: aprs + - Password: xK9mP2vQ7sR3nL5w + + Connection test output: + {{ db_test.stdout }} + + Connection strings: + - PostgreSQL: postgresql://aprs:xK9mP2vQ7sR3nL5w@10.0.19.5:5432/aprs + - Ecto: ecto://aprs:xK9mP2vQ7sR3nL5w@10.0.19.5:5432/aprs \ No newline at end of file diff --git a/home/ansible/templates/Caddyfile.j2 b/home/ansible/templates/Caddyfile.j2 new file mode 100644 index 0000000..19b170a --- /dev/null +++ b/home/ansible/templates/Caddyfile.j2 @@ -0,0 +1,18 @@ +# Caddy reverse proxy configuration +# Managed by Ansible - do not edit manually + +# Forgejo Git server +git.w5isp.com { + # Caddy will automatically obtain Let's Encrypt certificates + + reverse_proxy http://100.109.233.14 { + # Tell backend that SSL is handled by proxy + header_up Host {host} + header_up X-Real-IP {remote} + header_up X-Forwarded-Proto https + header_up X-Forwarded-Port 443 + + } +} + +# Add more entries below as needed \ No newline at end of file diff --git a/home/ansible/upgrade-postgres-simple.yml b/home/ansible/upgrade-postgres-simple.yml new file mode 100644 index 0000000..00b5a87 --- /dev/null +++ b/home/ansible/upgrade-postgres-simple.yml @@ -0,0 +1,53 @@ +--- +- name: Upgrade PostgreSQL to 16 and Install PostGIS + hosts: lab02 + become: true + vars: + ct_id: 300 + + tasks: + - name: Add PostgreSQL APT repository + command: pct exec {{ ct_id }} -- bash -c "wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O- | apt-key add - && echo 'deb http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main' > /etc/apt/sources.list.d/pgdg.list" + + - name: Update apt cache + command: pct exec {{ ct_id }} -- apt-get update -qq + + - name: Install PostgreSQL 16 + command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16 postgresql-client-16 + + - name: Check current PostgreSQL clusters + command: pct exec {{ ct_id }} -- pg_lsclusters + register: clusters + + - name: Display current clusters + debug: + msg: "{{ clusters.stdout }}" + + - name: Drop old PostgreSQL 16 cluster if exists + command: pct exec {{ ct_id }} -- pg_dropcluster 16 main --stop + ignore_errors: yes + + - name: Upgrade cluster from 15 to 16 + command: pct exec {{ ct_id }} -- pg_upgradecluster 15 main + + - name: Install PostGIS for PostgreSQL 16 + command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3 + + - name: Enable PostGIS in APRS database + command: pct exec {{ ct_id }} -- sudo -u postgres psql -p 5433 -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;" + + - name: Switch to port 5432 for PostgreSQL 16 + command: pct exec {{ ct_id }} -- bash -c "sed -i 's/port = 5433/port = 5432/' /etc/postgresql/16/main/postgresql.conf && systemctl restart postgresql@16-main" + + - name: Stop PostgreSQL 15 + command: pct exec {{ ct_id }} -- systemctl stop postgresql@15-main + + - name: Verify upgrade + command: pct exec {{ ct_id }} -- sudo -u postgres psql -c "SELECT version();" + register: version + + - name: Display results + debug: + msg: | + PostgreSQL upgrade completed! + {{ version.stdout }} \ No newline at end of file diff --git a/home/ansible/upgrade-postgres-to-16.yml b/home/ansible/upgrade-postgres-to-16.yml new file mode 100644 index 0000000..f2e2b8d --- /dev/null +++ b/home/ansible/upgrade-postgres-to-16.yml @@ -0,0 +1,71 @@ +--- +- name: Upgrade PostgreSQL 15 to 16 in LXC + hosts: lab02 + become: true + vars: + ct_id: 300 + + tasks: + - name: Stop PostgreSQL 15 service + command: pct exec {{ ct_id }} -- systemctl stop postgresql@15-main + + - name: Add PostgreSQL APT repository key + command: pct exec {{ ct_id }} -- bash -c "wget -q -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -" + + - name: Add PostgreSQL APT repository + command: pct exec {{ ct_id }} -- bash -c "echo 'deb http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main' > /etc/apt/sources.list.d/pgdg.list" + + - name: Update apt cache + command: pct exec {{ ct_id }} -- apt-get update + + - name: Install PostgreSQL 16 + command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16 postgresql-client-16 postgresql-contrib-16 + + - name: Stop PostgreSQL 16 (auto-started after install) + command: pct exec {{ ct_id }} -- systemctl stop postgresql@16-main + + - name: Upgrade the cluster from 15 to 16 + command: pct exec {{ ct_id }} -- sudo -u postgres /usr/lib/postgresql/16/bin/pg_upgrade -b /usr/lib/postgresql/15/bin -B /usr/lib/postgresql/16/bin -d /var/lib/postgresql/15/main -D /var/lib/postgresql/16/main -o "-c config_file=/etc/postgresql/15/main/postgresql.conf" -O "-c config_file=/etc/postgresql/16/main/postgresql.conf" + + - name: Copy PostgreSQL 15 configuration + command: pct exec {{ ct_id }} -- bash -c "cp /etc/postgresql/15/main/postgresql.conf /etc/postgresql/16/main/ && cp /etc/postgresql/15/main/pg_hba.conf /etc/postgresql/16/main/" + + - name: Update PostgreSQL 16 port to 5432 + command: pct exec {{ ct_id }} -- sed -i "s/port = 5433/port = 5432/" /etc/postgresql/16/main/postgresql.conf + + - name: Start PostgreSQL 16 + command: pct exec {{ ct_id }} -- systemctl start postgresql@16-main + + - name: Enable PostgreSQL 16 + command: pct exec {{ ct_id }} -- systemctl enable postgresql@16-main + + - name: Disable PostgreSQL 15 + command: pct exec {{ ct_id }} -- systemctl disable postgresql@15-main + + - name: Install PostGIS for PostgreSQL 16 + command: pct exec {{ ct_id }} -- apt-get install -y postgresql-16-postgis-3 + + - name: Enable PostGIS in APRS database + command: pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "CREATE EXTENSION IF NOT EXISTS postgis;" + + - name: Enable PostGIS in Forgejo database (if needed) + command: pct exec {{ ct_id }} -- sudo -u postgres psql -d forgejo -c "CREATE EXTENSION IF NOT EXISTS postgis;" + ignore_errors: yes + + - name: Verify PostgreSQL version + command: pct exec {{ ct_id }} -- sudo -u postgres psql -c "SELECT version();" + register: pg_version + + - name: Verify PostGIS installation + command: pct exec {{ ct_id }} -- sudo -u postgres psql -d aprs -c "SELECT PostGIS_Version();" + register: postgis_version + + - name: Display results + debug: + msg: | + PostgreSQL upgrade completed! + + {{ pg_version.stdout }} + + PostGIS Version in APRS database: + {{ postgis_version.stdout }} \ No newline at end of file diff --git a/home/cluster/aprs/aprs-secret.yaml b/home/cluster/aprs/aprs-secret.yaml index 75b623d..ce5fdf4 100644 --- a/home/cluster/aprs/aprs-secret.yaml +++ b/home/cluster/aprs/aprs-secret.yaml @@ -6,9 +6,9 @@ metadata: type: Opaque stringData: database-password: "xK9mP2vQ7sR3nL5w" - # Direct connection to PostgreSQL on CM3588 - database-url: "ecto://aprs:xK9mP2vQ7sR3nL5w@10.0.19.220:5432/aprs" - # Connection via PgBouncer on CM3588 (recommended) - database-url-pgbouncer: "ecto://aprs:xK9mP2vQ7sR3nL5w@10.0.19.220:6432/aprs" + # Direct connection to PostgreSQL VM + database-url: "ecto://aprs:xK9mP2vQ7sR3nL5w@10.0.19.5:5432/aprs" + # Connection via PgBouncer on PostgreSQL VM (if available) + database-url-pgbouncer: "ecto://aprs:xK9mP2vQ7sR3nL5w@10.0.19.5:6432/aprs" erlang-cookie: "aprs-cluster-cookie-ksdf8934jfklsdjf983jfklsdf" secret-key-base: "GJxzOUW3YXBAF7xB4mH5VcXY6BN1NYLnoJYadlZyiCxcRUGBw65w4Sco7+sNiW2t" \ No newline at end of file diff --git a/home/cluster/aprs/aprs-statefulset.yaml b/home/cluster/aprs/aprs-statefulset.yaml index 718357b..36197ee 100644 --- a/home/cluster/aprs/aprs-statefulset.yaml +++ b/home/cluster/aprs/aprs-statefulset.yaml @@ -52,8 +52,8 @@ spec: - sh - -c - | - echo "Waiting for PostgreSQL at 10.0.19.220:5432..." - until nc -z 10.0.19.220 5432; do + echo "Waiting for PostgreSQL at 10.0.19.5:5432..." + until nc -z 10.0.19.5 5432; do echo "Database not ready, waiting..." sleep 2 done diff --git a/home/cluster/aprs/create-ghcr-secret.sh b/home/cluster/aprs/create-ghcr-secret.sh new file mode 100755 index 0000000..ce6f98f --- /dev/null +++ b/home/cluster/aprs/create-ghcr-secret.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Script to create GitHub Container Registry pull secret for APRS + +echo "This script will help you create a GitHub Container Registry pull secret" +echo "You need:" +echo "1. Your GitHub username" +echo "2. A GitHub Personal Access Token (PAT) with 'read:packages' scope" +echo "" +echo "To create a PAT:" +echo "1. Go to https://github.com/settings/tokens" +echo "2. Click 'Generate new token (classic)'" +echo "3. Select 'read:packages' scope" +echo "4. Generate the token" +echo "" + +read -p "Enter your GitHub username: " GITHUB_USERNAME +read -s -p "Enter your GitHub PAT: " GITHUB_PAT +echo "" + +kubectl create secret docker-registry ghcr-pull-secret \ + --docker-server=ghcr.io \ + --docker-username=$GITHUB_USERNAME \ + --docker-password=$GITHUB_PAT \ + --docker-email="${GITHUB_USERNAME}@users.noreply.github.com" \ + --namespace=aprs \ + --dry-run=client -o yaml | kubectl apply -f - + +echo "Secret created/updated successfully!" \ No newline at end of file diff --git a/home/cluster/aprs/install-postgis-manual.sh b/home/cluster/aprs/install-postgis-manual.sh new file mode 100644 index 0000000..87bdf54 --- /dev/null +++ b/home/cluster/aprs/install-postgis-manual.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Manual commands to install PostGIS on the PostgreSQL LXC container + +echo "Run these commands on the Proxmox host (lab02):" +echo "" +echo "# 1. Update package list in the container" +echo "pct exec 300 -- apt-get update" +echo "" +echo "# 2. Install PostGIS for PostgreSQL 15" +echo "pct exec 300 -- apt-get install -y postgresql-15-postgis-3" +echo "" +echo "# 3. Enable PostGIS extension in the APRS database" +echo "pct exec 300 -- sudo -u postgres psql -d aprs -c 'CREATE EXTENSION IF NOT EXISTS postgis;'" +echo "" +echo "# 4. Verify installation" +echo "pct exec 300 -- sudo -u postgres psql -d aprs -c 'SELECT PostGIS_Version();'" +echo "" +echo "After running these commands, the APRS migrations should work." \ No newline at end of file diff --git a/home/cluster/aprs/redis.yaml b/home/cluster/aprs/redis.yaml new file mode 100644 index 0000000..d5bc7e1 --- /dev/null +++ b/home/cluster/aprs/redis.yaml @@ -0,0 +1,73 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: aprs + labels: + app: redis +spec: + ports: + - port: 6379 + targetPort: 6379 + name: redis + selector: + app: redis +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: redis-data + namespace: aprs +spec: + accessModes: + - ReadWriteOnce + storageClassName: ceph-rbd + resources: + requests: + storage: 10Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis + namespace: aprs +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: redis:7-alpine + command: + - redis-server + - --appendonly + - "yes" + - --save + - "900 1" + - --save + - "300 10" + - --save + - "60 10000" + ports: + - containerPort: 6379 + name: redis + resources: + requests: + memory: "256Mi" + cpu: "100m" + limits: + memory: "512Mi" + cpu: "500m" + volumeMounts: + - name: redis-storage + mountPath: /data + volumes: + - name: redis-storage + persistentVolumeClaim: + claimName: redis-data \ No newline at end of file diff --git a/home/cluster/aprs/setup-database.sh b/home/cluster/aprs/setup-database.sh new file mode 100755 index 0000000..47ac527 --- /dev/null +++ b/home/cluster/aprs/setup-database.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Setup APRS database on PostgreSQL VM + +set -e + +POSTGRES_HOST="10.0.19.5" +POSTGRES_USER="postgres" +APRS_USER="aprs" +APRS_PASSWORD="xK9mP2vQ7sR3nL5w" +APRS_DATABASE="aprs" + +echo "Setting up APRS database on PostgreSQL server at $POSTGRES_HOST" +echo "This requires the postgres user password or SSH access to the PostgreSQL VM" +echo "" + +# Create the SQL commands +SQL_COMMANDS=" +-- Create APRS user +CREATE USER $APRS_USER WITH PASSWORD '$APRS_PASSWORD'; + +-- Create APRS database +CREATE DATABASE $APRS_DATABASE OWNER $APRS_USER; + +-- Grant privileges +GRANT ALL PRIVILEGES ON DATABASE $APRS_DATABASE TO $APRS_USER; +" + +# Option 1: Try with psql directly (requires postgres password) +echo "Attempting to connect to PostgreSQL directly..." +echo "$SQL_COMMANDS" | psql -h $POSTGRES_HOST -U $POSTGRES_USER -d postgres 2>/dev/null && { + echo "✓ Database setup completed successfully!" + echo "" + echo "Connection details:" + echo " Host: $POSTGRES_HOST" + echo " Database: $APRS_DATABASE" + echo " User: $APRS_USER" + echo " Password: $APRS_PASSWORD" + echo "" + echo "Connection string:" + echo " ecto://$APRS_USER:$APRS_PASSWORD@$POSTGRES_HOST:5432/$APRS_DATABASE" + exit 0 +} + +# If direct connection fails, provide manual instructions +echo "Could not connect directly. Please run these commands on the PostgreSQL server:" +echo "" +echo "sudo -u postgres psql << EOF" +echo "$SQL_COMMANDS" +echo "EOF" +echo "" +echo "Or SSH to the PostgreSQL VM and run:" +echo " ssh @$POSTGRES_HOST" +echo " sudo -u postgres psql" +echo " Then paste the following:" +echo "$SQL_COMMANDS" \ No newline at end of file diff --git a/home/cluster/aprs/setup-postgres-aprs.sql b/home/cluster/aprs/setup-postgres-aprs.sql new file mode 100644 index 0000000..dd70ff0 --- /dev/null +++ b/home/cluster/aprs/setup-postgres-aprs.sql @@ -0,0 +1,25 @@ +-- Setup script for APRS database on PostgreSQL VM (10.0.19.5) +-- Run this as the postgres superuser + +-- Create the aprs user with the password from the Kubernetes secret +CREATE USER aprs WITH PASSWORD 'xK9mP2vQ7sR3nL5w'; + +-- Create the aprs database owned by the aprs user +CREATE DATABASE aprs OWNER aprs; + +-- Connect to the aprs database +\c aprs + +-- Grant all privileges on the aprs database to the aprs user +GRANT ALL PRIVILEGES ON DATABASE aprs TO aprs; + +-- Create schema and grant privileges +GRANT ALL ON SCHEMA public TO aprs; + +-- If you need PostGIS extensions (for APRS location data), uncomment: +-- CREATE EXTENSION IF NOT EXISTS postgis; +-- CREATE EXTENSION IF NOT EXISTS postgis_topology; + +-- Verify the setup +\du aprs +\l aprs \ No newline at end of file diff --git a/home/cluster/forgejo-complete.yaml b/home/cluster/forgejo-complete.yaml index 57cc906..8587ba2 100644 --- a/home/cluster/forgejo-complete.yaml +++ b/home/cluster/forgejo-complete.yaml @@ -66,7 +66,7 @@ spec: - name: FORGEJO__database__PASSWD value: fj8K3n2Qp9Lx5mW7 - name: FORGEJO__server__ROOT_URL - value: http://git.tail683b6.ts.net/ + value: https://git.tail683b6.ts.net/ - name: FORGEJO__server__DOMAIN value: git.tail683b6.ts.net - name: FORGEJO__server__SSH_DOMAIN @@ -118,6 +118,7 @@ metadata: tailscale.com/expose: "true" tailscale.com/hostname: "git" tailscale.com/tags: "tag:k8s" + tailscale.com/funnel: "true" spec: type: LoadBalancer loadBalancerClass: tailscale diff --git a/home/cluster/forgejo-proxy-config.yaml b/home/cluster/forgejo-proxy-config.yaml new file mode 100644 index 0000000..792d04b --- /dev/null +++ b/home/cluster/forgejo-proxy-config.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: forgejo-proxy-config + namespace: forgejo +data: + app.ini: | + [server] + PROTOCOL = http + HTTP_PORT = 3000 + ROOT_URL = https://git.w5isp.com/ + DISABLE_SSH = false + SSH_PORT = 22 + START_SSH_SERVER = true + OFFLINE_MODE = false + # Disable HTTPS redirect since proxy handles SSL + REDIRECT_OTHER_PORT = false + PORT_TO_REDIRECT = 0 + + # Trust proxy headers + REVERSE_PROXY_LIMIT = 1 + REVERSE_PROXY_TRUSTED_PROXIES = 100.109.233.14,204.110.191.212,100.0.0.0/8 + + [service] + DISABLE_REGISTRATION = false + REQUIRE_SIGNIN_VIEW = false \ No newline at end of file diff --git a/home/cluster/forgejo-tailscale-service.yaml b/home/cluster/forgejo-tailscale-service.yaml new file mode 100644 index 0000000..0e936db --- /dev/null +++ b/home/cluster/forgejo-tailscale-service.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + name: forgejo-tailscale + namespace: forgejo + annotations: + tailscale.com/expose: "true" + tailscale.com/hostname: "git" + tailscale.com/funnel: "true" +spec: + type: LoadBalancer + loadBalancerClass: tailscale + selector: + app: forgejo + ports: + - name: http + port: 80 + targetPort: 3000 + protocol: TCP + - name: ssh + port: 22 + targetPort: 2222 + protocol: TCP \ No newline at end of file diff --git a/home/cluster/forgejo-update-config.yaml b/home/cluster/forgejo-update-config.yaml new file mode 100644 index 0000000..2df4b15 --- /dev/null +++ b/home/cluster/forgejo-update-config.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: forgejo + namespace: forgejo +spec: + template: + spec: + containers: + - name: forgejo + volumeMounts: + - mountPath: /data + name: data + - mountPath: /data/gitea/conf + name: config + volumes: + - name: data + persistentVolumeClaim: + claimName: forgejo-data-rbd-dynamic + - name: config + configMap: + name: forgejo-proxy-config \ No newline at end of file diff --git a/home/cluster/forgejo/deployment.yaml b/home/cluster/forgejo/deployment.yaml index d53b695..fca4bc4 100644 --- a/home/cluster/forgejo/deployment.yaml +++ b/home/cluster/forgejo/deployment.yaml @@ -41,11 +41,11 @@ spec: - name: FORGEJO__database__PASSWD value: fj8K3n2Qp9Lx5mW7 - name: FORGEJO__server__ROOT_URL - value: http://10.0.19.3/ + value: https://git.tail683b6.ts.net/ - name: FORGEJO__server__DOMAIN - value: "10.0.19.3" + value: git.tail683b6.ts.net - name: FORGEJO__server__SSH_DOMAIN - value: "10.0.19.3" + value: git.tail683b6.ts.net - name: FORGEJO__DEFAULT__APP_NAME value: "w5isp's code" volumeMounts: diff --git a/home/cluster/forgejo/ingress-tailscale-fixed.yaml b/home/cluster/forgejo/ingress-tailscale-fixed.yaml new file mode 100644 index 0000000..3faa89a --- /dev/null +++ b/home/cluster/forgejo/ingress-tailscale-fixed.yaml @@ -0,0 +1,15 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: forgejo + namespace: forgejo +spec: + defaultBackend: + service: + name: forgejo + port: + number: 80 + ingressClassName: tailscale + tls: + - hosts: + - git \ No newline at end of file diff --git a/home/cluster/forgejo/ingress-tailscale.yaml b/home/cluster/forgejo/ingress-tailscale.yaml index 08b3d95..2550510 100644 --- a/home/cluster/forgejo/ingress-tailscale.yaml +++ b/home/cluster/forgejo/ingress-tailscale.yaml @@ -3,6 +3,9 @@ kind: Ingress metadata: name: forgejo-tailscale namespace: forgejo + annotations: + tailscale.com/hostname: "git" + tailscale.com/tags: "tag:k8s" spec: ingressClassName: tailscale defaultBackend: @@ -12,4 +15,4 @@ spec: number: 80 tls: - hosts: - - forgejo \ No newline at end of file + - git \ No newline at end of file diff --git a/home/cluster/forgejo/service-tailscale-https.yaml b/home/cluster/forgejo/service-tailscale-https.yaml new file mode 100644 index 0000000..1d86531 --- /dev/null +++ b/home/cluster/forgejo/service-tailscale-https.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Service +metadata: + name: forgejo-tailscale + namespace: forgejo + annotations: + tailscale.com/expose: "true" + tailscale.com/hostname: "git" + tailscale.com/tags: "tag:k8s" + # Enable HTTPS with serve + tailscale.com/serve-config: | + { + "TCP": { + "443": { + "HTTPS": true + } + }, + "Web": { + "${TS_CERT_DOMAIN}:443": { + "Handlers": { + "/": { + "Proxy": "http://forgejo.forgejo.svc.cluster.local:80" + } + } + } + } + } +spec: + type: LoadBalancer + loadBalancerClass: tailscale + selector: + app: forgejo + ports: + - port: 443 + targetPort: 3000 + protocol: TCP + name: https + - port: 22 + targetPort: 2222 + protocol: TCP + name: ssh \ No newline at end of file diff --git a/home/terraform/debian13-caddy-cloud-init.yml b/home/terraform/debian13-caddy-cloud-init.yml deleted file mode 100644 index 7cff822..0000000 --- a/home/terraform/debian13-caddy-cloud-init.yml +++ /dev/null @@ -1,235 +0,0 @@ -#cloud-config -# Cloud-init configuration for Debian 13 Vultr server with Caddy proxy and Tailscale - -# Update and upgrade packages on first boot -package_update: true -package_upgrade: true - -# Configure hostname -hostname: caddy - -# Configure timezone -timezone: America/Chicago - -# Install packages -packages: - # SSH server - - openssh-server - - # Include all base packages - - sudo - - curl - - wget - - git - - vim - - tmux - - htop - - rsync - - net-tools - - dnsutils - - build-essential - - python3 - - python3-pip - - apt-transport-https - - ca-certificates - - gnupg - - lsb-release - - software-properties-common - - fail2ban - - ufw - - # Caddy and web server tools - - debian-keyring - - debian-archive-keyring - -# Create users with sudo access -users: - - name: graham - groups: sudo - shell: /bin/bash - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_import_id: - - gh:gmcintire - - - name: andy - groups: sudo - shell: /bin/bash - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_import_id: - - gh:nsnw - - - name: ansible - uid: 10001 - groups: sudo - shell: /bin/bash - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFghGMnDdkfNC6JPEhMxrKhYDmNcXjHXp/y/mf3uLtzb graham@mbp14.local - -# Configure SSH -ssh_pwauth: false -disable_root: false # Allow root initially for Vultr SSH keys - -# Write configuration files -write_files: - - path: /etc/ssh/sshd_config.d/99-custom.conf - content: | - PermitRootLogin prohibit-password - PasswordAuthentication no - PubkeyAuthentication yes - AuthorizedKeysFile .ssh/authorized_keys - Banner /etc/issue.net - - - path: /etc/issue.net - content: | - ****************************************************************** - * Authorized access only. All activity is monitored. * - ****************************************************************** - - - path: /etc/apt/sources.list.d/caddy-stable.list - content: | - deb [signed-by=/usr/share/keyrings/caddy-stable-archive-keyring.gpg] https://dl.cloudsmith.io/public/caddy/stable/deb/debian any-version main - - - path: /etc/caddy/Caddyfile - content: | - # Global options - { - # Email for Let's Encrypt - email admin@example.com - - # Enable the admin endpoint - admin off - } - - # Default site - return 404 for undefined hosts - :80 { - respond 404 - } - - # Example reverse proxy configuration - # example.com { - # reverse_proxy localhost:8080 - # } - permissions: '0644' - owner: root:root - - - path: /etc/sysctl.d/99-tailscale.conf - content: | - # Tailscale UDP GRO fix - net.ipv4.udp_rmem_min = 131072 - net.ipv4.udp_wmem_min = 131072 - net.core.rmem_default = 131072 - net.core.wmem_default = 131072 - net.core.netdev_max_backlog = 5000 - - - path: /opt/scripts/install-tailscale.sh - content: | - #!/bin/bash - # Install Tailscale - curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null - curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list - apt-get update - apt-get install -y tailscale - - # Enable and start tailscaled - systemctl enable tailscaled - systemctl start tailscaled - - # If TAILSCALE_KEY is provided, authenticate - if [ -n "$TAILSCALE_KEY" ]; then - tailscale up --authkey="$TAILSCALE_KEY" --accept-routes --hostname=$(hostname) - fi - permissions: '0755' - - - path: /opt/scripts/setup-caddy.sh - content: | - #!/bin/bash - # Ensure Caddy starts after network is ready - mkdir -p /etc/systemd/system/caddy.service.d - cat > /etc/systemd/system/caddy.service.d/override.conf < /etc/fail2ban/jail.d/caddy.conf <