Mirrors issue R1.1 Relay production environment from the DataTalksClub/community-base unification plan (docs/plan/phase-1.md). Repository: DataTalksClub/relay (code) and DataTalksClub/aws-infra (Terraform, by pull request). Depends on: nothing.
Goal
Give Relay a production deployment path: a manually approved production deploy workflow, the production tenant provisioning for the first client (the DTC website), and operator documentation. The plan issue's live checks (canary email, SES identity in the AWS console, prod system.echo) are owner-gated and stay open after the code lands.
Scope
deploy-prod.yml: a workflow_dispatch production deploy workflow gated on the production GitHub environment with a required reviewer. It reuses scripts/deploy_relay_sandbox.sh parameterised by --environment production; sandbox behaviour of the script is unchanged.
scripts/provision_production_tenant.sh: provisions organisation datatalksclub, audience dtc, client dtc-website, default sender DataTalks.Club <hello@datatalks.club> (final address to be confirmed by the owner in the pull request), and one client API key. The key is generated on the host into the 0600 runtime env file, following the sandbox RELAY_BOOTSTRAP_API_KEY mechanism; the script never prints or embeds key material. The owner copies the key into the DTC deployment secrets.
docs/production.md: the production environment, on-call checks, and rollback. Explicit that production is not deployed yet.
Note on the Terraform half
The plan's aws-infra step (a production Relay root) is already satisfied by the merged main/relay root in DataTalksClub/aws-infra, with documented deviations from the issue text (no Elastic IP: the host is private behind the shared ALB; one ingress queue: the inbound path is deliberately out of scope; the datatalks.club SES identity, DKIM, SPF and DMARC records live in main/common and main/website-static). That conflict is reported to the plan owner as a plan fix; nothing is applied.
Acceptance criteria
deploy-prod.yml deploys only on manual dispatch from main, only after lint/checks/tests pass, and only after the environment reviewer approves.
- Sandbox deploy path of
scripts/deploy_relay_sandbox.sh is byte-for-byte behaviour-identical.
- The provisioning script has a dry-run mode and never prints key material.
docs/production.md states production is not deployed and lists the owner-gated checks.
Test notes
uv run pytest (full suite), uv run ruff check ..
python -c yaml.safe_load on both workflows.
bash -n and --help/--dry-run for both scripts.
- Live checks (curl
system.echo against prod, /internal/ops/status, SES identity verified in the console) need the owner to apply the Terraform pull request and run the prod deploy: Not run here, needs: owner approved and applied the Terraform root and the first production deploy.
Mirrors issue
R1.1 Relay production environmentfrom the DataTalksClub/community-base unification plan (docs/plan/phase-1.md). Repository: DataTalksClub/relay (code) and DataTalksClub/aws-infra (Terraform, by pull request). Depends on: nothing.Goal
Give Relay a production deployment path: a manually approved production deploy workflow, the production tenant provisioning for the first client (the DTC website), and operator documentation. The plan issue's live checks (canary email, SES identity in the AWS console, prod
system.echo) are owner-gated and stay open after the code lands.Scope
deploy-prod.yml: aworkflow_dispatchproduction deploy workflow gated on theproductionGitHub environment with a required reviewer. It reusesscripts/deploy_relay_sandbox.shparameterised by--environment production; sandbox behaviour of the script is unchanged.scripts/provision_production_tenant.sh: provisions organisationdatatalksclub, audiencedtc, clientdtc-website, default senderDataTalks.Club <hello@datatalks.club>(final address to be confirmed by the owner in the pull request), and one client API key. The key is generated on the host into the0600runtime env file, following the sandboxRELAY_BOOTSTRAP_API_KEYmechanism; the script never prints or embeds key material. The owner copies the key into the DTC deployment secrets.docs/production.md: the production environment, on-call checks, and rollback. Explicit that production is not deployed yet.Note on the Terraform half
The plan's aws-infra step (a production Relay root) is already satisfied by the merged
main/relayroot in DataTalksClub/aws-infra, with documented deviations from the issue text (no Elastic IP: the host is private behind the shared ALB; one ingress queue: the inbound path is deliberately out of scope; the datatalks.club SES identity, DKIM, SPF and DMARC records live inmain/commonandmain/website-static). That conflict is reported to the plan owner as a plan fix; nothing is applied.Acceptance criteria
deploy-prod.ymldeploys only on manual dispatch frommain, only after lint/checks/tests pass, and only after the environment reviewer approves.scripts/deploy_relay_sandbox.shis byte-for-byte behaviour-identical.docs/production.mdstates production is not deployed and lists the owner-gated checks.Test notes
uv run pytest(full suite),uv run ruff check ..python -c yaml.safe_loadon both workflows.bash -nand--help/--dry-runfor both scripts.system.echoagainst prod,/internal/ops/status, SES identity verified in the console) need the owner to apply the Terraform pull request and run the prod deploy:Not run here, needs: owner approved and applied the Terraform root and the first production deploy.