### Summary of Changes This PR introduces a declarative, GitOps-managed cloud infrastructure for the monorepo using K3s, Flux v2, and HashiCorp Packer: 1. **Packer Golden Image Builder (`ci/packer/`)**: - Automated Debian 12 minimal base OS image creation using QEMU builder, UEFI firmware, GPT partition scheme, and 2M cluster size `.qcow2` conversion. - Cloud-init, `virtio` kernel drivers, and serial console (`ttyS0`, 115200 baud). - Pre-installed K3s binary (`v1.31.2+k3s1`) with isolated first-boot token and cert generation. - Full identity sanitization (`machine-id` and SSH host key resets). 2. **First-Boot Cloud-Init Bootstrapping (`ci/cloud-init/user-data.yaml`)**: - Configures K3s with `servicelb` disabled and TLS SANs for custom domains and static IP. - Waits for API readiness, initializes `flux-system` namespace, injects `sops-age` secret, and triggers Flux sync. 3. **SOPS & GitOps Root Orchestration (`.sops.yaml`, `ci/k8s/clusters/production/`)**: - SOPS encryption configuration targeting Kubernetes secrets with `age` key recipient. - Flux v2 `GitRepository` and `Kustomization` manifests tracking `next`. 4. **Infrastructure & Networking (`ci/k8s/base/`, `ci/k8s/infrastructure/`)**: - Dedicated `com-ermnvldmr` namespace. - `cert-manager` HTTP-01 `ClusterIssuer` (`letsencrypt-prod` & `letsencrypt-staging`). - Traefik Ingress routing for `ermnvldmr.com`, `www.ermnvldmr.com`, `docs.ermnvldmr.com`, and `analytics.ermnvldmr.com`. 5. **PostgreSQL & Applications (`ci/k8s/apps/`)**: - PostgreSQL 16 StatefulSet on 5Gi `local-path` persistent storage with low-memory tuning. - Deployments for `www` (pinned `sha-6d33b71`), `docs` (pinned `sha-91f5245`), and `umami` (pinned `postgresql-v2.14.0`) with zero-downtime rolling update strategy. 6. **CI/CD Workflows (`.github/workflows/`)**: - `ci - next/build-golden-image`: Workflow to build and upload `com-ermnvldmr-debian-12-k3s-amd64-<tag>.qcow2` to static S3 `/dev/images/`. - Updated `services-www-releases-dispatch-release.yml` and `services-docs-next-required.yml` with GitOps deployment steps.
36 lines
1010 B
Bash
Executable File
36 lines
1010 B
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
SERVICE=$1
|
|
TAG=$2
|
|
|
|
if [ -z "$SERVICE" ] || [ -z "$TAG" ]; then
|
|
echo "Usage: $0 <service: www|docs|umami> <tag>"
|
|
exit 1
|
|
fi
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
APP_DIR="$ROOT_DIR/ci/k8s/apps/$SERVICE"
|
|
|
|
if [ ! -d "$APP_DIR" ]; then
|
|
echo "Error: Application directory '$APP_DIR' does not exist."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Updating Kustomize image tag for '$SERVICE' to '$TAG'..."
|
|
cd "$APP_DIR"
|
|
kustomize edit set image "ghcr.io/deytenit/ermnvldmr.com/${SERVICE}=ghcr.io/deytenit/ermnvldmr.com/${SERVICE}:${TAG}"
|
|
|
|
cd "$ROOT_DIR"
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add "ci/k8s/apps/${SERVICE}/kustomization.yaml"
|
|
|
|
if git diff --staged --quiet; then
|
|
echo "No manifest changes to commit for $SERVICE."
|
|
else
|
|
git commit -m "chore(release): deploy ${SERVICE} ${TAG} [skip ci]"
|
|
git push origin next
|
|
echo "Successfully deployed $SERVICE ($TAG) via GitOps."
|
|
fi
|