# qa/ows-coda

Terraform configuration for the `ows-coda` service in the QA environment.
Manages: Fargate service, Aurora MySQL, ElastiCache Redis, S3 uploads bucket, IAM, Sentry, Datadog.

## Environments

### Main environment (default workspace)

The default Terraform workspace manages the long-lived QA environment at
`https://qa-ows-coda.theorchard.io` (also reachable via `coda.qaorch.com`).

```bash
terraform init
terraform plan
terraform apply
```

### Ephemeral environments

Ephemeral environments are short-lived copies of ows-coda used for PR previews and
integration testing. Each ephemeral instance gets its own Fargate service but
**shares** the RDS cluster, Redis, and S3 bucket from the main environment to avoid
the cost and time of provisioning fresh datastores per PR.

```
main workspace (default)
  └── qa-ows-coda Fargate        ← own service
  └── qa-ows-coda RDS cluster    ← shared
  └── qa-ows-coda-chatbot Redis  ← shared
  └── qa-ows-coda-uploads S3     ← shared

ephemeral workspace "pr-42"
  └── qa-ows-coda-pr-42 Fargate  ← own service, reads from shared datastores
  └── coda_pr_42 database        ← own schema on shared RDS (created manually)
```

**Prerequisite:** the default workspace must be applied before any ephemeral
environment can be created. The `create-ephemeral.sh` script verifies this at
runtime by checking for the shared AWS resources.

> **Redis encryption (TLS):** The shared Redis cluster has in-transit encryption
> enabled. All connections — including from ephemeral instances — must use
> `rediss://` (TLS) connection strings. If you see `ECONNREFUSED` or TLS
> handshake errors from an ephemeral instance, verify that `REDIS_URL` starts
> with `rediss://`, not `redis://`.

#### Creating an ephemeral environment

```bash
./scripts/create-ephemeral.sh pr-42
```

The script will:
1. Verify RDS, Redis, and S3 shared resources exist in the QA account
2. Create (or select) a Terraform workspace named `pr-42`
3. Run `terraform apply -var="instance=pr-42"`
4. Print SQL statements to create the per-instance database schema

#### Destroying an ephemeral environment

```bash
./scripts/destroy-ephemeral.sh pr-42
```

The script destroys all Fargate/IAM resources for the instance and deletes the
workspace. It prints the SQL to drop the database schema if desired.

#### Naming rules

Instance names must be lowercase alphanumeric with hyphens, start with a letter,
and be at most 21 characters (enforced by both the script and a Terraform
`validation` block). This keeps all derived AWS resource names within the 64-char
IAM limit.

Valid: `pr-42`, `feat-auth`, `fix-redis`
Invalid: `PR-42` (uppercase), `42-pr` (starts with digit), `this-name-is-way-too-long-for-aws`

## State

State is stored in S3: `orcd-terraform-state / qa/ows-coda/terraform.tfstate`

Each ephemeral workspace has its own state key within the same backend:
`qa/ows-coda/env:/pr-42/terraform.tfstate`

## After state migration from accounting/qa

If migrating state from the previous `qa-accounting-terraform-state` backend:

```bash
terraform init -migrate-state
```

Confirm the migration prompt and verify with `terraform plan`.
It should show 0 resources to add, change, or destroy.
