Skip to main content
note

The maintained, living version of this content is now Region Deployment — kept current as regions are actually stood up. This page is left in place but may be stale (e.g. it still references dev-sgp-1-style multi-instance naming and k8s 1.31); prefer the linked version.

Deploying a Region

Assumptions

  • This document uses dev-sgp as the implementation example — development environment on AWS Singapore (ap-southeast-1).
  • Each region produces two DNS zones: one for the control-plane API (sgp.dev.cplane.api.cogrion.com) and one for workspace subdomains (sgp.dev.cogrion.com).
RepositoryPurpose
cogrion-terraformCloud infrastructure
cogrion-gitopsArgoCD apps, Helm charts, environment values

This page documents the actual procedure for deploying a new region or environment. For the architectural rationale behind these steps see ADR: Deploying a Region.


Global Prerequisites

These must exist once before any region is deployed. They are shared across all environments and regions.

PrerequisiteStatusNotes
cogrion.com root domain registered (GoDaddy)TODO
cogrion.com DNS zone active in CloudflareTODOCurrently this DNS zone for root domain is managed on AWS Route 53
Cloudflare Workers deployed (auth.cogrion.com, cplane.cogrion.com/lookup)TODOGlobal auth proxy and tenant→region routing
Cloudflare KV namespace (tenant→region map)TODOWritten at workspace provision time
Dashboard UI deployed (app.cogrion.com)TODO
Root CA in AWS Secrets Manager (ap-southeast-1)TODOShared PKI root for all regional OpenBao instances
Primary region sgpTODOAll other regions resolve principals from sgp

Deployment Sequence

Phase 1 — AWS Infrastructure (Terraform)

  1. Prepare directory infra/envs/dev-sgp/ in cogrion-terraform.

  2. Set feature flags and values in terraform.tfvars. Roll out in sub-phases:

    • create_vpc = true, create_storage = true — VPC, subnets, NAT, S3 buckets
    • create_eks = true, create_database = true — EKS cluster + node groups, RDS instance
    • create_iam = true — IRSA roles
    • create_dns = true — Route53 hosted zones + ACM wildcard certs
  3. Push to main — the CodePipeline cogrion-terraform-dev-sgp auto-applies each phase.

    Resources created:

    • VPC (10.11.0.0/19) + secondary CIDR (100.64.0.0/16) for EKS pod networking
    • EKS cluster (cogrion-dev-sgp-cluster, k8s 1.31)
    • RDS instance (cogrion-dev-sgp, db.t3.small)
    • Route53 zones: sgp.dev.cplane.api.cogrion.com, sgp.dev.cogrion.com
    • ACM wildcard certs for both zones
    • S3 buckets: cogrion-dev-sgp-artifacts, cogrion-dev-sgp-exports
    • IAM roles (cluster, node, ebs-csi-driver pod identity)
  4. Get the Route53 nameservers from the Terraform output:

    AWS_PROFILE=cogrion-dev-sgp tofu -chdir=infra/envs/dev-sgp output zone_name_servers

Phase 2 — DNS Delegation

  1. In the Cloudflare dashboardcogrion.com zone → DNS → Records → + Add record, manually add NS records for both zones.

    For sgp.dev.cplane.api.cogrion.com (4 records, Type: NS, Name: sgp.dev.cplane.api):

    ns-XXXX.awsdns-XX.org
    ns-XXXX.awsdns-XX.co.uk
    ns-XXX.awsdns-XX.com
    ns-XXX.awsdns-XX.net

    For sgp.dev.cogrion.com (4 records, Type: NS, Name: sgp.dev):

    ns-XXXX.awsdns-XX.org
    ns-XXXX.awsdns-XX.co.uk
    ns-XXX.awsdns-XX.com
    ns-XXX.awsdns-XX.net

    Replace the placeholder nameserver values with the actual output from step 4.

  2. Verify delegation and cert issuance:

    dig NS sgp.dev.cplane.api.cogrion.com +short
    dig NS sgp.dev.cogrion.com +short
    aws acm list-certificates --region ap-southeast-1 \
    --query 'CertificateSummaryList[*].[DomainName,Status]' --output table

    Both certs should reach ISSUED within a few minutes of delegation.

Phase 3 — Cluster Bootstrap

  1. Bootstrap ArgoCD and apply cluster resources — see GitOps: Bootstrap a new cluster.

    kubectl apply -n argocd -k https://github.com/argoproj/argo-cd/manifests/cluster-install?ref=v2.12.0
    kubectl apply -f argocd/_bootstrap/dev-sgp-1/bootstrap.yaml
    kubectl apply -f argocd/app-roots/dev-sgp-1.yaml
  2. Apply cluster-level secrets (image pull, RDS credentials, inter-region service token).

Phase 4 — PKI and TLS

  1. Deploy OpenBao into the cluster.
  2. Import the shared root CA from AWS Secrets Manager into OpenBao's PKI backend.
  3. Deploy cert-manager and configure it to use OpenBao as the issuer.

Phase 5 — Platform Services (ArgoCD)

  1. Copy ArgoCD app manifests and Helm values from an existing region into cogrion-gitops:

    cp -r argocd/apps/prod-sgp-1 argocd/apps/dev-sgp-1
    cp -r values/prod-sgp-1 values/dev-sgp-1

    Update all domain and bucket values in values/dev-sgp-1/ to use dev.sgp-1.cogrion.com, cogrion-dev-sgp-1-artifacts, etc.

  2. Sync ArgoCD — deploys in dependency order:

    • Keycloak
    • Temporal (server + workers)
    • Control plane API
    • Observability stack (Prometheus, Grafana, Loki)

Phase 6 — Region Registration

  1. Update Cloudflare KV to route new tenants to dev.sgp-1.cogrion.com at signup.
  2. Since dev-sgp-1 is a secondary region (not sgp-1 primary): set PRIMARY_CPLANE_API_URL=https://cplane.sgp-1.cogrion.com and INTER_REGION_SERVICE_TOKEN in Helm values.

Phase 7 — Smoke Test

  1. Create a test tenant assigned to dev-sgp-1 and verify the full auth flow end-to-end.
  2. Provision a test workspace and confirm DNS delegation, cert issuance, and cluster agent bootstrap token flow.

New Environment vs New Region

  • New environment (e.g. dev-sgp-1): Phase 1 is a subset — no new VPC if sharing; new RDS and S3 only. Route53 zone is a subdomain of the existing regional zone.
  • New region: Full Phase 1 including VPC and EKS. Phase 2 adds a new top-level NS delegation.

Teardown

Drain workspaces → remove Cloudflare KV entry → delete ArgoCD apps → tofu destroy. The shared root CA and global Cloudflare layer are unaffected.