Repository navigation
Conversation
The migrations need PostgreSQL 15 (000134 uses UNIQUE NULLS NOT DISTINCT), but the environment inputs still accepted older majors: Azure's postgres_version allowed 11-16, and AWS database_engine_version and GCP database_version had no validation. A custom deployment on an older engine would plan and apply, then fail at migration time. Validate all three at plan time: Azure "15"/"16", GCP POSTGRES_15/POSTGRES_16, and AWS "<major>" or "<major>.<minor>" with a major of 15 or more (try() makes a malformed value a validation failure rather than an evaluation error). Every shipped tfvars pins 16, so no deployed environment changes. Add a mocked tftest per environment (old major rejected, 15 and 16 accepted), run by a new "Test environment inputs" step in the terraform-validate CI job, and state the minimum in docs/DEPLOYMENT.md. Closes LeanerCloud#1233 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…5 tftest The combined-tree git-secrets run flagged terraform/environments/aws/tests/postgres_version.tftest.hcl:10, a bare account_id = "123456789012" in the mocked aws_caller_identity. The repo allows that placeholder only on AccountID lines in _test.go files, so add an anchored whole-line entry for this one mock line (bracketed digits so the entry does not match itself), like the other terraform/ entries. Refs LeanerCloud#1233 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
IAmJSD
added a commit
to IAmJSD/cloud-commitments-platform
that referenced
this pull request
Oct 23, 2026
…S tftest The combined-tree git-secrets run flagged terraform/environments/aws/tests/lambda_cors_origins.tftest.hcl:10, a bare account_id = "123456789012" in the mocked aws_caller_identity. Add an anchored whole-line .gitallowed entry for that one line (bracketed digits so the entry does not match itself), placed before the other terraform/ entries so it does not collide with LeanerCloud#1255's entry for its own tftest. Refs LeanerCloud#324 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
The migrations need PostgreSQL 15+ (#1110, migration 000134, uses
UNIQUE NULLS NOT DISTINCT), but the Terraform environment inputs still accepted older majors:terraform/environments/azure/variables.tfpostgres_version: validation allowed11-16.terraform/environments/aws/variables.tfdatabase_engine_version: no validation.terraform/environments/gcp/variables.tfdatabase_version: no validation.So a custom or self-hosted deployment on an older engine would plan and apply cleanly, then fail at migration time.
Fix
Validate each input at plan time:
postgres_version:contains(["15", "16"], ...).database_version:contains(["POSTGRES_15", "POSTGRES_16"], ...).database_engine_version:try(tonumber(regex("^([0-9]+)(\\.[0-9]+)?$", v)[0]) >= 15, false). This accepts the major-only pin ("16") and the"16.6"form theterraform/profiles/aws/*.tfvars.examplefiles use.try()makes a malformed value such as"sixteen"fail validation cleanly instead of failing with atonumber()evaluation error. (Terraform 1.10's&&does not short-circuit, so the issue's plaintonumber(split(".", v)[0]) >= 15would error instead of fail.)Each variable's description and error message now name the 15+ requirement.
docs/DEPLOYMENT.md→ Prerequisites states the minimum and names the input for each cloud.Every shipped tfvars (
github-{dev,staging,prod}.tfvars,dev.tfvars.example, profiles) pins 16, so no deployed environment's plan changes.Deploy gating: the AWS check takes effect on the next AWS plan. The Azure and GCP changes only take effect at their next deploy, which is gated on the paused Azure/GCP deploys. Until those resume, they are covered only by CI (
terraform validateplus the new tftests below).Tests
A new
terraform/environments/{aws,azure,gcp}/tests/postgres_version.tftest.hclper environment:14,14.12andsixteen; accepts15,16and16.6.14; accepts15and16.POSTGRES_14; acceptsPOSTGRES_15andPOSTGRES_16.Every provider is mocked (
mock_provider), so nothing reaches a cloud API. Each run usescommand = planwithplan_options { target = [module.database] }.module.databaseis the input's only consumer, and targeting it keeps the variable's validation in the graph without planning the whole environment against mock data. An untargeted mocked plan fails on unrelated mock-data gaps (empty AZ lists, non-12-digit mock account IDs, an unknown-at-plancount). I also checked that targeting an unrelated resource (random_id.suffix) drops the validation and gives "Missing expected failure", which is why the tests target the consumer. Fixtures used: AWS mocksaws_caller_identity/aws_availability_zoneswith the placeholder123456789012that the fargate tftest already uses. GCP sets a 64-zero placeholdercredential_encryption_key, because the auto-generated one is unknown at plan and the secrets module uses it in acount.CI did not run any environment-level tftests before this change. A new "Test environment inputs" step in the
terraform-validatejob (afterTerraform Validate) runsterraform testinterraform/environments/<cloud>when atests/dir exists.Verification
All of this is local, mocked-provider tftest evidence (Terraform v1.10.5, the CI pin). No
terraform plan/applywas run against a real backend or with real credentials. Everything ran withAWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null.Commands, run on temp copies of
terraform/(after= this branch,before=origin/mainplus the new test files) so.terraform/never touched the worktree:Fail-before / pass-after (
terraform test):rejects_postgres_14fail: "Missing expected failure", rest skippedrejects_postgres_14fail: "Missing expected failure", rest skippedrejects_postgres_14fail: "Missing expected failure", rest skippedAlso checked:
beforecopy, aws 3/3, azure 2/2 and gcp 2/2 passed. A failing reject run therefore comes from the missing validation, not from the harness.>= 16, Azure["16"], GCP["POSTGRES_16"]):accepts_postgres_15fails with "Invalid value for variable" in all three environments, so the accept runs do catch an over-tight floor.Combined-tree verification. This branch was tested together with six other queued branches on a local, never-pushed tree:
queue/platform@77d116c6= origin/maina14dc8f2plus these heads, merged in this order:Linux, Go 1.26.9,
AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null AWS_EC2_METADATA_DISABLED=true; Docker Postgres via testcontainers:go build ./...,go vet ./...,go vet -tags integration ./...and the fullgo test -race -short -count=1 ./....--build-tags integration, andgocyclo -over 10is silent on the changed non-test files. These ran atb61a9c30, which differs from77d116c6only by one.gitallowedline on fix/issue-1233.-tags integration -count=1):cmd/cleanup-lambda,internal/analytics,internal/auth,internal/database/postgres/migrationsandinternal/purchase.internal/apipasses, except two tests whose Postgres container didn't start, or whose migrations hit a timeout, under machine load. Rerun alone on the same tree, both pass:TestDeleteManagedPlanByExecutionStatusandTestNotifiedRow_RescheduleDoesNotOverwriteConcurrentCancel.internal/configpasses exceptTestPostgresStoreDB_ResolveStaleRIExchange_ValidatesCloudCheck, which fails the same way on unmodified main (fixed by fix(config): compare resolve checked_at at the database's microsecond precision #1252).TESTCONTAINERS_RYUK_DISABLED=trueto avoid a testcontainers reaper race under load.scripts/setup-git-secrets.shpatterns in a fresh repo with an isolated HOME, found nothing in the changed files, and a planted fake key was flagged.scripts/test-git-secrets-allowlist.sh: 137 PASS, 0 FAIL.Out of scope
terraform/modules/database/azurepostgres_version,terraform/modules/database/gcpdatabase_version,terraform/modules/database/awsengine_version) are still unvalidated. The Azure module's description still lists "11, 12, 13, 14, 15, 16". The issue targets the environment inputs, which are the only callers in this repo. Adding the same floor to the modules would be a small follow-up.docs/DEPLOYMENT.mdstill says "Aurora Serverless v2 PostgreSQL 16.4" for AWS, while the env provisions anaws_db_instancepinned to major 16. This is pre-existing doc drift and is left alone.Maintainer: please mirror the issue's triage labels onto this PR:
triaged,priority/p3,severity/low,urgency/this-quarter,impact/few,effort/xs,type/bug.Closes #1233
🤖 Generated with Claude Code