Repository navigation
feat(app-yaml): adopt an existing RDS instance and Route53 record - #155
Open
Alexanderamiri wants to merge 2 commits into
Open
Alexanderamiri wants to merge 2 commits into
Alexanderamiri wants to merge 2 commits into
Conversation
Apps moving onto the platform could only get new resources. moresleep must keep its RDS instance and its hand-made sleepingpill DNS record. - databases[].adopt: <identifier> (postgres) generates the new service-rds-adopted module plus an import block. The module manages only tags, deletion_protection and an optional backup_retention_period; everything else is ignored, and prevent_destroy is set. - databases[].host_env / port_env wire the hostname and port separately (created and adopted postgres); service-rds gains an address output. - routing.adopt_dns: true sets allow_overwrite on the routing record so an existing record is taken over (Route53 UPSERT) instead of failing. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Terraform Plan✅ No changes — infrastructure is up to date. Plan output |
…ecord adopt and adopt_dns let a team take over resources the team boundary does not protect (untagged legacy RDS instances, Route53 records in shared zones). Each adoption now has to be listed for the team in ADOPTIONS in scripts/registry.py, so it is approved in a platform PR. Also give the adopted instance's final snapshot a stable random suffix and pin the module to AWS provider >= 5.40, and tell adopters to keep a public instance's security group narrow. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Terraform Plan✅ No changes — infrastructure is up to date. Plan output |
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.
Why
Today app.yaml can only create resources.
javaBin/moresleep(sleepingpill.javazone.no) is moving onto the platform with no architectural change, so it has to keep two existing things:dbmoresleep(Postgres 17, public endpoint, serves the program API since 2021). Not in any Terraform state.sleepingpill.javazone.no.routing.hostwould fail on apply because the record already exists.moresleep also reads
DBHOSTandDBPORTseparately, but the RDS modules only exposeendpoint(host:port).What
app.yaml (validated in
scripts/generate-modules.py):databases[].adoptgeneratesmodule "rds_<name>"from the newterraform/modules/service-rds-adopted, plus:deletion_protection, an optionalbackup_retention_period, and the Terraform-only final-snapshot settings:skip_final_snapshot=false, a final snapshot id,delete_automated_backups=false.instance_class(required by the provider) is read from the live instance. Every other argument is inignore_changes, andprevent_destroyis set.instance_class,allocated_storage,engine_versionandmulti_azare rejected together withadopt.adoptis rejected for dynamodb or an invalid identifier.host_env/port_envmap toaddress/portoutputs.service-rdsgains anaddressoutput, and the adopted module'sportis a string.routing.adopt_dns: truepassesallow_dns_overwrite = truetoservice-routing, which setsallow_overwriteon the record, so Route53 UPSERTs the existing record instead of failing on CREATE. The value isnullwhen unset, so existing apps' records and generated files do not change.importblock on purpose. moresleep runs in parallel onmoresleep.javazone.nofirst and then changeshost. At that point the routing record address is already in state, so Terraform would skip an import and the replacement CREATE would fail.allow_overwritecovers both the fresh case and the host-change case.adoptandadopt_dnsonly validate when the identifier or host is listed for the app's team inADOPTIONSinscripts/registry.py. This PR listsmoresleep: rds dbmoresleep, dns sleepingpill.javazone.no. Why: Route53 records in the shared zones have no team ABAC, andDenyXTeamonly fires on resources tagged with another team. Without the allowlist, any team could take over another app's hostname (host: submit.javazone.no+adopt_dns: true), or adopt, tag away and later delete an untagged legacy database with one app.yaml line. The generator always runs from platformmain, so a team can't edit the list itself.<identifier>-final-<random_id hex>(stable per state), so a later delete/re-adopt cycle can't collide with an old snapshot. The module pinshashicorp/aws >= 5.40, < 6.0becausededicated_log_volumeis inignore_changes.app-yaml-reference.md(an "Adopting an existing PostgreSQL instance" section,adopt_dns,host_env/port_env),reusable-modules.md,terraform/modules/README.mdand the module table inCLAUDE.md.scripts/registry.py:MODULE_SOURCESgainsservice-rds-adopted.How verified
python3 -m unittest discover -s scripts/tests: 59 tests OK, 16 of them new inAdoptTest(3 cover the approval list: another team's database, another team adoptingdbmoresleep, an unapproved host). The existing fmt test now also runs on the moresleep fixture.terraform/lambda-src/tests: 64 OK.terraform fmt -check -recursive terraform/modulesis clean.terraform validatepasses forservice-rds-adopted,service-routingandservice-rds(init -backend=false).terraform planagainst the real account (local backend, admin profile, never applied):Plan: 1 to import, 0 to add, 1 to change, 0 to destroy(before the review fix; therandom_idsuffix now adds1 to add). The only diffs aredeletion_protection false -> true,tags_all(+5 default tags), and the Terraform-onlyskip_final_snapshot,final_snapshot_identifieranddelete_automated_backups. Engine, class, storage, security group, publicity, PI and monitoring are untouched.moresleep.javazone.no, all modules, local module sources):Plan: 1 to import, 22 to add, 1 to change, 0 to destroy. It stops only atreading IAM Role (javabin-ecs-exec-moresleep), which is created when themoresleepteam is registered (javaBin/registry#40).Follow-ups
master) and Postgres for JVM tests.dbmoresleepsits in the default VPC with the default SG open to0.0.0.0/0. This PR deliberately leaves the SG alone.0.0.0.0/0. All traffic to such an instance goes through the NAT and pays data processing.DenyXTeamprotects them) is still a security-workstream item. The approval list closes the app.yaml path, not hand-written Terraform.🤖 Generated with Claude Code