Skip to content

Latest commit

 

History

History
82 lines (63 loc) · 6.94 KB

File metadata and controls

82 lines (63 loc) · 6.94 KB

ECS and CircleCI deployment

service.yaml creates the forms-api-v6 Fargate service on the existing topcoder-infrastructure cluster. It owns ECR, task/execution roles, CloudWatch logs, private task networking, RDS ingress, ALB target group/rule, and both HTTP API Gateway routes (/v6/forms and /v6/forms/{proxy+}). The existing gateway VPC link, TLS integration, CloudFront origin authorizer, and domain remain shared.

The runtime listens on port 3000. Health checks use /v6/forms/health/ready and require database availability. OpenAPI UI is /v6/forms/api-docs, with JSON at /v6/forms/api-docs-json. The root forms list requires an administrator token; published schemas and anonymous submissions are public.

Inbound JWT handling uses the same tc-core-library-js middleware as the other v6 APIs. Both legacy HS256 and Auth0 RS256 tokens are supported in one deployment. The Forms VALID_ISSUERS parameter must contain https://auth.topcoder-dev.com/ for dev browser sign-in; the library resolves its JWKS and normalizes the dev namespaced roles/user ID. Existing AUTH_MODE and AUTH_AUDIENCE task settings are ignored by the new runtime. Updating the application image is sufficient when the issuer is already allowed; otherwise update the issuer parameter and roll the tasks as well. See authentication configuration.

Initial environment setup

Dev uses schema forms in database topcoder-services on the existing services RDS instance. The database administrator provisions the forms login and schema; this service does not create a separate database or rotate that login. All tables, enums, functions, reporting views, and Prisma migration history remain in forms.

Load the dev AWS credentials and the administrator-provided FORMS_DB_USERNAME / FORMS_DB_PASSWORD into the environment. python3 deploy/bootstrap-dev.py checks the existing connection and schema ownership without writes. Once the target schema is migrated and its existing data has been copied, python3 deploy/bootstrap-dev.py --apply selects it in the encrypted DATABASE_URL and MIGRATION_DATABASE_URL parameters under /config/forms-api-v6/appvar. Both URLs use the supplied forms login, schema=forms, and certificate-verified TLS. The script preserves the existing authentication settings.

For a new environment, create the CloudFormation stack with DesiredCount=0, configure the equivalent database/schema/login and encrypted settings, run the migrations, then release the runtime. Production uses forms-api-v6-production with Environment=production, production networking/gateway parameters, CORS origins, and credentials. Template defaults describe dev and must be overridden for production. The bootstrap script intentionally refuses another AWS account.

Moving the original dev data

The original forms database is preserved as a recovery copy. Its three applied migrations are archived unchanged in prisma/legacy-migrations; current prisma/migrations contains a fresh baseline for schema forms. Do not run the new baseline against the old installation as an in-place upgrade.

  1. Migrate the empty target schema using the new login and schema=forms.
  2. Pause the Forms ECS service and wait for its tasks to stop before the final data copy.
  3. With boto3 and psycopg[binary] installed, run python3 deploy/copy-dev-data.py --apply. It copies the seven service tables in one transaction, preserving every ID, version, timestamp, answer, and idempotency key. It recreates each reporting view in forms and verifies all table/view contents against the source. The copy tool temporarily disables only application triggers inside this transaction, retaining foreign keys and CHECKs, and re-enables them before commit.
  4. Select the new encrypted URLs with bootstrap-dev.py --apply and release the matching runtime. Confirm readiness, the published schema, and a real browser submission against forms.event_interest_v1.

The copy refuses a nonempty target. The source is retained and fenced against further application writes at cutover. A rollback requires stopping the new service, restoring the prior URLs/image, and explicitly reconciling any new submissions before restoring source writes. Never switch back after accepting new data without reconciliation.

Releases

.circleci/config.yml follows the other v6 services' Docker build flow: checkout, remote Docker setup, deployment dependency installation, image build, and release. Node, pnpm, dependency installation, Prisma generation, and TypeScript compilation run inside the Docker build. There is no CircleCI PostgreSQL service or separate verification job. develop builds and deploys dev; master builds and deploys production. Both use Topcoder's org-global context and pinned tc-deploy-scripts credential helper. Forms retains its runtime and migration images and release.py deployment process: target-database migrations still run before runtime promotion. Deployments are serialized separately per environment. The CircleCI project must be connected in the Topcoder organization to use that shared context.

Local checks and the same release command can run from an authorized workstation:

nvm use
pnpm lint && pnpm build && pnpm test
docker build --target migrate -t forms-api-v6:migrate-candidate .
docker build --target runtime -t forms-api-v6:candidate .
python3 -u deploy/release.py dev dev-UNIQUE_RELEASE_TAG

Use --network=host for local Docker builds if the workstation bridge cannot resolve the registry. release.py requires boto3 and Docker and checks account and stack environment before pushing. Runtime and migration images receive immutable release tags. The migration task runs in the same private subnets as the service, uses the configured schema-owner login, and applies only the schema-scoped migrations. Only exit code zero permits CloudFormation promotion. ECS keeps the previous task healthy during rollout and uses its deployment circuit breaker to roll back failed runtime starts. Database migrations must remain compatible with the previous runtime; the service rollback does not undo data/schema migrations.

The script writes release-dev.json or release-production.json containing image digests and AWS task/stack identifiers. On an observation timeout, inspect the reported task/stack operation before retrying; do not start a second migration while the first remains active. Infrastructure edits are applied separately using CloudFormation with the current ImageTag and environment parameters preserved; normal app releases retain the existing stack template and parameters.

Dev sample

python3 deploy/seed-dev.py publishes event_interest from examples/event-interest.json, using a short-lived bootstrap token held in memory. It refuses production and conflicting published definitions. The corresponding CMS seed lives in payload-cms/scripts/seed-forms-test.ts. The website resolves the CMS page at /forms-test and fetches its schema from the public Forms API at runtime.