fix(providers): declare the two NatGateway / LogGroup wiring gaps as silent drops so they auto-route via Cloud Control - #1429
Merged
Conversation
…silent drops so they auto-route via Cloud Control Both properties were declared in handledProperties while nothing read them, so a template setting either deployed successfully with the value discarded. Both issues proposed wiring them into create; for MaxDrainDurationSeconds that is impossible. It is not a CreateNatGatewayRequest member and EC2 ships no ModifyNatGateway operation at all, the only two SDK inputs carrying it being DisassociateNatGatewayAddress and UnassignPrivateNatGatewayAddress, which is why the registry schema lists it under writeOnlyProperties. cdkd rejects every NatGateway property change, so it has nowhere to deliver the value. Modelling it as a replacement trigger was rejected too: the registry schema does not list it under createOnlyProperties, so recreating a gateway on a drain-timeout change would diverge from CloudFormation and needlessly break the data plane. ResourcePolicyDocument takes option 2 of its issue for the reason the issue gives: logs:PutResourcePolicy is account-scoped, not per-log-group, so owning it from a log group lifecycle would require inventing an ownership answer. Managing the sibling AWS::Logs::ResourcePolicy resource remains the real feature. Neither provider sets disableCcApiFallback, so declaring the drop does not hard-reject these templates. It fires the auto-route and provisions through Cloud Control, where AWS's own handler applies the value. Routing is sticky from state, so already-deployed resources do not flip layer mid-life. Closes #1411 Closes #1412
…ng-stickiness claim Review findings on the first cut. The cleanup trap wiped the state file unconditionally. A classic NAT stuck in deleting makes the VPC delete fail with DependencyViolation, and dropping the state anyway would orphan a per-hour-billed NAT and VPC with nothing left to retry from. The removal is now gated on the state destroy exit status, and the skip is announced. Two smaller fixture defects: the missing-constant diagnostic was unreachable because set -e aborts at the grep assignment, and the post-destroy assertion accepted deleting as success even though both delete paths wait for settle, so a deleting readback means the wait did not hold. The changelog claimed routing stickiness prevents an existing SDK-provisioned resource from flipping layer. That is wrong: stickiness is cc-api to cc-api only, so such a resource does re-evaluate and move to Cloud Control on its next update, which is the intended outcome.
go-to-k
force-pushed
the
fix/1411-1412-handled-wiring-gaps
branch
from
August 9, 2026 14:37
223c0a5 to
90d5fa7
Compare
github-actions Bot
pushed a commit
that referenced
this pull request
Aug 9, 2026
## [0.278.16](v0.278.15...v0.278.16) (2026-08-09) ### Bug Fixes * **providers:** declare the two NatGateway / LogGroup wiring gaps as silent drops so they auto-route via Cloud Control ([#1429](#1429)) ([a39e201](a39e201))
|
🎉 This PR is included in version 0.278.16 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Both properties were declared in
handledPropertieswhile nothing read them, so a template setting either deployed "successfully" with the value discarded. Found by the first real-tree run of thehandled-property-wiringcritic (#1404), which seeded them as tracked KNOWN GAP allow-list entries rather than fixing them in the critic's own PR.Both issues proposed wiring the property into
create(). For #1411 that turned out to be impossible, and re-deriving it changed the fix.#1411 —
AWS::EC2::NatGateway.MaxDrainDurationSecondsVerified against the installed
@aws-sdk/client-ec2:CreateNatGatewayRequest(models/models_1.d.ts) has noMaxDrainDurationSecondsmember.ModifyNatGateway*operation at all (ls dist-types/commands/ | grep -i natgateway).DisassociateNatGatewayAddressRequest(models_5) andUnassignPrivateNatGatewayAddressRequest(models_7) — it is a per-call drain timeout for RELEASING secondary addresses, which is why the CFn registry schema lists it underwriteOnlyProperties.updateNatGatewayrejects every NatGateway property change, so it never issues those two calls and has nowhere to deliver the value.Modelling it as a replacement trigger — the issue's fallback — was rejected too: the registry schema does not list it under
createOnlyProperties, so recreating a gateway on a drain-timeout change would diverge from CloudFormation and needlessly break the data plane.#1412 —
AWS::Logs::LogGroup.ResourcePolicyDocumentTakes option 2 of the issue, for the reason the issue itself gives: the value maps to the separate
AWS::Logs::ResourcePolicytype, whoselogs:PutResourcePolicyis account-scoped, not per-log-group. Owning it from a log group's lifecycle would mean inventing an ownership answer cdkd has no basis for — which policy name to claim, what to do on delete when the account-wide policy may be shared, how to resolve two log groups declaring conflicting documents. Managing the sibling resource remains the real feature.Both are now
unhandledByDesign, which is better than either alternativeCorrecting a premise carried in both issues: neither provider sets
disableCcApiFallback, so declaring the drop does NOT hard-reject these templates via the #614 viability guard. It fires the #614 auto-route — the resource is provisioned through Cloud Control API, where AWS's own resource handler applies the value.That is strictly better than both the silent drop and a reject.
Note on existing stacks: routing stickiness is
cc-api->cc-apionly (provider-registry.ts). A resource already recorded asprovisionedBy: 'sdk'whose template sets one of these properties WILL re-evaluate and flip to Cloud Control on its next UPDATE —deploy-engine.tsdoes this deliberately. That is the intended outcome (the value starts being applied instead of dropped) and carries no physical-ID churn, since Cloud Control updates in place.Both
HANDLED_WIRING_ALLOW_LISTentries are removed, so the critic now verifies the fix instead of excusing it: 0 gaps, 2 allow-listed (down from 4).Test plan
10 new unit tests across two files. Each asserts the property is absent from
handledProperties, present inunhandledByDesignwith a rationale, reported byfindSilentDropProperties, and thatProviderRegistry.getProviderForroutes to CC for a template setting it and to SDK for one that does not. Plus a guard thatCreateNatGatewaynever carries the field, and a fence that neither retired property may return tohandledProperties.Revert-proofed: re-adding both properties to
handledPropertiesfails 6 of 10 and makesaudit:handled-property-wiring:checkfail naming both.tests/unit/scripts/gen-handled-property-wiring.test.tsre-pointed its real-code stale-entry probes onto a still-live allow-list entry (IAMAccessKeyProvider#Serial), since the two they were bound to are now gone.Real AWS integ (
/run-integ vpc-nat-gateway, us-east-1, 265s, PASS). The fixture gains a SECOND, L1-only private NAT gateway setting the property, so the L2 gateway stays on the SDK path and the two together assert heterogeneous routing in one stack. Live output confirms the route is chosen for the stated reason:Assertions: template/state carry
MaxDrainDurationSeconds=120; drain gatewayprovisionedBy == 'cc-api'; plain gatewayprovisionedBy == 'sdk'; both live on AWS with the drain oneavailableandConnectivityType=private(proof CC forwarded the full property map); both gone after destroy; state gone. Destroy: 22 deleted, 0 errors, 0 orphans.The value is
writeOnlyPropertiesand no EC2 API returns it, so a read-back-and-compare assertion is structurally impossible — the fixture asserts the routing consequence plus a vacuity guard that greps the literal out of the stack file so the two cannot drift.Full suite: 524 files / 8949 tests pass.
Deliberately not done
AWS::Logs::LogGroup:ResourcePolicyDocumentdeclared handled but never wired #1412's routing. SettingResourcePolicyDocumentmakes AWS create an account-wideAWS::Logs::ResourcePolicy, which would collide with other fixtures sharing the integ account and is awkward to clean up. The mechanism it would exercise is the same Add Cloud Control API greenfield fallback for unhandled top-level properties #614 auto-route the NAT-gateway fixture now proves end-to-end against real AWS, so the marginal value does not justify the account-wide side effect. Recorded in theunhandledByDesignJSDoc.MaxDrainDurationSecondsfrom the SDK path. That means liftingupdateNatGateway's blanket rejection and adding associate/disassociate/assign/unassign handling: a substantial feature, out of scope for a wiring-gap fix, and the CC route already delivers the property correctly today. Recorded in the code comment.AWS::Logs::ResourcePolicy(option 1 ofAWS::Logs::LogGroup:ResourcePolicyDocumentdeclared handled but never wired #1412). The issue calls this "the real feature"; option 2 was the maintainer's stated preference. Recorded in theunhandledByDesignJSDoc.Closes #1411
Closes #1412