Repository navigation
Fix Render database names in API connection strings - #633
Conversation
There was a problem hiding this comment.
Important
The staging connection switch needs a documented data migration prerequisite before the first apply.
Reviewed changes The Render database connection strings and cutover instructions were reviewed against the Terraform resources and staging startup settings.
- Database names: Both API connection strings now use the suffixed database names from the corresponding Render internal URLs and the resource database users.
- Cutover sequence: The runbook separates initial production environment-group linkage from a later production database switch and direct-variable cleanup.
GPT Sol | 𝕏
There was a problem hiding this comment.
Important
The staging database name change makes the reseed workflow reject its own replacement database before migration or seeding.
Reviewed changes Reviewed the new Terraform and runbook changes since the prior Pullfrog review.
- Staging cutover: Added a prerequisite to copy and verify staging data before linking the new database environment group.
- Database lifecycle: Moved staging connection construction into the staging Terraform root, used the Render URL database name, and preserved operator IP allow lists across both roots and reseeds.
- Production cutover: Kept the production database switch behind
api_database = "render"and documented checks before removing direct service variables.
GPT Sol | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes Reviewed the staging seed target fix and merged base changes since the prior Pullfrog review.
- Seed target validation: Accepted the Render-suffixed staging database name while retaining the staging host and user checks, with tests for permitted and rejected targets.
GPT Sol | 𝕏
SonarCloud S6444 and SYSLIB1045 on the seed target check: the pattern is now a GeneratedRegex with a one second timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes Reviewed the staging seed database-name matcher change since the prior Pullfrog review.
- Bounded matcher: Replaced the dynamic regex with an equivalent source-generated matcher with a one-second timeout; the staging host and user checks remain unchanged.
GPT Sol | 𝕏
|
…) (#635) * Guard web service Terraform plans before apply (#631) * Guard Terraform web service updates before apply * Guard Terraform web service replacement and deletion (cherry picked from commit 7a1e26a) * Add manual API release workflow for production and staging (#632) (cherry picked from commit 498015a) * Add Amazon SES delivery and signed event handling (#628) * Add SES identities, DNS, and delivery infrastructure * Add SES sender and signed SNS event handling * Classify SES webhook and clarify email contract * Fix SES cutover controls and webhook verification * Extract shared email composition for SES and Resend * Isolate staging SES events and sender credentials * Escape interpolated names in the SES isolation test patterns CodeQL js/incomplete-hostname-regexp flagged the tuple values flowing into new RegExp; every interpolated value is now escaped as a literal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit f770b47) * Keep staging awake and reseed its free database (#626) * Add staging keepalive and database reseed lifecycle * Document and strengthen staging seed command * Keep Terraform plan details out of workflow logs * Require successful health responses in staging workflows * Parse Render creation time portably * Isolate staging database state and gate reseed on deploy * Read the staging database id from the main state before moving it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Correlate staging reseed deploy with live commit --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit ee40ae9) * fix: point apex DNS at Render landing site (#634) (cherry picked from commit 65d355f) * Move uploads to private S3 with stable read links (#625) * Add configurable S3 upload signing * Provision private S3 upload buckets and scoped credentials * Expose storage provider cutover as Terraform variables * Add stable read redirects for private S3 uploads * Map public upload reads in agent catalog * Fix upload read validation and S3 bucket safeguards * Keep S3 upload reads available across provider rollback * Bound anonymous upload reads per client IP (cherry picked from commit 395239f) * Fix Render database names in API connection strings (#633) * fix: derive Render database names from connection URLs * Generate the staging database name pattern with a match timeout SonarCloud S6444 and SYSLIB1045 on the seed target check: the pattern is now a GeneratedRegex with a one second timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 0fd416f) * Complete carried error copy and generated gating matrix * Keep SES event notifications recoverable (#746) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>




Change
infra/configuration.tfnow takes each database name from its Render Postgres internal connection URL when constructing both API connection strings. The username follows the corresponding resource'sdatabase_user.infra/README.mddocuments settingapi_database = "render"during the production cutover and removing duplicated service variables after the linked group is verified.Closes thomasluizon/orbit-tickets#819.
Test evidence
terraform fmt -check -recursive infrapassed.terraform -chdir=infra validatepassed.node tools/check-dashes.mjs --files infra/configuration.tf infra/README.mdandnode tools/check-timeless.mjs --stagedpassed.dotnet build Orbit.slnxpassed with zero errors.dotnet testpassed all 6,813 tests.terraform -chdir=infra consolecheck withapi_database=renderand both required web digest variables set to valid placeholder digests evaluated the connection string locals. The expression was{ production = { for key, value in local.production_api_database_values : key => nonsensitive(regex("Database=([^;]+)", value)[0]) }, staging = { for key in local.database_keys : key => nonsensitive(regex("Database=([^;]+)", local.staging_render_npgsql)[0]) } }. Passwords were not printed. Result:terraform plan -refresh=falsewithapi_database=rendercould not complete becauseRENDER_API_KEYis unset in this shell. Terraform reportedError: Missing Render API Key. The plan therefore did not establish the web service change set.dotnet build Orbit.slnx: 0 errors.dotnet test Orbit.slnx --no-build: 6,842 passed, 0 failed.-refresh=falseshowed no Postgres replacement or web-service update. The planned connection strings namedorbit_production_9g8landorbit_staging_jo8c, with passwords excluded from the output.render_postgres(no replacement, no allow list removal) and no web service update; the staging-database root plans onlyrender_env_group.staging_databaseand its link (2 to add, 0 to change, 0 to destroy), keeps the allow list, and its connection string namesDatabase=orbit_staging_jo8c(password redacted). The liveGET /v1/postgresvalues areorbit_production_9g8l/orbit_productionandorbit_staging_jo8c/orbit_staging. No existing database-name regression test supplied a pre-fix observation; the pre-fix plan of the staging root readdatabase_name = "orbit_staging_jo8c" -> "orbit_staging" # forces replacement.External interface evidence
The installed Render provider v1.9.1 schema reports
render_postgres.connection_info.internal_connection_stringas a computed sensitive string andrender_postgres.database_useras a string.terraform state pull, filtered to the two Render Postgres resources, showedinternal_connection_stringandpasswordin eachconnection_infoobject. Parsing only the database path from those saved URLs producedorbit_production_9g8landorbit_staging_jo8c. This can be repeated without exposing credentials using:Assumptions
infra/local.tfvars; I did not change theapi_databasedefault because the Render group must be verified before production uses it.ignore_changesfordatabase_nameanddatabase_userso their configured creation values remain usable when staging is replaced. I rejected hard-coding the current suffixed names as creation inputs.Manual steps
orbit-stagingPostgres connection screen. Before the staging API switches to the linked environment group, use that instance's connection details to dump databaseorbit_stagingwithpg_dump -Fcand restore it intoorbit_staging_jo8cwithpg_restore --clean --if-exists. Compare table counts in the PostgreSQL console, verify the staging API reads the restored data, then droporbit_staging. A final database list should containorbit_staging_jo8cand noorbit_staging.infra/local.tfvars, set the exact keyapi_database = "render"after confirming production data in the Render Dashboardorbit-productionPostgres connection screen. WithRENDER_API_KEYand the other documented credentials available, inspect a fresh plan: both production connection keys must nameorbit_production_9g8l, and neither web service nor the imported API service may update in place. Apply that approved plan and verify the production API uses the linkedorbit-production-apienvironment group.orbit-api> Environment. After verifying the linked group, remove direct service values that duplicateorbit-production-api, includingConnectionStrings__DefaultConnectionandConnectionStrings__SessionConnection, and leaveORBIT_TERRAFORM_ENV_GROUP. The service must remain healthy and useorbit_production_9g8lafter those direct values are removed.orbit_stagingintoorbit_staging_jo8cusing credentials from the staging database’s Render Connections screen before applying the staging environment-group change. Compare records, verify staging API reads from the new database, then droporbit_staging.production_postgres_ip_allow_listininfra/local.tfvarsandstaging_postgres_ip_allow_listininfra/staging-database/local.tfvarsfrom each database’s Render Networking screen. Confirm the plans retain those exact entries.STAGING_POSTGRES_IP_ALLOW_LISTin the API repository’s GitHub Settings > Secrets and variables > Actions > Variables to the staging list as JSON. Confirm a reseed plan retains it.api_database = "render"ininfra/local.tfvars, apply its reviewed plan, and verify the production API connection. Then remove duplicated direct connection variables on the Render production API Environment screen; confirm the linked group still supplies both connections.