carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

Approval plan: the db-reads/ lifecycle rule on the deployment buckets

Status: PREPARED, not applied. AGENTS.md's production rule applies: nothing here is applied until Paul approves this scope.

What and why

Two lifecycle rules on each deployment bucket, both filtered to the prefix db-reads/ (db region forward spec §5.7, §11.1, J4):

  • db-reads-expire: current versions expire 1 day after creation; noncurrent versions expire 1 day after they become noncurrent; incomplete multipart uploads are aborted after 1 day.
  • db-reads-delete-markers: expired object delete markers are removed.

The forwarded read protocol writes create-only objects under db-reads/ and deletes nothing. These rules are its only deletion. They must be in place on a deployment's bucket before any console there sets CARLOS_DB_FORWARD=1; without them db-reads/ objects are never removed.

The module change is in infra/modules/deployment-buckets/main.tf, inside the existing aws_s3_bucket_lifecycle_configuration.deployment, beside the geoip-noncurrent rule, which is unchanged. The module test tests/db_reads.tftest.hcl (T17) pins both rules and the GeoIP rule.

Scope

| | Dev | Flagship | |---|---|---| | Account and region | the dev account (profile kass), eu-west-1 | the flagship account (profile keymail), eu-west-1 | | Bucket | carlos-dev-640012953448 | carlos-flagship-271376211898 | | Root | platform-infrastructure (tracks main) | carlosframework/carloku-infrastructure (modules at a release tag) | | Resource | aws_s3_bucket_lifecycle_configuration.deployment inside the deployment-buckets module | the same | | Change | two rules added; the control/geoip/ rule unchanged | the same |

No IAM change, no new permission, no traffic change. Nothing outside db-reads/ is affected: the filter is the prefix, and no other key in the bucket starts with it. A bucket's lifecycle configuration is replaced whole by the apply, which is why the plan must show the GeoIP rule still there.

Cost

Lifecycle expiration is free. Storage of db-reads/ objects is at most a few days of forwarded reads (a query's ciphertext is at most 64 MiB).

Steps

Dev first (Paul's roll order), then the flagship:

  1. Dev: in platform-infrastructure, tofu init -upgrade, then tofu plan -target=<the deployment-buckets module address> (find it with grep -n 'deployment-buckets' *.tf). The plan must show only the lifecycle configuration changing in place, with the two rules added and geoip-noncurrent kept. Apply with the same -target after approval.
  2. Flagship: cut the platform release that carries this module change, push its tag to the GitHub mirror (git push https://github.com/carlosframework/platform.git refs/tags/vX.Y.Z), bump every ?ref= in carloku-infrastructure, tofu init -upgrade, then the same targeted plan. Apply with the same -target after approval. A whole-root apply is not allowed (user_data drift restarts every box).

Verification

aws s3api get-bucket-lifecycle-configuration --bucket <deployment bucket> --profile <the deployment's profile> lists geoip-noncurrent, db-reads-expire and db-reads-delete-markers, the last two filtered to db-reads/.

Rollback

Remove the two rules and apply the same targeted change. Until a rule is back, db-reads/ objects are not removed, so turn forwarding off (CARLOS_DB_FORWARD unset on the console) first.

Duration

Permanent while forwarding is in use. Plan 5 (spec §14) moves this traffic to a bucket per region, which carries its own copy of these rules; these then stay for any object written before the move.