Useful Commands — Operator (direct AWS access)

Commands that require direct access to AWS — the EKS cluster, RDS, ECR, Lambda, Terraform, and kubectl — plus the platform lifecycle (wbsp-platform). These are operator concerns. Application developers deploy and operate their apps through the wbsp CLI (see the application developers' useful-commands guide) and never touch AWS directly.

Requires AWS_PROFILE set and the platform provisioned on AWS.

Platform lifecycle — provision / health / destroy / cleanup

Run from the platform repo root (reads .env + deploy/aws/ outputs). Requires in .env: WBSP_RDS_PASSWORD, WBSP_ACME_EMAIL (and optionally WBSP_SAMPLE_BASE_DOMAIN, WBSP_ACME_STAGING).

wbsp-platform provision --provider aws
wbsp-platform provision --provider aws --sample-base-domain demo.wbsp.io --verbose

wbsp-platform health    --provider aws
wbsp-platform health    --provider aws --json --verbose
wbsp-platform health    --provider aws --verbose        # per-check progress

wbsp-platform destroy   --provider aws                  # removes all apps first, then infra
wbsp-platform destroy   --provider aws --force          # cluster layer; add --include-edge for VPC/RDS/ECR

Whole-landscape diagram

# image prompt + mermaid (all apps, pods, routing, Postgres/Redis, parallel envs), no secrets
wbsp-platform diagram landscape.txt --provider aws

Orphaned-resource cleanup

wbsp-platform cleanup --provider aws                     # scan only (default)
wbsp-platform cleanup --provider aws --mode interactive  # confirm each
wbsp-platform cleanup --provider aws --mode force        # remove all orphans

Point kubectl at the cluster

# Discover the cluster name
aws eks list-clusters --query clusters --output text

# Configure kubectl (cluster is usually wbsp-platform)
aws eks update-kubeconfig --name <cluster> --region <region>

# App namespace is wbsp-<tenant>-<app>; workload is <tenant>-<app>
kubectl -n wbsp-<tenant>-<app> get pods,svc,deploy
kubectl -n wbsp-<tenant>-<app> get ingressroute        # Traefik routing
kubectl -n wbsp-<tenant>-<app> logs deploy/<tenant>-<app> --tail=100 -f
kubectl -n wbsp-<tenant>-<app> exec -it deploy/<tenant>-<app> -- sh

Inspect a deployed app's injected env

kubectl -n wbsp-<tenant>-<app> set env deploy/<tenant>-<app> --list
kubectl -n wbsp-<tenant>-<app> set env deploy/<tenant>-<app> --list | grep -E '_HOST|_PORT|DATABASE_'

Connect to the platform database (RDS), manually

Application developers use wbsp db (no direct AWS access needed). For the raw path — or to connect as the admin user — connect from inside the cluster:

# Get the RDS endpoint (from Terraform)
terraform -chdir=deploy/aws output rds_address

# Run a throwaway psql pod inside the cluster
kubectl run psql-tmp --rm -it --image=postgres:16 --restart=Never -- \
  env PGPASSWORD="$WBSP_RDS_PASSWORD" \
  psql -h <rds_address> -U wbsp_admin -d <tenant>_<app>

Credentials: user wbsp_admin, password from WBSP_RDS_PASSWORD. The host comes from WBSP_RDS_HOST or the rds_address Terraform output.

Access containers in the parallel-services environment

Namespace is wbsp-svc-<tenant>-<env-name>.

kubectl -n wbsp-svc-<tenant>-<env> get pods,svc,netpol
kubectl -n wbsp-svc-<tenant>-<env> logs deploy/<service> --tail=100 -f
kubectl -n wbsp-svc-<tenant>-<env> exec -it deploy/<service> -- sh

# Reach a parallel service from your laptop (e.g. its postgres on 5432)
kubectl -n wbsp-svc-<tenant>-<env> port-forward svc/postgres 5544:5432
# then: PGPASSWORD=… psql -h localhost -p 5544 -U <user> -d <db>

# Run prisma/other migrations against the parallel DB through the forward
POSTGRES_HOST=localhost POSTGRES_PORT=5544 POSTGRES_USER=… POSTGRES_PASSWORD=… \
POSTGRES_DB=… npx prisma migrate deploy

Isolation: only allow-listed apps (same tenant) may reach the parallel namespace. A probe from any other namespace is denied by NetworkPolicy.

Forgejo: reach it, mint an admin token, seed repos

Forgejo (the worked-example parallel service) is internal-only. Forward its web port for the API/UI; full guide: accessing-forgejo.md.

# Forward Forgejo's web port (API + UI); add the SSH port in a second shell if needed
kubectl -n wbsp-svc-<tenant>-<env> port-forward svc/forgejo 3080:3000
kubectl -n wbsp-svc-<tenant>-<env> port-forward svc/forgejo 2222:22
# → http://localhost:3080   (e.g. curl -s localhost:3080/api/v1/version)

Mint a Forgejo admin access token (for API calls / seeding). The forgejo CLI refuses to run as root, so run it as the git user and pass the config path:

ns=wbsp-svc-<tenant>-<env>
pod=$(kubectl -n $ns get pods -l app=forgejo -o jsonpath='{.items[0].metadata.name}')

# list users (confirm the admin user exists)
kubectl -n $ns exec "$pod" -- su git -s /bin/sh -c \
  'forgejo --config /data/gitea/conf/app.ini admin user list'

# create an admin user if missing
kubectl -n $ns exec "$pod" -- su git -s /bin/sh -c \
  'forgejo --config /data/gitea/conf/app.ini admin user create \
     --username wbsp-admin --email wbsp-admin@wbsp.local --random-password --admin --must-change-password=false'

# generate an access token (prints the token once)
kubectl -n $ns exec "$pod" -- su git -s /bin/sh -c \
  'forgejo --config /data/gitea/conf/app.ini admin user generate-access-token \
     --username wbsp-admin --scopes all --token-name seed'

Seed the example app's catalog/repo data against AWS by running its scripts through the DB tunnel, pointing Forgejo env at the forwarded port (keep the port-forward svc/forgejo 3080:3000 above open):

# Import catalog rows (DB only)
wbsp db run --config wbsp.yaml --destination prod -- npm run catalog:import

# Seed one project's Forgejo repo (needs the DB tunnel + Forgejo forward + a token)
FORGEJO_HOST=localhost FORGEJO_PORT=3080 FORGEJO_ADMIN_TOKEN=<token> \
  wbsp db run --config wbsp.yaml --destination prod -- npm run repo:seed <project-number>

Inspect a Lambda (aws.on-demand / aws.demo) directly

State is shared with the normal aws destination. The function is named for the tenant/app; logs land in CloudWatch.

aws lambda list-functions --query "Functions[].FunctionName" --output text
aws lambda get-function --function-name <function-name>
aws logs tail /aws/lambda/<function-name> --follow

Grant someone the AWS permissions the --backdoor paths need

Everyday wbsp use needs no AWS credentials — commands route through wbsp-api on the caller's wbsp login session. --backdoor is the exception, and it needs real IAM permissions. wbsp aws-policy prints the least-privilege policy for a chosen set of command paths, ready to paste into IAM → Policies → Create policy → JSON.

wbsp aws-policy --deploy                       # wbsp deploy/remove/stop/… --backdoor
wbsp aws-policy --database                     # wbsp db proxy/connect/run/url/dump/restore
wbsp aws-policy --database --deploy            # combined into one policy set
wbsp aws-policy --status                       # read-only; safe for auditors and on-call
wbsp aws-policy --platform                     # provision/destroy the whole platform (Terraform)
wbsp aws-policy --demo --repo --on-demand --backup
wbsp aws-policy --all --output wbsp-policy.json

The JSON goes to stdout and the coverage notes to stderr, so wbsp aws-policy --repo > repo-policy.json yields a clean file. Account and region are read from the ambient AWS profile; override with --account, --region, --cluster. Selections that exceed AWS's 6,144-character managed-policy limit are split into several documents — create each as its own policy and attach them all.

Two things the policy cannot do for you:

  • Cluster access is not IAM. For every cluster-facing scope the principal must ALSO be mapped in the cluster (an EKS access entry or an aws-auth ConfigMap entry). Without it aws eks get-token succeeds and every Kubernetes call still returns Forbidden.
  • --platform is not a day-to-day grant. It can create and delete the VPC, the cluster and the database. Grant it for a platform build, then remove it.

External reference documentation

AWS

Kubernetes

Terraform (platform provisioning)