Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

ResourceGroupsTaggingAPI: Migration for Integrated Services#13821

Merged
aidehn merged 16 commits intomainfrom
aidehn/feat/rgta-migration
Feb 23, 2026
Merged

ResourceGroupsTaggingAPI: Migration for Integrated Services#13821
aidehn merged 16 commits intomainfrom
aidehn/feat/rgta-migration

Conversation

@aidehn
Copy link
Copy Markdown
Contributor

@aidehn aidehn commented Feb 23, 2026

Motivation

  • See this PR for additional context, but to summarize, we needed to update our approach for RGTA which resulted in updating how we stored tags.
  • This means that currently supported services with RGTA needed to be updated to now store tags under the Tags collection, and for us to move away from TaggingService

Changes

  • The changes can be summarized as updating all of the previously merged code for services which integrate with RGTA to now store their tags on the service store using the Tags utility.
  • Added the new Tags dataclass which replaces TaggingService (and the Tagger in Pro) which stores tags as a dict which maps tag keys to tag values but also adds a get_resource_tags_map method which exposes it's entire resource tags state.
    • Tests have been added to test the Tags collection.
  • SQS
    • Updated SQS store to now store tags on the store instead of on the queue and to use the Tags collection. Updated tagging utils to now to now use this new tags field.
  • SNS
    • Migrated away from TAGS which uses TaggingService to instead have the tags field which uses the Tags collection. Updated tagging utils to use this updated field.
  • Lambda
    • Migrated away from TAGS which uses TaggingService to instead have the tags field which uses the Tags collection. Updated tagging utils to use this updated field.
  • Route53
    • This service was originally a moto service without any tagging operations implemented in LocalStack (so the operations would fallback to moto). We keep this new implementations for the tagging methods, but now storing the tags on the tags field using Tags on the route53_stores store. Tagging methods were updated accordingly.
    • Since Route 53 is a global service, it doesn’t have any “supported regions”. This meant that the store never actually worked since no region would ever be valid. This was updated to skip the validation which we do in other services which have this property such as s3tables.
  • OpenSearch
    • Updated the store to now use the Tags collection under tags instead of TaggingService and TAGS. It is also stored under a LocalAttribute instead of a CrossAccountAttribute. Tagging methods updated accordingly.
  • S3, S3Control
    • Migrated TAGS field which used TaggingService to tags which uses Tags and the already existing tagging methods for S3 buckets were updated.
    • Previously, we didn't migrate S3 objects to use Tagger since RGTA doesn't support these resources. We now require these resources to be stored in the same place so new methods have been created to tag these resources also. Additional code has been added in Pro to deal with these scenarios for RGTA.
    • There was an issue on the cross-account and cross-region visibility of tags which @bentsku identified (thank you!). This has been updated by making tags a local attribute and accessing tags by using the bucket region and bucket account as these buckets are cross account and cross region accessible.
    • S3 Control tagging methods have been removed and instead are handled in the provider operations since it's not used else where or overridden.
  • KMS
    • The KMS implementation previously stored tags within the key itself. We want to move away from doing this so KMS key tagging logic on the KmsKey class has been removed. This was mostly because keeping this logic would result in repeated logic for tag validation and tag storage.
    • This has additional implications since the custom KMS key logic by LocalStack which allows custom key material and key IDs used the tags stored on the key. (Potentially something we want to rethink in the future) so additional utils have been added and the KmsKey class has been updated to decouple this class from this logic.
    • Like other services, tags are now stored on the class and the corresponding tagging methods have been updated to reflect this.

@aidehn aidehn added docs: skip Pull request does not require documentation changes notes: skip Pull request does not have to be mentioned in the release notes semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases labels Feb 23, 2026
@aidehn aidehn added this to the 4.14 milestone Feb 23, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 23, 2026

Test Results - Preflight, Unit

23 070 tests   - 53   21 179 ✅  - 73   6m 3s ⏱️ -7s
     1 suites ± 0    1 891 💤 +20 
     1 files   ± 0        0 ❌ ± 0 

Results for commit 8ad96a6. ± Comparison against base commit a857a31.

This pull request removes 74 and adds 21 tests. Note that renamed tests count towards both.
tests.unit.aws.protocol.test_op_router ‑ test_create_op_router_works_for_every_service[evidently]
tests.unit.aws.protocol.test_op_router ‑ test_create_op_router_works_for_every_service[iotanalytics]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-BatchEvaluateFeature]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-CreateExperiment]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-CreateFeature]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-CreateLaunch]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-CreateProject]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-CreateSegment]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-DeleteExperiment]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[evidently-rest-json-DeleteFeature]
…
tests.unit.aws.protocol.test_op_router ‑ test_create_op_router_works_for_every_service[signer-data]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-data-rest-json-GetRevocationStatus]
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_double_dollar_raises
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_empty_expression
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_filter_expression_with_variable
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_filter_predicate_bare_dollar_equals_zero
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_filter_predicate_with_context_variable
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_lone_dollar_ignored
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_multiple_variables
tests.unit.services.stepfunctions.test_jsonata_variable_references.TestExtractJsonataVariableReferences ‑ test_no_variables
…
This pull request skips 19 tests.
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-AddProfilePermission]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-CancelSigningProfile]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-DescribeSigningJob]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-GetRevocationStatus]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-GetSigningPlatform]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-GetSigningProfile]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-ListProfilePermissions]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-ListSigningJobs]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-ListSigningPlatforms]
tests.unit.aws.test_service_router ‑ test_service_router_works_for_every_service[signer-rest-json-ListSigningProfiles]
…

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 23, 2026

Test Results (amd64) - Acceptance

7 tests  ±0   5 ✅ ±0   3m 2s ⏱️ -3s
1 suites ±0   2 💤 ±0 
1 files   ±0   0 ❌ ±0 

Results for commit 8ad96a6. ± Comparison against base commit a857a31.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

S3 Image Test Results (AMD64 / ARM64)

    2 files      2 suites   8m 32s ⏱️
  573 tests   521 ✅  52 💤 0 ❌
1 146 runs  1 042 ✅ 104 💤 0 ❌

Results for commit 8ad96a6.

@github-actions
Copy link
Copy Markdown

Test Results (amd64) - Integration, Bootstrap

    5 files  ±0      5 suites  ±0   2h 39m 25s ⏱️ - 1m 24s
5 738 tests +1  5 214 ✅ +1  524 💤 ±0  0 ❌ ±0 
5 744 runs  +1  5 214 ✅ +1  530 💤 ±0  0 ❌ ±0 

Results for commit 8ad96a6. ± Comparison against base commit a857a31.

@github-actions
Copy link
Copy Markdown

LocalStack Community integration with Pro

    2 files  ±0      2 suites  ±0   2h 3m 22s ⏱️ + 1m 41s
5 333 tests +1  4 965 ✅ +1  368 💤 ±0  0 ❌ ±0 
5 335 runs  +1  4 965 ✅ +1  370 💤 ±0  0 ❌ ±0 

Results for commit 8ad96a6. ± Comparison against base commit a857a31.

Copy link
Copy Markdown
Contributor

@bentsku bentsku left a comment

Choose a reason for hiding this comment

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

LGTM, very nice set of changes 💯

Only very minor comments, but I think we should get this PR in ASAP and fix those later if we want to, this way we can migrate the last services 👍 Very nice work churning through all of those services and cleaning up 🧹

Also, thanks a lot for fixing S3 cross-account cross-region behavior for tags 🙏 this looks great

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

good to move out logic from the models to the provider 👍 nice work

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice refactoring 👍

Comment on lines +105 to +111
custom_key_material = None
tags = request.get("Tags", [])
for tag in tags:
if tag["TagKey"] == TAG_KEY_CUSTOM_KEY_MATERIAL:
custom_key_material = base64.b64decode(tag["TagValue"])

return custom_key_material
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: this could be simplified a bit directly returning in the if block if we find the tag key, but not worth changing I believe 👍

Comment on lines +41 to +43
@staticmethod
def get_route53_store(account_id: str, region: str) -> Route53Store:
return route53_stores[account_id][region]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: this maybe could have been in the Pro implementation as it isn't used here (in case somebody deletes it), but is also fine to leave right now to not delay merging this, we can cleanup later!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice changes for S3, thanks for fixing up the cross-account cross-region nature of the tags! this is much better!

_tags if the resource has been deleted.

This distinction is important to maintain parity with the Resource Groups Tagging API (RGTA) which will tap into
supported service's `Tags` dataclass within it's store.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit, let's clean up later 👍

Suggested change
supported service's `Tags` dataclass within it's store.
supported service's `Tags` dataclass within its store.

@aidehn aidehn marked this pull request as ready for review February 23, 2026 15:30
@aidehn aidehn merged commit 3e9d30f into main Feb 23, 2026
43 checks passed
@aidehn aidehn deleted the aidehn/feat/rgta-migration branch February 23, 2026 17:13
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

docs: skip Pull request does not require documentation changes notes: skip Pull request does not have to be mentioned in the release notes semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants