Skip to content

Configuration Reference

Nexa is deployed and operated by your platform team in your own cloud. Configuration lives in two layers: the infrastructure layer (Terraform variables that provision the VPC, Kubernetes cluster, database, and IAM) and the application layer (Kubernetes Kustomize overlays and per-service environment variables). This page lists both, grouped by area, so you know what each setting controls and how to change it safely.

Two facts to keep in mind while reading:

  • Infrastructure variables are set in environments/<env>.tfvars and applied with terraform apply. Changing one re-provisions infrastructure; some (marked replace) destroy and recreate a resource and cause downtime.
  • Application settings are Kubernetes environment variables sourced from a ConfigMap (non-secret) or from AWS Secrets Manager via the Secrets Store CSI driver (secret). None are hot-reloaded — the pod reads them at startup, so a change takes effect only after a rollout restart of the affected Deployment.

The “Reload” column below uses: apply = terraform apply; replace = apply that recreates the resource (downtime); rollout = kubectl rollout restart of the Deployment; sync = an ArgoCD sync of the overlay.

Set per environment in the Terraform network module. See the reference architecture for topology.

Variable Type Default Controls Reload
vpc_cidr string 10.0.0.0/16 CIDR block for the environment VPC replace
private_subnet_cidrs list(string) two /24s Private subnets that run the worker nodes and database replace
public_subnet_cidrs list(string) two /24s Public subnets for the load balancer and NAT replace
availability_zones list(string) two AZs in-region AZs the subnets span replace
aws_region string ap-southeast-1 Region all resources deploy to replace
rds_allowed_cidr_blocks list(string) [] Extra source CIDRs allowed to reach Postgres on 5432 (in addition to the VPC) apply

Set in the eks module. Nexa runs on one Elastic Kubernetes Service (EKS) cluster per environment.

Variable Type Default Allowed / typical Controls Reload
eks_cluster_version string 1.34 supported EKS versions Kubernetes control-plane version apply (rolling)
node_instance_types list(string) t3.xlarge (dev/prod) any EC2 type Worker node size replace (node group)
node_desired_size number 5 ≥ min, ≤ max Steady-state node count apply
node_min_size number 3 Floor for the managed node group apply
node_max_size number 56 ≥ desired Ceiling for the node group apply
node_capacity_type string SPOT SPOT, ON_DEMAND Purchasing model for nodes replace
node_disk_size number 20 (GiB) Root EBS volume per node replace
bifrost_node_group_enabled bool false true/false Dedicated node pool for the Bifrost AI gateway apply

Application-level autoscaling is not done with a HorizontalPodAutoscaler. Replica counts are fixed per service in the overlay, and only the orchestration worker scales, via a KEDA ScaledObject (see the app table below).

Set in the rds module. Postgres holds platform, web, and agent metadata.

Variable Type Default Controls Reload
rds_instance_class string db.t3.micro Database compute/memory size replace
rds_engine_version string 15.x Postgres major/minor version apply (minor) / replace (major)
rds_allocated_storage number 20 (GB) Provisioned gp3 storage apply
rds_force_ssl bool / 0|1 off in dev Whether rds.force_ssl requires TLS on every connection apply (param group)
rds_publicly_accessible bool true (dev), false (prod) Whether the DB gets a public IP apply
rds_skip_final_snapshot bool true (dev), false (prod) Take a final snapshot on destroy apply
rds_snapshot_identifier string null Restore a new instance from this snapshot replace

Fixed in the module (not variables, same for every environment): storage_type = gp3, storage_encrypted = true (AWS-managed key), backup_retention_period = 7 days, backup window 03:00–04:00, maintenance window Mon 04:00–05:00, and postgresql log export to CloudWatch. Multi-AZ is not enabled — enable it in the module before production.

Object storage for the raw data lake is provisioned by the raw-data-lake stack: an S3 bucket with AES256 server-side encryption, versioning on, all public access blocked, and a cross-account assume-role (with ExternalId) that lets your warehouse read the raw/ prefix.

Variable / mechanism Type Default Controls Reload
app_secrets map per-env list Which AWS Secrets Manager containers are created (e.g. nexa-shared-secret-<env>) apply
recovery_window_in_days number 7 Secrets Manager deletion recovery window apply
github_oidc_repositories list(string) ["repo:dataready-ai/*:*"] Which GitHub repos may assume the CI push role apply
Pod Identity associations (module) per service Maps each service account to an IAM role for AWS access apply

Nexa uses EKS Pod Identity (not IRSA) to give pods AWS access, and the AWS Secrets Store CSI driver to mount secrets. Secret containers are created empty by Terraform; values are populated out-of-band (kept out of Terraform state). No customer-managed KMS keys and no IAM permission boundaries are created by the reference IaC.

Setting Default Controls
EKS control-plane logs api, audit, authenticator, controllerManager, scheduler (all on) Streams cluster API/audit logs to CloudWatch
RDS log exports ["postgresql"] Ships Postgres logs to CloudWatch
SSM /app/log-level, /app/feature-flag per-env Parameter Store values apps can read

The reference IaC does not deploy Prometheus, Grafana, or a log shipper — those are added at the cluster layer. See the operations guide for what to scrape.

Each service is a Kubernetes Deployment. Ports and probe paths are stable; replica counts and resources are set in the Kustomize overlay. Changing any env var requires a rollout.

Service Port Health path Base replicas Purpose
nexa-web 3000 / 1 Web UI
nexa-backend 4000 /health-check 1 Core API (TypeScript)
nexa-databricks-api / nexa-snowflake-api 8000 /health 1 Data-platform API (FastAPI)
nexa-agents-api 8000 /api/v1/health 1 Agents authoring/execution API
nexa-orchestration-service 8003 /readyz 1 (+KEDA worker 0–5) Automation orchestration
nexa-stt-service 8010 /readyz 1 Speech-to-text
nexa-slackbot-service 8000 /api/v1/health 1 Slack integration

The orchestration worker scales with a KEDA ScaledObject (nexa-orch-worker): min 0, max 5, triggered by rows in the Postgres work_items table where status = 'pending' (scale up at ≥ 1 pending, 10s poll, 60s cooldown).

Sourced from the shared secret (<env>-nexa-shared-secrets) unless noted. These names are stable across services that use them.

Variable Type Example / default Controls Reload
ENVIRONMENT string dev / test / prod Environment name used in logs and routing rollout
LOG_LEVEL enum info (debug, warning, error) Log verbosity rollout
LOG_FORMAT enum json / text Log encoding (use json in prod) rollout
DEBUG bool false Verbose error output — keep false in prod rollout
PG_HOST / PG_PORT / PG_DATABASE string secret Postgres connection rollout
PG_USERNAME / PG_PASSWORD string secret Postgres credentials (role per service) rollout
PG_SCHEMA_PLATFORM / PG_SCHEMA_WEB / PG_SCHEMA_LLM string secret Schema each layer writes to rollout
NEXA_AUTH_ENABLED bool true Enforce Nexa auth on API calls rollout
NEXA_AUTH_JWT_SECRET string secret Signing key for issued tokens rollout
NEXA_AUTH_TOKEN_TTL_SECONDS number secret Token lifetime rollout
NEXA_SERVICE_AUTH_TOKEN (+ _PREVIOUS) string secret Service-to-service auth; _PREVIOUS allows zero-downtime rotation rollout
CORS_ORIGINS list https://<env>.<domain> Allowed browser origins rollout
GITHUB_TOKEN string secret Access to the code repositories Nexa writes to rollout
Variable Controls
DATABRICKS_HOST Workspace URL
DATABRICKS_CLIENT_ID / DATABRICKS_CLIENT_SECRET OAuth (service principal) credentials
DATABRICKS_AUTH_TYPE Auth mechanism (e.g. oauth-m2m)
DATABRICKS_CATALOG Unity Catalog target
DATABRICKS_WAREHOUSE_ID SQL warehouse used for queries
DATABRICKS_WORKSPACE_ID Workspace identifier

nexa-databricks-api and nexa-snowflake-api run background workers behind feature flags in the shared secret / ConfigMap:

  • ENABLE_WORKER_<name> (bool) — turn an individual background worker on or off.
  • WORKER_<name>_SYNC_INTERVAL_SECONDS (number) — poll interval.
  • WORKER_<name>_CRON_SCHEDULE (cron string) — schedule for cron-style workers.
  • MAX_CONCURRENT_DEPLOYMENTS (number) — cap on concurrent pipeline deploys.

All are read at startup; change them in the overlay/secret and roll out the Deployment. For applying config changes safely, see the operations guide.