Repository navigation
fix(aws/redshift): verify reserved-node tagging contract used by purchase idempotency #107
Description
Summary
Verify and correct the Redshift reserved-node tag contract used for purchase idempotency. The current code depends on tag operations on a constructed reserved-node ARN, but AWS's documented taggable resource list does not include reserved nodes. Adding IAM actions alone does not establish that this resource/API combination is supported.
Current behavior
At 81f2fc3ac44ce47221682fa1c50dec26e4f24eed, providers/aws/services/redshift/client.go:
scanNodesForTokenconstructsarn:aws:redshift:<region>:<account>:reservednode:<id>for active/payment-pending nodes and callsnodeHasIdempotencyTag(lines270-286).nodeHasIdempotencyTagcallsDescribeTags; any lookup error propagates and causes a tokened purchase to be refused before buying.tagReservedNodeuses the same ARN withCreateTags(lines332 and382). A post-purchase tagging error is logged while the successful purchase result is returned. The pre-purchase guard therefore depends on a marker whose supported write/read contract has not been established.
AWS's Redshift tagging guide enumerates supported resource types without reserved nodes. This is a documented-contract gap, not a claim that a live AWS request was executed or rejected. No purchase, tag mutation or credentialed cloud verification was performed.
Steps to verify the gap
- Trace
PurchaseCommitmentthroughfindNodeByIdempotencyToken,scanNodesForToken,nodeHasIdempotencyTagandtagReservedNodeat the commit above. - Reconcile the exact ARN and resource type with AWS's current
DescribeTags/CreateTagscontract. Establish support from authoritative documentation or separately authorized read-only evidence; do not buy a reservation to test it. - Exercise the actual pre-purchase path with an existing active node and a nonempty idempotency token, including a tag lookup error. Exercise post-purchase tag failure and a re-drive without permitting a second real purchase.
Expected behavior and proposed fix
Use a supported, durable idempotency mechanism, and make the limits of post-purchase reconciliation explicit. If the tag API cannot support reserved nodes, replace that assumption at its source; do not suppress lookup errors or broaden IAM to imply the feature works. Confirm first that the chosen mechanism survives an interrupted purchase and cannot silently double-buy on retry.
Keep the provider behavior fix separate from PR LeanerCloud/cloud-commitments-cli#2077's six CE/EC2 runtime grants. Its proposed Redshift tag grants are being removed pending this contract verification. Update the related tests in providers/aws/services/redshift/client_test.go with actual error/re-drive shapes, not only happy-path tag mocks.
References and triage
- Found during PR LeanerCloud/cloud-commitments-cli#2077, which addresses fix(iac/aws): ce:GetCostAndUsage is granted in no IaC flavor; ladder baselines are denied cloud-commitments-cli#1967/#1968 and does not repair Redshift idempotency.
- Closed feat(purchases): extend IdempotencyToken to all commitment executors (AWS RDS/ElastiCache/MemoryDB/OpenSearch/Redshift, Azure, GCP) — blocks #639 cloud-commitments-cli#641 introduced the multi-service idempotency behavior; closed PR fix(purchases): recover executions stranded in 'approved' (closes #632) cloud-commitments-cli#635 addressed stranded execution recovery and does not prove this AWS tag contract.
- Open fix(aws): OpenSearch and Redshift idempotency guards page every reservation uncapped #87 concerns uncapped idempotency scans. Its proposed
ResourceType: "reservednode"optimization must not be implemented without resolving this contract first. - Open chore(aws): medium/low findings from the 2026-07-28 full review #53 tracks cached STS failures, and ARCH-03: AWS RI purchase skeleton (idempotency guard etc.) copy-pasted across 5-6 service clients #10 tracks duplicated purchase code; neither covers resource support for reserved-node tagging.
Severity: medium, limited Redshift users; priority P2 pending contract verification. Potential consequences include refusing legitimate tokened purchases or unreliable re-drive deduplication. No observed duplicate purchase is claimed. Effort M; investigate this sprint before adding tag grants or optimizing the tag scan.
Activity
fix(iam): limit runtime additions to supported CE and EC2 calls
fix(iac/aws): grant six required runtime CE and EC2 actions (#2077)
cristim commentedon Oct 7, 2026
claimed by cc-go-w4
cristim commentedon Oct 7, 2026
The documented Redshift contract doesn't establish reserved-node tagging or a replayable purchase request. Independent source review checked Go head
c31e229b935e5efb17755caa262d9eaa8eea7aa4, pinned Redshift SDK v1.58.3, and the current AWS API documentation.DescribeTags lists its valid resource types explicitly and omits reserved nodes, as does the tagging guide. CreateTags accepts an ARN but doesn't establish support for the constructed reserved-node ARN. Resource Groups tagging also depends on underlying service support.
PurchaseReservedNodeOffering accepts only the offering ID and node count, with no client token or caller-selected reservation ID. It does document
ReservedNodeAlreadyExists, so the library comment saying that fault doesn't exist needs correction, but the fault provides no documented caller-controlled identity or replay guarantee.The current public purchase path refuses a tag-lookup error, but a successful purchase followed by failed tagging still returns success, and interruption before tagging leaves no supported marker for a later re-drive. The existing mock tests establish those branches' control flow without establishing AWS support. No credentialed request, tagging operation or purchase was performed, and no observed duplicate purchase is claimed. The attempted targeted test run didn't acquire the shared runner lock, so this investigation claims source and documented-contract evidence only.
The caller recovery assumption also needs coordination. Public platform main
3131779c5fcdecaf1a8fd5dbfe93f590235fe1b5marks every AWS service safe for re-drive, and both automatic recovery and the Retry endpoint use that predicate. Execution status and purchase ID are recorded after purchase fanout, so the existing execution rows don't provide a per-recommendation dispatch journal. The finding has been relayed to the platform owners, without platform edits or duplicate dispatch.A purchase-preserving fix needs a caller-backed durable attempt record: claim before dispatch, persist the returned reservation ID, adopt recorded success, and refuse unresolved dispatched attempts. Explicit refusal of tokened Redshift purchases is a smaller containment option but would also block the platform's legitimate first purchases. Removing tokens, suppressing errors, or matching inventory characteristics wouldn't satisfy durable idempotency. The purchase operation's configured SDK retry attempts also need review because retries can occur inside one library call.
PR #276 covers pagination bounds and cancellation only. This issue stays open for the durable contract fix, and the proposed reserved-node tag-scan optimization in #87 remains deferred.
fix(aws): bound reservation idempotency scans (#276)