Skip to content

fix(persistence): migrate pre-partition arn:aws: ARNs in persisted state - #2627

Merged
vieiralucas merged 6 commits into
mainfrom
fix/issue-2610
Oct 1, 2026
Merged

vieiralucas merged 6 commits into
mainfrom
fix/issue-2610

Conversation

@vieiralucas

@vieiralucas vieiralucas commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Summary

Closes #2610.

State persisted by a cn/gov/iso-region server before the ARN partition work (#2569..#2591) still held arn:aws:.... A one-time, load-time migration now rewrites it.

  • Mechanism: fakecloud_persistence::arn_partition::migrate_data_dir(data_path, region) runs in main.rs right after the version-file check, before any service loads, then sets arn_partitions_migrated = true in fakecloud.version.toml (new data dirs start with it set). A single marker instead of ~100 per-service schema bumps; old binaries ignore the field. Files are replaced atomically and the marker is written last, so an interrupted run re-runs idempotently.
  • Rules: regional ARNs (arn:aws:<svc>:<region>:...) take their region's partition whatever --region is (an arn:aws: ARN with a cn/gov/iso region can't be valid). Region-less ARNs (arn:aws:iam::..., arn:aws:s3:::...) take the server's partition, only when it isn't aws. AWS-managed policies (arn:aws:iam::aws:policy/...) stay as is, matching the managed-policy catalog lookup. Wildcards (*, ?) and ${...} variables move with the resources they match; region patterns follow the server's partition.
  • Coverage: values, map keys (ARN-keyed maps like SNS topics, tag maps) and ARNs inside stored documents (policies, templates, state-machine definitions; edited in place, formatting unchanged) in every <service>/*.json and logs/manifest.json, plus S3 bucket subresource files and object/multipart sidecars. A byte pre-scan skips files with nothing to fix, so commercial servers pay one scan.
  • Deliberately untouched: payloads with a stored hash/size (SQS bodies/attributes with MD5, ECR manifests, CloudWatch dashboards, EventBridge events); customer data (DynamoDB items/streams, SSM values, secrets, SES template content, SNS messages, S3 keys/user metadata/tags, log events); S3 bodies, log segments, container volumes. Unreadable paths (e.g. lost+found) are skipped individually; a failed write aborts startup so the marker is never set over stale state.
  • fakecloud-persistence now depends on fakecloud-aws (moved to layer 2 in scripts/publish-crates.sh; --check passes).

Edge cases (accepted): an aws-partition server still rewrites regional ARNs naming a cn/gov/iso region and sets the marker; no-marker dirs written by current main are treated as legacy (an IAM entity created on a cn server through a us-east-1-signed request would become aws-cn; indistinguishable); a migrated map key colliding with an existing new-partition key keeps the existing one and logs a warning.

Surfaces: new "ARN partition migration" section in docs/reference/persistence.md. No CLI/SDK change.

Test plan

  • Unit: 25 in arn_partition_tests.rs (rewriter rules, keys/values/documents, wildcards and variables, managed policies, idempotence, full data-dir runs, marker, regression test per review finding); persistence crate 97.
  • New e2e arn_partition_migration_persistence.rs: us-east-1 server creates KMS/SNS/IAM/SQS/S3/Lambda/DynamoDB state, snapshots rewritten to cn-north-1 with the marker stripped (realistic legacy dir), restart with --region cn-north-1 -> arn:aws-cn: from KMS DescribeKey/ListAliases (lookup by new ARN and alias), SNS ListTopics/GetTopicAttributes alongside a new topic, IAM GetRole + trust/inline docs + attached customer policies (managed policy still arn:aws:), SQS QueueArn + RedrivePolicy (body + MD5 unchanged), S3 bucket policy + object SSE-KMS key ARN (ARN-like key still reachable), DynamoDB DescribeTable, Lambda GetFunction, marker set. Fails with the migration disabled.
  • All 44 *_persistence e2e suites (139 tests).
  • fmt + workspace clippy clean; publish-crates.sh --check; local /code-review medium 4 rounds, last clean (fixed 11 findings incl. lost+found abort, stranded S3 objects, customer-data rewrites, wildcards/variables, escaped-ARN pre-scan miss, write errors marked migrated).

Summary by cubic

Migrates arn:aws: ARNs in persisted state to their region's partition, so a China, GovCloud, or ISO-region server restarted on older state stops mixing partitions and its ARN-keyed lookups (SNS topics, tag maps) work again.

  • Runs before any service loads, right after the version-file check, and records arn_partitions_migrated = true in fakecloud.version.toml; new directories start with the marker, and an interrupted run re-runs idempotently.
  • Regional ARNs take their region's partition, whatever --region is; ARNs without a region take the server's partition when it isn't aws, while AWS-managed policy ARNs keep the aws spelling to match the managed-policy catalog. Wildcards (*, ?) and ${...} variables move with the resources they match.
  • Rewrites values, ARN-keyed map keys, and ARNs inside stored documents in place, plus S3 bucket configuration and object sidecars; a byte pre-scan skips files with nothing to change, and ARNs behind a backslash escape (\narn:aws:...) in raw JSON/XML still count.
  • Unreadable paths are skipped per-file so the rest still migrates; a failed rewrite aborts startup so the marker is never set over stale state.
  • Leaves hash-verified payloads (SQS bodies/attributes with MD5, ECR manifests) and customer data (DynamoDB items, SSM values, secrets, SES template content, SNS messages, S3 keys, metadata and tags, multipart-upload tagging, client-supplied object headers, log events, container volumes) untouched.

Written for commit 551e581. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 10 files

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread crates/fakecloud-persistence/src/arn_partition.rs Outdated
Comment thread crates/fakecloud-persistence/src/arn_partition.rs Outdated
Comment thread crates/fakecloud-persistence/src/arn_partition.rs
Comment thread website/content/docs/reference/persistence.md Outdated
Comment thread website/content/docs/reference/persistence.md Outdated
Comment thread crates/fakecloud-persistence/src/arn_partition.rs
State written before fakecloud minted ARNs in the region's partition
spells them arn:aws: even for China, GovCloud and ISO regions, so a
cn/gov/iso server restarted on such a data directory mixed partitions
in its responses and kept ARN-keyed state (SNS topics, tag maps, ...)
under the stale spelling.

Before any service loads, a one-time migration now rewrites every ARN
token in the persisted state: values, object keys, and ARNs embedded in
stored documents (policies, templates, definitions), in place so the
document text is otherwise unchanged. A regional ARN whose region
belongs to another partition takes that partition; a region-less ARN
takes the server region's partition when that is not aws, except
AWS-owned ones (managed policies), which fakecloud keeps as arn:aws:.
Hash-verified payloads (SQS bodies/attributes, ECR manifests) and bulk
payloads (log events, S3 object bodies, container volumes) are left
alone. S3 sidecar TOML is covered too.

The run is recorded once per directory as arn_partitions_migrated in
fakecloud.version.toml; directories created by this binary start with
it set, so newer state is never re-migrated.

Closes #2610
…igration

Review fixes for the one-time ARN partition migration:

- Skip filesystem artifacts (lost+found, dotfiles) and service
  directories the server cannot read instead of failing startup.
- Leave customer data verbatim: DynamoDB items and stream images, SSM
  parameter values, Secrets Manager secrets, and S3 object keys, user
  metadata and tags (rewriting the key stranded the object in the
  directory derived from the old key). Object sidecars are rewritten
  structurally; bucket subresource files hold raw JSON/XML payloads and
  are rewritten as text.
- Rewrite policy wildcards (`arn:aws:kms:*:acct:key/*`) with the
  resources they match, so stored allows keep matching.
- Drop the token-boundary check from the byte pre-check: an ARN behind
  a serialized escape (`\narn:aws:...`) made a file look clean and it
  was then marked migrated for good.
…N migration

Second review round on the ARN partition migration:

- Accept `${...}` policy variables and Fn::Sub references in the region
  and account fields, so `arn:aws:iam::${aws:PrincipalAccount}:role/x`
  moves with the roles it matches; a variable region follows the
  server's partition like a wildcard.
- Detect S3 object trees only at `s3/buckets/<bucket>/{objects,mpu}`, so
  a bucket named `objects` or `mpu` keeps its configuration rewritten.
- Skip an unreadable file or directory individually instead of
  abandoning the rest of its service (or every later S3 bucket).
- Keep EventBridge events and CloudWatch dashboard bodies verbatim: they
  are customer payloads measured by a stored size_bytes.
…rbatim

Third review round on the ARN partition migration:

- A failure writing a migrated file is no longer mistaken for an
  unreadable path and skipped: the loader would read the stale file and
  the marker would stop the migration for good. It now fails startup,
  and the next start retries.
- Keep SES sent emails (subject, bodies, raw data, template data,
  headers: the stored DKIM signature covers them) and SNS published
  messages (kept like the SQS copies of the same publish) verbatim.
- Accept `?` in the service field like the region and account fields.
- Treat a backslash-escape tail (`\narn:aws:...`) as a token start, so
  the raw-text rewrite of bucket subresource payloads agrees with the
  byte pre-check instead of leaving a stale ARN behind the marker.
- Keep a multipart upload's `tagging` and the client-supplied object
  headers (Content-Type, Content-Disposition, ...) verbatim, like object
  tags and user metadata.
- Docs: say which S3 metadata is rewritten and which fields are kept.
@vieiralucas
vieiralucas merged commit 639c183 into main Oct 1, 2026
158 checks passed
@vieiralucas
vieiralucas deleted the fix/issue-2610 branch October 1, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate pre-partition arn:aws: ARNs in state persisted by cn/gov-region servers

1 participant