Infrastructure-as-code for zed-pkg: Cloudflare (R2 + DNS), AWS (S3 alternative), GCP (planned), and the Kubernetes Argo CD app-of-apps that runs the backend.
terraform/
cloudflare/ R2 artifact buckets + zpkg.net DNS (primary)
aws/ S3 artifact bucket + least-priv IAM (alternative)
gcp/ planned (GCS + GKE)
workers/ Cloudflare Workers for registry/cdn/web/app/user.zpkg.net
k8s/
bootstrap/zed.yaml root Application (standalone app-of-apps entrypoint)
apps/ child Applications (one per service)
manifests/
zed-api-server/ kustomize base + overlays/{dev,prod}
zed-web-server/ kustomize base + overlays/{dev,prod}
postgres/ production guidance + dev StatefulSet
docs/wiring-k8s-cluster.md attach to ~/codes/ores/k8s-cluster (canonical prod)
- Canonical / production — the ORES k8s-cluster app-of-apps. The
namespace-scoped manifests are owned by each app repo
(
zed-api-server.rs/k8s,zed-web-server.rs/k8s);k8s-clusterowns thezedtenant +AppProject+Applicationpointers. This is the source of truth for the running backend. See docs/wiring-k8s-cluster.md. - Standalone / dev self-host — this repo's
k8s/. A self-contained Argo CD app-of-apps (k8s/bootstrap/zed.yaml) for a personal or air-gapped cluster with no dependency on the ORES platform. Itsoverlays/devadds an in-cluster Postgres and local artifact storage that have no place in the contract-bound app-repo manifests.
The Terraform (DNS/edge/buckets) is shared by both paths.
terraform>= 1.6kubectl+kustomize(orkubectl kustomize)- An Argo CD install on the target cluster
- A container registry (
ghcr.io/zed-pkg/*)
# Cloudflare R2 + DNS (primary artifact storage)
cd terraform/cloudflare
cp terraform.tfvars.example terraform.tfvars # fill in token/account/zone
terraform init && terraform plan && terraform apply
# AWS S3 alternative
cd terraform/aws
cp terraform.tfvars.example terraform.tfvars
terraform init && terraform plan && terraform applyR2 vs S3: R2 is the default (no egress fees, region = auto, S3-compatible
API). Use AWS S3 when you are AWS-native or want lifecycle/replication
features. The API server speaks the S3 API to either; only
S3_ENDPOINT_URL/credentials differ.
Use this only for a self-hosted cluster with no ORES k8s-cluster. For the
production deploy, follow docs/wiring-k8s-cluster.md
instead — there the manifests are owned by the app repos, not these overlays.
# preview what the overlays render
kubectl kustomize k8s/manifests/zed-api-server/overlays/prod
kubectl kustomize k8s/manifests/zed-web-server/overlays/prod
# bootstrap a standalone Argo CD app-of-apps
kubectl apply -f k8s/bootstrap/zed.yamlBuilding images uses a parent-dir build context (the services path-depend on
../zed-interfaces); see the wiring doc for the exact commands.
Provider credentials for zed-pkg (the zpkg.net Cloudflare zone token, Supabase
keys) live encrypted in env/enc/<name>.env.enc — sops with age recipients,
dotenv format, values-only encryption so the variable names double as a
reviewable schema. env/template.env.example documents every variable.
nix develop # sops, age, just, ores-sops, kubectl, jq
just edit prod # change a secret in place; plaintext never touches disk
just use prod # decrypt and symlink ./.env for local tooling
just audit # CI/pre-commit gate: nothing plaintext is committable
just cf-verify prod # prove the zone token actually authenticatesSecrets enter this store only via just edit (or sops edit) on a trusted
host. A credential that has transited chat, a shell command, or an unencrypted
file is burned: revoke it at the provider and mint a fresh one. Onboarding a
new machine or operator is a .sops.yaml recipient addition + sops updatekeys; the flow is documented at the top of .sops.yaml.
MIT
Run npm ci --ignore-scripts && npm test in infra-isolation/
for the canonical/auth/admin infrastructure contract and adversarial tests.
The dedicated GitHub Actions check is offline; live isolation acceptance requires
fresh provider/AWS evidence and explicitly authorized read-only probes. Missing
projects, private endpoints, or evidence remain blocked rather than passing.