Resource Groups is routed through the generated resourcegroups Smithy API
(Boto3 service name resource-groups) and the shared typed command executor.
All 23 modeled operation names are registered. This does not complete the full
selected-service target: EC2 specialty groups and unavailable query owners
remain explicit prerequisites. Application tag synchronization and lifecycle
capture use actual owner state and current IAM authority, not metadata-only
success. Positive native AppRegistry/GLE parity is not claimed.
Ordinary groups retain their scoped name/ARN, description, resource query and tags in typed memory and SQLite repositories. Create, get, update, delete, query get/update, group listing and tagging operate on the same owner state. The common Resource Groups Tagging API discovers groups and dispatches its tag and untag mutations to this owner. A query group can discover itself.
SearchResources and ListGroupResources evaluate current owner snapshots,
not a retained ARN catalog or the Tagging API's historical previously-tagged
view. Owner tag changes, deletion and recreation affect the next query. Query
results use the generated CloudFormation resource type names. The published
support table determines query eligibility, not availability of an implemented
owner; unsupported or absent owners are not synthesized from table rows.
The two query forms are:
TAG_FILTERS_1_0: resource type union; distinct tag keys are ANDed, values within a key are ORed. Omitted/emptyValuesrequires key presence. An empty string value matches an actual empty tag value. Native duplicate-key behavior uses the final filter for that key. JSON member names are case-sensitive; duplicate resource types, unknown members/types and malformed query documents are rejected.CLOUDFORMATION_STACK_1_0: the stack ARN resolves through the real CloudFormation repository, then through the current live resource owners. Direct current deployments participate; stale replacement/retention history does not. Membership requires the live native row's private CloudFormation owner claim for that exact stack, logical ID and incarnation; public tags and the stack's own resource records prove nothing. An out-of-band delete/recreate, or a copied/forged public marker, therefore cannot impersonate the old CloudFormation resource. Resource families without a native private claim (for example EC2 images/snapshots, ECS tasks and Organizations roots) never appear as stack members. A missing stack producesCLOUDFORMATION_STACK_NOT_EXISTINGin search results. KnownDELETE_COMPLETE,ROLLBACK_COMPLETEandCREATE_FAILEDstacks produceCLOUDFORMATION_STACK_INACTIVE. Creating/updating a query for a missing or inactive stack is rejected instead.CREATE_IN_PROGRESSis not itself an inactive status.
ListGroups filters group definitions: its resource-type filter does not
expand a definition's AWS::AllSupported into every resource type. Ordinary
groups do not support DisplayName, Owner or Criticality mutation; these
modeled fields are rejected rather than silently persisted. Empty descriptions
are omitted from group responses. Tag returns the submitted tag set, not the
entire merged set; Untag returns the submitted keys, including absent keys.
List/search pagination uses deterministic sorted keys and scoped, query-bound continuation tokens. Changing the query or scope invalidates a token. Cursors do not impose an unverified expiry or depend on process-local signing state. They do not reproduce AWS's internal page layout or possible empty intermediate pages. Owner evaluation is current on each page, not a historical snapshot of changing remote resources.
Run Command's resource-groups:Name and optional
resource-groups:ResourceTypeFilters consume this owner's current membership,
not a second group or tag store. The consumer checks
resource-groups:ListGroupResources on the scoped group, resolves the current
query in the shared transaction, and projects only eligible EC2 members onto
registered, running SSM nodes. Ordinary interactive query API authorization is
unchanged; native SSM does not additionally require tag:GetResources,
GetGroup or GetGroupQuery. SSM still checks its document and each selected
instance's SendCommand authority.
Tag/query changes affect subsequent admissions; already admitted invocations keep their selection across controller restart. Missing groups are empty SSM selections, while listing denial produces a failed command. This does not add hybrid managed instances or executable support for other resource families. See SSM targeting and native calibration for the syntax, timing and evidence boundaries. The actual official-agent guest workflow observed selected stdout, tag exclusion, retained selection across query change and SQLite/controller restart, restored membership and real SNS→SQS notifications, with independent owned-resource cleanup.
AWS::KMS::Alias is a
stack-only resource type.
Stack queries read the current scoped KMS alias rows and require the owner's
stack ID, logical ID and physical-incarnation token to match the current
deployment. Neither a matching name nor CloudFormation history proves ownership.
Aliases do not inherit key tags and are not added to tag-based discovery.
Schema 297 retains that private owner identity with the alias. CloudFormation
create recovery reuses only an exact owned alias under current KMS permissions;
update/delete reject a foreign replacement. Native UpdateAlias preserves the
incarnation, while native delete/create resets it. Legacy aliases without an
owner remain unclaimed; migration does not infer ownership from stack history.
integration/cloudformation_kms_alias_test.go verifies signed SDK stack queries,
scope, native retargeting, same-name recreation and foreign update/delete
rejection across memory/SQLite reopen. An actual SQLite executable restart
verifies these transitions and stack/alias cleanup. A separate fresh-process
handler smoke recovers an already-committed alias without changing its creation
timestamp. These are local ownership proofs, not a native AWS crash/recreation
capture; AWS's documented alias properties remain the
public contract.
AWS::Lambda::Alias likewise uses current, scoped Lambda alias rows and exact
stack/logical/incarnation matching, not inherited function tags. Native alias
retargeting preserves membership; delete/recreate removes it even if the name
and target are identical. Schema 298 retains the private identity across restart.
The native capture returned
the actual alias from a stack-backed group and verified owned-resource cleanup.
The provider workflow adds signed SDK and
actual provisioned-runtime/restart proofs without claiming native recovery parity.
AWS::Lambda::Version membership reads the current scoped publication receipt
and exact stack/logical/incarnation identity. Schema 299 retains that receipt
atomically with the immutable version; native and legacy publications cannot be
adopted from stack history. Deletion removes membership, and replacement admits
the new owned version rather than its retired predecessor. Versions do not inherit
function tags. The native capture
observed the qualified version ARN in a version-filtered stack-backed group.
Deployment and runtime evidence distinguishes
public AWS behavior from the local private recovery contract.
AWS::Lambda::LayerVersion membership reads the current layer publication and its
private stack/logical/incarnation owner. Replacement admits only the current owned
publication; catalog deletion removes membership even while functions retain the
old archive. Native and legacy rows cannot be adopted from CloudFormation history.
Layers are stack-only members, not inferred function-tag members. The
native lifecycle capture
recorded a bounded membership miss rather than a permanent exclusion.
Deployment and executable evidence
covers layer-backed application replacement, retirement and SQLite restart.
The generated servicecatalogappregistry frontend (Boto3
servicecatalog-appregistry, IAM/ARN namespace servicecatalog) owns scoped
applications, JSON-object attribute groups, associations, tags and regional
tag-query configuration. Immutable create-token fingerprints prevent replays
after update/restart from reverting state. Deletion requires explicit
disassociation and never deletes customer resources. Lists use scoped,
operation/association-bound cursors.
Application and attribute-group updates accept an explicit unchanged name. This permits Terraform's description and attribute updates without treating the current name as a rename. Current IAM checks still run; actual name changes remain unsupported. SDK memory/SQLite regressions and the Terraform governance update/reopen lifecycle exercised this behavior.
An application has separate servicecatalog, legacy application-group and modern
application-group identities. The modern Resource Groups ARN is the
awsApplication tag value. Legacy groups contain actual stack/tag-query child
collections. Managed configuration and legacy metadata are protected; modern
UpdateGroup supports DisplayName, Owner and Criticality with real filters.
Application grouping currently admits S3 buckets, SQS queues, SSM parameters and
CloudFormation stacks. Managed application/tag-value queries explicitly name
these implemented owner types. AssociateResource accepts CFN_STACK and
RESOURCE_TAG_VALUE; ordinary resources use grouping or native owner tagging.
Omitted options mean SKIP. APPLY checks current dependent owner permissions;
failed associations roll back child groups, owner tags and admitted stack jobs.
The tag-value collection is a real query group, not a fabricated ARN. Its
deterministic local name is not claimed to reproduce native naming.
CloudFormation tag updates use the actual asynchronous stack owner. Pending effects are not reported as completed, and failed grouping outcomes do not leave prior success as the latest result. Stable owner incarnations fence status and task cleanup after recreation. Terminal grouping history remains stable after unrelated tag changes. Tag-value APPLY uses current matches; continuous matching/removal belongs to a real tag-sync task.
The AppRegistry service-linked role uses current IAM trust/managed policy; customer tag effects retain caller authority. Applications and unexpired role sessions prevent role deletion. AppRegistry audit uses the captured hyphenated event source, URI labels, missing-resource wildcards and native mutation error bodies. Generated source metadata is corrected for both AppRegistry and Resource Groups so configured CloudTrail/EventBridge consumers can accept those events.
Native credentials here cannot create applications or attribute groups because
of new-customer maintenance mode. testdata/aws/appregistry/ retains 49 actual
observations and all 49 exact request-ID-matched CloudTrail events, unchanged
settings and exact attempted-name absence. Its native-contracts.json separates
documented positive contracts from captures. Local positive workflows are not
successful native parity evidence.
Groups are isolated by partition, account and region. Commercial global IAM
resources participate in the calibrated us-east-1 query scope; noncommercial
global home-region behavior remains uncalibrated.
Every command uses current reusable IAM evaluation. Group calls provide the
current group's aws:ResourceTag/* values; tagging also supplies request tags
and tag keys. Create uses resource-groups:CreateGroup on * and additionally
checks resource-groups:Tag for a tagged prospective group. Tag queries check
the dependent tag:GetResources authority. Stack queries check
cloudformation:DescribeStacks and cloudformation:ListStackResources.
Changing a role policy or a group tag affects an already-issued role session's
next request.
The repositories share the existing memory/SQLite transaction domain. Mutations and successful API records commit together; an error rolls back the attempt and records the rejected outcome through the shared completion path. SQLite uses normalized group, tag, grouping, task-owned membership, lifecycle account and lifecycle snapshot tables with SQLC-generated queries and the canonical generated bootstrap schema. Reopening the executable preserves task selectors, due work, group incarnations and event sequences, while discovery still consults current owners. Snapshots are detached observations, never a second authoritative owner tag store.
The native-calibrated audit projection uses
resource-groups.amazonaws.com, not the unhyphenated Smithy metadata value.
Events are management AwsApiCall records. Get/List/Search are read-only and
omit response contents; mutations retain response contents, including native
Message error bodies. Request/response field names retain their modeled
capitalization. Tagging ARN request labels use native percent encoding.
Create/update/delete audit group objects include the native unmodeled OwnerId.
GetGroup, GetGroupQuery, GetGroupConfiguration and ListGroupResources supply
native event resources, including rejected lookups; lookup resource search
terms remain separate. Native captured errors have errorCode but omit
errorMessage. These projections do not change the public API response shapes.
StartTagSyncTask requires a real modern application group, current
resource-groups:StartTagSyncTask and resource-groups:CreateGroup permissions,
and iam:PassRole on the supplied same-account role with
iam:PassedToService=resource-groups.amazonaws.com. Specify either a tag-based
ResourceQuery or both TagKey and TagValue; an empty tag value is meaningful.
The original selector is retained separately from the application's
awsApplication query. Public GLE enrollment is not imposed as an undocumented
prerequisite: the official Start API and AppRegistry tag-sync guide do not list it.
The shared deterministic driver scans current supported application owners.
Each effect freshly assumes the supplied role through its current trust policy,
checks grouping/tagging permissions and invokes the native owner tagging command.
Its tag mutation, incarnation-fenced task ownership and grouping observation
share one transaction. An owner failure rolls back that effect without undoing
effects already committed for other owners. Current trust or policy revocation
is visible as task ERROR; later successful scans restore ACTIVE.
Only tags actually applied by a task are candidates for its removal. Existing
direct application membership is not adopted, a later successful direct
grouping takes ownership, and a different application's tag is not overwritten
or removed. Deleting/recreating an owner cannot reuse an old task membership.
Pending CloudFormation tagging is not reported as a completed grouping.
CancelTagSyncTask checks cancellation and dependent deletion authority,
deletes the task and stops future effects. It leaves existing owner tags alone;
the published cancellation contract does not promise retroactive tag cleanup.
Already admitted asynchronous owner operations can still finish. Deleting the
owning group atomically removes its tasks.
GLE activation checks the documented caller dependencies and creates the actual
AWSServiceRoleForResourceGroups IAM role using the captured
ResourceGroupsServiceRolePolicy. Lifecycle scans assume this role with current
trust and permissions. IN_PROGRESS becomes ACTIVE only after a successful
initial capture; owner/authority failures are reported rather than represented
by an inert active flag. Disabling GLE stops capture and releases IAM role usage.
The role cannot be deleted while the account setting still requires it.
The local capture mechanism is a retained one-second source snapshot scan,
not a fabricated EventBridge managed rule or target. Initial activation
baselines existing groups. Subsequent observed creations, description/query/
configuration changes, deletions and membership transitions publish the
documented aws.resource-groups state/membership events through the existing
transactional EventBridge publisher to the default bus. Event sequence and group
UUID survive restart; same-name group replacement gets a new UUID and sequence.
Snapshot changes and event acceptance commit together. As with any sampled
snapshot, multiple changes between scans can coalesce; this is not a claim of
capturing every native tag/CloudFormation source event or reproducing AWS's
internal Managed.ResourceGroups.TagChangeEvents setup. Application owner
incarnations are fenced; other query-owner snapshots retain their existing
discovery boundaries.
The dedicated local executable probe is
scripts/aws/resource_groups_sync_executable_smoke.py --binary <stackd-binary> --state-directory <fresh-owned-directory>. It exercises signed SDK task
admission, current delegated owner/trust denial and recovery, ownership-safe
removal/cancellation, SQLite restart, and actual lifecycle EventBridge-to-SQS
delivery. The exercised report is
testdata/integration/resourcegroups_sync_executable.json: three zero-exit
controller runs, six delivered events, retained sequence/UUID across restart,
new UUID after group replacement and exact cleanup. Role deletion waits for
real issued sessions to expire; disabling GLE does not delete its IAM role.
The full Resource Groups target remains open. The following are required real work, not optional extensions or successfully implemented operations:
| Boundary | Current behavior | Missing owner/effect |
|---|---|---|
| Capacity reservation pools | A structurally admissible configuration returns NotImplementedException; no group is created. |
EC2 capacity-reservation ownership, applicable shared/RAM authority and real instance placement into pool capacity. |
| Dedicated Host management | Missing configuration is rejected; an admissible configuration reports NotImplementedException. |
EC2 Dedicated Host allocation/release and License Manager host-management effects. |
| Network Firewall groups | Native instance-query configuration is recognized but returns NotImplementedException. Invalid/missing query forms are rejected. |
Real Network Firewall rule-group ownership and updates from current associated EC2 instance addresses. |
| AppRegistry remaining depth | Real application/group/tag effects exist for the four named owners. SyncResource remains model-known unsupported, not an alias for awsApplication. |
Native existing-customer calibration, legacy CloudFormation AppRegistry system tags, other application owners and older-application upgrades. |
| Native tag-sync/GLE conformance | Real retained task execution and lifecycle snapshot publication are implemented locally. | An eligible native account is needed to calibrate successful task timing, cancellation, managed capture setup and lifecycle event details; transient changes between local scans can coalesce. |
| Additional query owners | Absent owners contribute no phantom resources. | Current typed snapshots for nested-stack deployments and service-linked specialty resources. |
| Other partition global scopes | No unsupported home-region inference. | Native calibration for aws-cn and aws-us-gov. |
The captured native account rejects new lifecycle/tag-sync enrollment following
AWS's availability change. This is not implemented as a universal denial:
existing eligible customers remain part of the full target. The account-specific
refusal is retained in native fixtures, not used as a local admission rule.
Specialty-owner prerequisites remain in configuration.go and the current owner
discovery adapter.
Native fixtures under testdata/aws/resourcegroups/ retain request IDs and
positive/negative responses:
native.json: 182 observations, including actual S3/SQS owners, group query selection, query/type/configuration validation and direct CloudFormation membership. Initial expected-selection annotations are retained even where disproven;selection[].actualis the observed result used by replay.native-query-boundaries.json: 32 observations covering case-sensitive query syntax, duplicate types, missing stack behavior, task filters and a real CREATE_IN_PROGRESS-to-CREATE_COMPLETE stack.native-attributes.json: 16 observations establishing ordinary-group attribute and definition-filter behavior.native-audit.json: 174 exact-owned-prefix CloudTrail events over six lookup pages, with every expected owned-prefix request ID observed. Unrelated events and credential fields are not retained. Completeness is limited to those request IDs; missing/late-event non-inference remains explicit.native-contracts.json: authoritative contracts and capture limitations.supported_resource_types.json: the pinned 1,204-row AWS support table, source digest and per-query eligibility. Its generator is offline by default; refreshing requires explicit--refresh.
All three mutating native captures verified exact-owned cleanup (57 cleanup and absence observations in total). Their groups, buckets and queues are gone; CloudFormation's provider-retained DELETE_COMPLETE history remains. Account settings were read only and remained INACTIVE. No capacity reservation, dedicated host, billed instance or firewall rule was provisioned, and successful application/tag-sync effects are not claimed.
integration/resourcegroups_sdk_test.go replays actual native selections
through the official Go SDK over memory and SQLite, preserving group
self-selection while explicitly excluding native specialized groups whose
owners are absent locally. It covers owner deletion/recreation and current
tagging, query-bound pagination, invalid update rollback and reopen. The
native definition-filter regression was observed failing before the fix with
AllSupported definition incorrectly treated as an explicit SQS type filter;
the retained subtest then passes on both backends.
The local executable smoke uses Boto3 against an explicitly local endpoint and
test credentials, not ambient native credentials. It runs the actual
cmd/stackd binary over SQLite, reads real S3 object bytes and SQS messages,
checks current-role/tag revocation, exercises CloudFormation replacement and
out-of-band recreation fences, restarts the process, validates all 23 operation
outcomes and their CloudTrail history, and verifies cleanup. The captured report
is testdata/integration/resourcegroups_executable.json.
scripts/aws/appregistry_executable_smoke.py exercises signed application,
attribute, configured tag-value and stack APPLY/SKIP flows, rollback, modern
grouping, real owner data planes, current-role denial/recovery, restart and
owner/name reuse. It reads configured CloudTrail gzip objects from S3 and compares
reachable missing-owner events with native captures. The exercised local report
is testdata/integration/appregistry_executable.json; both controllers exit zero
and exact-owned cleanup succeeds. Focused SDK/memory/SQLite tests also cover
immutable create-token replay, cursor binding, attribute validation, coordinated
rollback and same-clock owner recreation.
The combined schema-260-to-264 executable upgrade is captured in
testdata/integration/appregistry_upgrade.json. Existing SES template state,
S3 bytes, an actual queued SQS message, an SSM parameter and a three-owner
Resource Groups query survive migration. The new AppRegistry application groups
those existing owners; its identity and membership survive another restart and
an SSM version update. All three controllers exit zero and all seven owned
resources are removed with absence checks. This verifies local upgrade behavior,
not successful native AppRegistry conformance or older AppRegistry application upgrades.
From the repository root (Go 1.26 and Boto3 installed):
go test -race ./storage/sqlite/resourcegroups ./integration -run '^(TestGroupsRemainAtomicScopedAndDetached|TestResourceGroupsNativeSelectionAndOwnerTransitions)$' -count=1 -v
go build -o /tmp/stackd-resourcegroups ./cmd/stackd
python3 -B scripts/aws/resource_groups_executable_smoke.py --binary /tmp/stackd-resourcegroups --state-directory /tmp/rg-fresh-owned-proof
python3 -B -P scripts/aws/resource_groups_types_capture.py --checkThe smoke uses the shared scripts/aws/stackd_process.py controller, recording
real process exits and owned log/state paths. The state directory must be new
and empty. resource_groups_capture.py is a native AWS probe, unlike the
executable smoke; it verifies caller identity, owns unique resources and
requires explicit native credentials. Its --query-boundaries, --attributes
and read-only --audit modes correspond to the retained fixtures.
Authoritative references:
- ResourceQuery
- Resource Groups IAM actions and conditions
- Service-linked group configuration types
- Supported resource types
- CloudTrail logging
- Lifecycle-event availability change
- StartTagSyncTask and selector/permission contracts
- CancelTagSyncTask permissions
- AppRegistry resource tag-sync behavior and delegated role
- GLE activation prerequisites
- Lifecycle event detail and group incarnation contract
- Resource Groups service-linked role
- Captured lifecycle managed policy v1
- Turning off lifecycle events and role retention
- AppRegistry native and documented contracts