# SQL Catalog Deployment

SQL Catalog has one logical production environment. Its first deployment is
hosted in the `clinic-dev` AWS account (`552185537300`) on the
`clinic-staging` EKS cluster, in the isolated `sql-catalog-prod` namespace.
The account and cluster names describe infrastructure placement; all
application labels, secrets, and release controls use `prod`.

The application is packaged as one immutable image because the Vite frontend
is static and the Python service already owns same-origin API and SPA routing.
The production overlay uses the commit SHA as the image tag.

## Prerequisites

- AWS profile `clinic-dev` authenticated through SSO.
- Kubernetes context
  `arn:aws:eks:us-west-2:552185537300:cluster/clinic-staging`.
- ECR repository `sql-catalog/prod/app`.
- AWS Secrets Manager secret `prod-sql-catalog/config` containing
  `SQL_CATALOG_DATABASE_URL`, `DB_PASSWD`, and `CLINIC_API_KEY`.
- `ClusterSecretStore/default` ready in the target cluster.
- ACM certificate for `sql-catalog.pingcap.net` in `us-west-2`.
- The `AmazonEKSLoadBalancerControllerRole_Clinic` role has the inline policy
  `SQLCatalogIngressCreateTags`, sourced from
  `deployment/aws/sql-catalog-controller-create-tags-policy.json`. The policy
  only permits create-time tagging for the exact SQL Catalog Ingress stack.

## Render And Validate

```bash
kubectl kustomize deployment/kustomize/envs/prod
kubectl apply --dry-run=server -k deployment/kustomize/envs/prod
```

The migration Job is an Argo CD `PreSync` hook. For the initial manual deploy,
the database is already at schema version 18, so applying the complete overlay
is safe; wait for both the Job and Deployment before testing.

```bash
kubectl apply -k deployment/kustomize/envs/prod
kubectl -n sql-catalog-prod wait --for=condition=complete job/sql-catalog-migrate --timeout=5m
kubectl -n sql-catalog-prod rollout status deployment/sql-catalog --timeout=5m
```

Before DNS cutover, or when troubleshooting the public route, validate through
a port forward:

```bash
kubectl -n sql-catalog-prod port-forward service/sql-catalog 18765:8765
curl -fsS http://127.0.0.1:18765/api/v1/healthz/ready
```

The production Ingress owns a dedicated internet-facing ALB named
`sql-catalog-prod`. It does not join an IngressGroup or modify Clinic routing.
After the ALB is provisioned, point `sql-catalog.pingcap.net` at the hostname
reported in `Ingress.status.loadBalancer`.

## Clinic Production DNS

The `clinic-dev` VPC has a private `pingcap.com` hosted zone. Because that zone
shadows the delegated public zone, Clinic needs an explicit record in the
private zone. Hosted zone `Z02886471U8VY0AY0OBK5` contains an A Alias for
`clinic.pingcap.com` targeting the Clinic production load balancer's stable DNS
name:

```text
dualstack.clinic-ingress-prod-cloud-1113039717.us-west-2.elb.amazonaws.com.
```

The Alias target hosted zone is `Z1H1FL5HABSF5`, with target health evaluation
enabled. This record is owned by the `clinic-dev` account and only affects VPC
`vpc-085f890400d64cd0a`; no Clinic production resource is modified. Do not pin
the load balancer's rotating public IP addresses in Pod `hostAliases`.
