@intentius/chant-lexicon-aws 0.46.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/dist/api/read-client.d.ts +10 -2
  2. package/dist/api/read-client.d.ts.map +1 -1
  3. package/dist/codegen/generate-lexicon.d.ts +5 -0
  4. package/dist/codegen/generate-lexicon.d.ts.map +1 -1
  5. package/dist/components/host-delivery.d.ts +4 -3
  6. package/dist/components/host-delivery.d.ts.map +1 -1
  7. package/dist/composites/agentcore-agent.d.ts +26 -1
  8. package/dist/composites/agentcore-agent.d.ts.map +1 -1
  9. package/dist/composites/bucket-deployment.d.ts +82 -0
  10. package/dist/composites/bucket-deployment.d.ts.map +1 -0
  11. package/dist/composites/dynamodb-table.d.ts +45 -0
  12. package/dist/composites/dynamodb-table.d.ts.map +1 -0
  13. package/dist/composites/ec2-instance-bundle.d.ts +61 -0
  14. package/dist/composites/ec2-instance-bundle.d.ts.map +1 -0
  15. package/dist/composites/ecr-repository.d.ts +49 -0
  16. package/dist/composites/ecr-repository.d.ts.map +1 -0
  17. package/dist/composites/fargate-service.d.ts +16 -0
  18. package/dist/composites/fargate-service.d.ts.map +1 -1
  19. package/dist/composites/index.d.ts +16 -2
  20. package/dist/composites/index.d.ts.map +1 -1
  21. package/dist/composites/monitoring-stack.d.ts +99 -0
  22. package/dist/composites/monitoring-stack.d.ts.map +1 -0
  23. package/dist/composites/nlb-service.d.ts +48 -0
  24. package/dist/composites/nlb-service.d.ts.map +1 -0
  25. package/dist/composites/step-functions-workflow.d.ts +36 -0
  26. package/dist/composites/step-functions-workflow.d.ts.map +1 -0
  27. package/dist/deep-observe.d.ts +45 -0
  28. package/dist/deep-observe.d.ts.map +1 -1
  29. package/dist/deep-topology.d.ts +104 -0
  30. package/dist/deep-topology.d.ts.map +1 -0
  31. package/dist/effect-receipt-row.d.ts +92 -0
  32. package/dist/effect-receipt-row.d.ts.map +1 -0
  33. package/dist/index.d.ts +7 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/integrity.json +14 -6
  36. package/dist/lint/audit-catalog.d.ts.map +1 -1
  37. package/dist/lint/post-synth/cf-refs.d.ts +17 -0
  38. package/dist/lint/post-synth/cf-refs.d.ts.map +1 -1
  39. package/dist/lint/post-synth/index.d.ts.map +1 -1
  40. package/dist/lint/post-synth/waw016.d.ts +10 -2
  41. package/dist/lint/post-synth/waw016.d.ts.map +1 -1
  42. package/dist/lint/post-synth/waw061.d.ts +19 -0
  43. package/dist/lint/post-synth/waw061.d.ts.map +1 -0
  44. package/dist/lint/post-synth/waw062.d.ts +19 -0
  45. package/dist/lint/post-synth/waw062.d.ts.map +1 -0
  46. package/dist/lint/post-synth/waw063.d.ts +35 -0
  47. package/dist/lint/post-synth/waw063.d.ts.map +1 -0
  48. package/dist/lint/post-synth/waw064.d.ts +17 -0
  49. package/dist/lint/post-synth/waw064.d.ts.map +1 -0
  50. package/dist/lint/post-synth/waw065.d.ts +23 -0
  51. package/dist/lint/post-synth/waw065.d.ts.map +1 -0
  52. package/dist/lint/post-synth/waw066.d.ts +25 -0
  53. package/dist/lint/post-synth/waw066.d.ts.map +1 -0
  54. package/dist/lint/post-synth/waw067.d.ts +24 -0
  55. package/dist/lint/post-synth/waw067.d.ts.map +1 -0
  56. package/dist/lint/post-synth/waw068.d.ts +20 -0
  57. package/dist/lint/post-synth/waw068.d.ts.map +1 -0
  58. package/dist/manifest.json +1 -1
  59. package/dist/meta.json +34 -0
  60. package/dist/okf/index.md +8 -0
  61. package/dist/okf/rules/WAW061.md +17 -0
  62. package/dist/okf/rules/WAW062.md +27 -0
  63. package/dist/okf/rules/WAW063.md +19 -0
  64. package/dist/okf/rules/WAW064.md +18 -0
  65. package/dist/okf/rules/WAW065.md +25 -0
  66. package/dist/okf/rules/WAW066.md +22 -0
  67. package/dist/okf/rules/WAW067.md +20 -0
  68. package/dist/okf/rules/WAW068.md +19 -0
  69. package/dist/okf/types/Action.md +1 -0
  70. package/dist/okf/types/AutoScalingGroup.md +1 -0
  71. package/dist/okf/types/Bucket.md +1 -0
  72. package/dist/okf/types/EC2Route.md +2 -0
  73. package/dist/okf/types/ECRRepository.md +1 -0
  74. package/dist/okf/types/Function.md +1 -0
  75. package/dist/okf/types/IamPolicy.md +1 -0
  76. package/dist/okf/types/InternetGateway.md +4 -0
  77. package/dist/okf/types/LaunchTemplate.md +1 -0
  78. package/dist/okf/types/LoadBalancer.md +1 -0
  79. package/dist/okf/types/ManagedPolicy.md +2 -0
  80. package/dist/okf/types/Map.md +5 -0
  81. package/dist/okf/types/NatGateway.md +4 -0
  82. package/dist/okf/types/Role.md +2 -0
  83. package/dist/okf/types/RouteTable.md +4 -0
  84. package/dist/okf/types/SecurityGroup.md +1 -0
  85. package/dist/okf/types/StateMachine.md +4 -0
  86. package/dist/okf/types/Subnet.md +6 -0
  87. package/dist/okf/types/SubnetRouteTableAssociation.md +5 -0
  88. package/dist/okf/types/Table.md +4 -0
  89. package/dist/okf/types/TransitGateway.md +6 -0
  90. package/dist/okf/types/TransitGatewayAttachment.md +4 -0
  91. package/dist/okf/types/TransitGatewayPeeringAttachment.md +4 -0
  92. package/dist/okf/types/TransitGatewayRoute.md +5 -0
  93. package/dist/okf/types/TransitGatewayRouteTable.md +4 -0
  94. package/dist/okf/types/TransitGatewayRouteTableAssociation.md +4 -0
  95. package/dist/okf/types/TransitGatewayRouteTablePropagation.md +4 -0
  96. package/dist/okf/types/TransitGatewayVpcAttachment.md +4 -0
  97. package/dist/okf/types/Type.md +8 -0
  98. package/dist/okf/types/VPNConnection.md +4 -0
  99. package/dist/okf/types/VPNGateway.md +4 -0
  100. package/dist/okf/types/Vpc.md +1 -0
  101. package/dist/op/activities/index.d.ts +6 -0
  102. package/dist/op/activities/index.d.ts.map +1 -1
  103. package/dist/op/builders.d.ts +47 -0
  104. package/dist/op/builders.d.ts.map +1 -0
  105. package/dist/plugin.d.ts.map +1 -1
  106. package/dist/receipt-store.d.ts +109 -0
  107. package/dist/receipt-store.d.ts.map +1 -0
  108. package/dist/rules/cf-refs.ts +40 -0
  109. package/dist/rules/waw016.ts +37 -16
  110. package/dist/rules/waw061.ts +67 -0
  111. package/dist/rules/waw062.ts +0 -0
  112. package/dist/rules/waw063.ts +0 -0
  113. package/dist/rules/waw064.ts +52 -0
  114. package/dist/rules/waw065.ts +110 -0
  115. package/dist/rules/waw066.ts +155 -0
  116. package/dist/rules/waw067.ts +114 -0
  117. package/dist/rules/waw068.ts +78 -0
  118. package/dist/serializer.d.ts.map +1 -1
  119. package/dist/skills/chant-aws-carve-terraform.md +26 -23
  120. package/dist/spec/parse.d.ts +7 -0
  121. package/dist/spec/parse.d.ts.map +1 -1
  122. package/package.json +3 -3
  123. package/src/api/read-client.test.ts +9 -0
  124. package/src/api/read-client.ts +15 -2
  125. package/src/codegen/fallback.ts +1 -0
  126. package/src/codegen/generate-lexicon.ts +6 -0
  127. package/src/codegen/sam.ts +9 -0
  128. package/src/components/host-delivery.ts +4 -3
  129. package/src/composites/agentcore-agent.ts +35 -13
  130. package/src/composites/bucket-deployment.test.ts +84 -0
  131. package/src/composites/bucket-deployment.ts +153 -0
  132. package/src/composites/composites.test.ts +325 -0
  133. package/src/composites/dynamodb-table.test.ts +154 -0
  134. package/src/composites/dynamodb-table.ts +124 -0
  135. package/src/composites/ec2-instance-bundle.ts +134 -0
  136. package/src/composites/ecr-repository.test.ts +118 -0
  137. package/src/composites/ecr-repository.ts +117 -0
  138. package/src/composites/fargate-service.ts +19 -3
  139. package/src/composites/index.ts +21 -2
  140. package/src/composites/monitoring-stack.test.ts +130 -0
  141. package/src/composites/monitoring-stack.ts +164 -0
  142. package/src/composites/nlb-service.ts +117 -0
  143. package/src/composites/step-functions-workflow.ts +127 -0
  144. package/src/deep-observe.test.ts +201 -1
  145. package/src/deep-observe.ts +204 -0
  146. package/src/deep-topology.test.ts +392 -0
  147. package/src/deep-topology.ts +237 -0
  148. package/src/effect-receipt-row.test.ts +164 -0
  149. package/src/effect-receipt-row.ts +147 -0
  150. package/src/generated/lexicon-aws.json +34 -0
  151. package/src/index.ts +36 -7
  152. package/src/lint/audit-catalog.ts +16 -0
  153. package/src/lint/post-synth/cf-refs.ts +40 -0
  154. package/src/lint/post-synth/index.ts +16 -0
  155. package/src/lint/post-synth/waw016.test.ts +61 -4
  156. package/src/lint/post-synth/waw016.ts +37 -16
  157. package/src/lint/post-synth/waw061.test.ts +99 -0
  158. package/src/lint/post-synth/waw061.ts +67 -0
  159. package/src/lint/post-synth/waw062.test.ts +109 -0
  160. package/src/lint/post-synth/waw062.ts +0 -0
  161. package/src/lint/post-synth/waw063.test.ts +220 -0
  162. package/src/lint/post-synth/waw063.ts +0 -0
  163. package/src/lint/post-synth/waw064.test.ts +79 -0
  164. package/src/lint/post-synth/waw064.ts +52 -0
  165. package/src/lint/post-synth/waw065.test.ts +90 -0
  166. package/src/lint/post-synth/waw065.ts +110 -0
  167. package/src/lint/post-synth/waw066.test.ts +108 -0
  168. package/src/lint/post-synth/waw066.ts +155 -0
  169. package/src/lint/post-synth/waw067.test.ts +79 -0
  170. package/src/lint/post-synth/waw067.ts +114 -0
  171. package/src/lint/post-synth/waw068.test.ts +74 -0
  172. package/src/lint/post-synth/waw068.ts +78 -0
  173. package/src/lsp/hover.ts +17 -2
  174. package/src/op/activities/index.ts +15 -0
  175. package/src/op/builders.test.ts +61 -0
  176. package/src/op/builders.ts +72 -0
  177. package/src/plugin.ts +41 -10
  178. package/src/receipt-store.test.ts +204 -0
  179. package/src/receipt-store.ts +315 -0
  180. package/src/serializer.ts +105 -2
  181. package/src/skills/chant-aws-carve-terraform.md +26 -23
  182. package/src/spec/parse.test.ts +74 -0
  183. package/src/spec/parse.ts +26 -6
@@ -0,0 +1,35 @@
1
+ /**
2
+ * WAW063: IAM Policy Denies An Action It Also Allows
3
+ *
4
+ * IAM evaluates an explicit Deny as an absolute veto: it wins over any
5
+ * Allow granted to the same principal, from any attached policy, no matter
6
+ * how the Allow got there. When a role ends up with both an Allow and a
7
+ * Deny for the same action (over an overlapping resource scope) —
8
+ * typically because a broad guardrail policy and a feature-specific policy
9
+ * were attached to the same role independently — CloudFormation deploys
10
+ * the stack without complaint and the contradiction only surfaces as a
11
+ * runtime 403, the most expensive class of error to trace back to its
12
+ * source. This is IAM-reasoning static analysis over the declared graph:
13
+ * collect every Allow/Deny statement attached to each declared IAM::Role
14
+ * (inline, standalone IAM::Policy, and IAM::ManagedPolicy) and flag a
15
+ * literal action+resource collision between an Allow and a Deny.
16
+ *
17
+ * Deliberately conservative to avoid flagging the common intentional
18
+ * "broad Allow + narrow safety-Deny" guardrail pattern (e.g. `Allow ec2:*`
19
+ * plus `Deny ec2:TerminateInstances`):
20
+ * - both statements' Action lists are compared string-by-string; a match
21
+ * requires either the literal same action on both sides, or a
22
+ * wildcarded Deny action that matches a literal (non-wildcarded) Allow
23
+ * action. A wildcarded Allow paired with a literal Deny is exactly the
24
+ * guardrail pattern and is never flagged;
25
+ * - resources are compared the same way: `Resource: "*"` on the Deny
26
+ * side always overlaps, or a literal exact match; a wildcarded Allow
27
+ * resource paired with a narrower literal Deny is not flagged;
28
+ * - any statement carrying a Condition, NotAction, NotResource,
29
+ * Principal, or an intrinsic Action/Resource is skipped — the rule
30
+ * can't prove those statically, so it stays quiet.
31
+ */
32
+ import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
33
+ export declare function checkDenyAllowContradiction(ctx: PostSynthContext): PostSynthDiagnostic[];
34
+ export declare const waw063: PostSynthCheck;
35
+ //# sourceMappingURL=waw063.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waw063.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/waw063.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAyG9G,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CA8CxF;AAED,eAAO,MAAM,MAAM,EAAE,cAOpB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * WAW064: Transit Gateway Route Table Declares A Blackhole Route
3
+ *
4
+ * `AWS::EC2::TransitGatewayRoute` with `Blackhole: true` silently drops any
5
+ * traffic matching its destination CIDR instead of forwarding it —
6
+ * CloudFormation deploys this without complaint, and the packet loss only
7
+ * surfaces downstream as unreachable hosts or a timeout nobody can explain
8
+ * from the template alone. A blackhole route is sometimes deliberate — an
9
+ * explicit deny for a CIDR range, or a placeholder pending real
10
+ * infrastructure — but it is also exactly what a copy-pasted route table or
11
+ * a forgotten cleanup step leaves behind. Warn so it stays a conscious
12
+ * choice rather than a silent accident.
13
+ */
14
+ import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
15
+ export declare function checkTgwBlackholeRoute(ctx: PostSynthContext): PostSynthDiagnostic[];
16
+ export declare const waw064: PostSynthCheck;
17
+ //# sourceMappingURL=waw064.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waw064.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/waw064.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAG9G,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CAyBnF;AAED,eAAO,MAAM,MAAM,EAAE,cAOpB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * WAW065: Transit Gateway Route Table Wiring Is Incomplete
3
+ *
4
+ * A Transit Gateway route table only does anything once two independent
5
+ * pieces are both wired up: an `AWS::EC2::TransitGatewayRouteTableAssociation`
6
+ * (which attachment's traffic is evaluated against this table) and an
7
+ * `AWS::EC2::TransitGatewayRouteTablePropagation` (which attachments' routes
8
+ * populate it). CloudFormation is happy to deploy a route table with one but
9
+ * not the other — the stack succeeds, and the gap only shows up as traffic
10
+ * that can't find a route. Two patterns, both "declared but half-wired":
11
+ *
12
+ * - a route table has one or more associations but zero propagations — the
13
+ * associated attachment's traffic is evaluated against this table, but
14
+ * nothing ever populates it with routes;
15
+ * - a declared attachment (VPC/VPN/peering, or the generic
16
+ * TransitGatewayAttachment) is referenced by neither an association nor
17
+ * a propagation anywhere in the template — it hangs off the transit
18
+ * gateway with no route table wiring at all.
19
+ */
20
+ import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
21
+ export declare function checkTgwRouteTableWiring(ctx: PostSynthContext): PostSynthDiagnostic[];
22
+ export declare const waw065: PostSynthCheck;
23
+ //# sourceMappingURL=waw065.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waw065.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/waw065.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAU9G,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CAsErF;AAED,eAAO,MAAM,MAAM,EAAE,cAOpB,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * WAW066: Private Subnet Route Table Has No Working Default Route
3
+ *
4
+ * Cross-resource join: a subnet's outbound path depends on a chain of three
5
+ * independently-declared resources — the `AWS::EC2::SubnetRouteTableAssociation`
6
+ * that pins it to a route table, the `AWS::EC2::Route` on that table for
7
+ * `0.0.0.0/0`, and the gateway that route names. CloudFormation validates
8
+ * none of this end-to-end: a subnet can be wired to a route table with no
9
+ * default route at all, or with a default route whose NAT gateway / Transit
10
+ * Gateway target was renamed or removed elsewhere in the template, and the
11
+ * stack still deploys clean. The subnet is black-holed — every deploy
12
+ * succeeds, and the only symptom is a workload with no outbound connectivity.
13
+ *
14
+ * A route table with a default route to an `AWS::EC2::InternetGateway` is
15
+ * treated as a public subnet and is out of scope for this check — this rule
16
+ * only flags the private case: no default route, or one whose target
17
+ * (`NatGatewayId` / `TransitGatewayId` / etc.) does not resolve to a
18
+ * resource declared in the same template. A route naming a target that
19
+ * exists in the template resolves cleanly and is never flagged, per the
20
+ * cross-resource contract.
21
+ */
22
+ import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
23
+ export declare function checkPrivateSubnetDefaultRoute(ctx: PostSynthContext): PostSynthDiagnostic[];
24
+ export declare const waw066: PostSynthCheck;
25
+ //# sourceMappingURL=waw066.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waw066.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/waw066.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAgD9G,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CA2E3F;AAED,eAAO,MAAM,MAAM,EAAE,cAOpB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * WAW067: Single-AZ NAT Gateway Serves Multi-AZ Private Subnets
3
+ *
4
+ * Cross-resource join across four resource kinds: a NAT gateway lives in one
5
+ * subnet, which lives in one Availability Zone; a route table's default
6
+ * route names the NAT gateway it forwards to; a subnet is pinned to a route
7
+ * table by an `AWS::EC2::SubnetRouteTableAssociation`. Follow that chain and
8
+ * a common reliability gap falls out — private subnets in two or more AZs
9
+ * all defaulting to the *same* NAT gateway. CloudFormation has no opinion on
10
+ * this; it deploys cleanly. But a NAT gateway lives entirely inside one AZ,
11
+ * so if that AZ has an outage, every subnet depending on it loses egress —
12
+ * including the subnets in AZs that were otherwise healthy. The
13
+ * Well-Architected fix is one NAT gateway per AZ, each serving only its own
14
+ * AZ's subnets.
15
+ *
16
+ * Only fires when the Availability Zones involved are literal strings —
17
+ * an `Fn::GetAZs`/`Fn::Select`-derived AZ can't be compared statically, so a
18
+ * subnet without a literal `AvailabilityZone` is silently excluded rather
19
+ * than guessed at.
20
+ */
21
+ import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
22
+ export declare function checkNatGatewaySingleAz(ctx: PostSynthContext): PostSynthDiagnostic[];
23
+ export declare const waw067: PostSynthCheck;
24
+ //# sourceMappingURL=waw067.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waw067.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/waw067.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAG9G,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CAgFpF;AAED,eAAO,MAAM,MAAM,EAAE,cAOpB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * WAW068: VPN Gateway Has A Single VPN Connection
3
+ *
4
+ * An `AWS::EC2::VPNConnection` always gets two tunnels from AWS, but that
5
+ * redundancy only covers the tunnel pair inside one connection — it does
6
+ * nothing if the connection's Customer Gateway, on-prem device, or the
7
+ * single site it terminates at goes down. The reliability boundary that
8
+ * matters is the connection itself: a `AWS::EC2::VPNGateway` (or a Transit
9
+ * Gateway used for VPN attachment) with only one `VPNConnection` attached
10
+ * has no fallback path for hybrid connectivity if that connection's
11
+ * Customer Gateway or on-prem side fails.
12
+ *
13
+ * Cross-resource join: group every declared `VPNConnection` by the gateway
14
+ * (`VpnGatewayId` or `TransitGatewayId`) it attaches to, and flag any
15
+ * gateway left with exactly one.
16
+ */
17
+ import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
18
+ export declare function checkVpnGatewayRedundancy(ctx: PostSynthContext): PostSynthDiagnostic[];
19
+ export declare const waw068: PostSynthCheck;
20
+ //# sourceMappingURL=waw068.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waw068.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/waw068.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAG9G,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CAgDtF;AAED,eAAO,MAAM,MAAM,EAAE,cAOpB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws",
3
- "version": "0.46.0",
3
+ "version": "0.50.0",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "AWS",
6
6
  "intrinsics": [
package/dist/meta.json CHANGED
@@ -6222,6 +6222,9 @@
6222
6222
  "deprecatedProperties": [
6223
6223
  "DeleteStorageConnectors"
6224
6224
  ],
6225
+ "inferredDeprecations": [
6226
+ "DeleteStorageConnectors"
6227
+ ],
6225
6228
  "tagging": {
6226
6229
  "taggable": true,
6227
6230
  "tagOnCreate": true,
@@ -11669,6 +11672,9 @@
11669
11672
  "deprecatedProperties": [
11670
11673
  "AccessControl"
11671
11674
  ],
11675
+ "inferredDeprecations": [
11676
+ "AccessControl"
11677
+ ],
11672
11678
  "tagging": {
11673
11679
  "taggable": true,
11674
11680
  "tagOnCreate": true,
@@ -14989,6 +14995,9 @@
14989
14995
  "deprecatedProperties": [
14990
14996
  "ComputeModel"
14991
14997
  ],
14998
+ "inferredDeprecations": [
14999
+ "ComputeModel"
15000
+ ],
14992
15001
  "replacementStrategy": "delete_then_create",
14993
15002
  "tagging": {
14994
15003
  "taggable": true,
@@ -15385,6 +15394,9 @@
15385
15394
  "deprecatedProperties": [
15386
15395
  "ComputeModel"
15387
15396
  ],
15397
+ "inferredDeprecations": [
15398
+ "ComputeModel"
15399
+ ],
15388
15400
  "conditionalCreateOnly": [
15389
15401
  "DbNodes"
15390
15402
  ],
@@ -17085,6 +17097,9 @@
17085
17097
  "deprecatedProperties": [
17086
17098
  "Deprecated"
17087
17099
  ],
17100
+ "inferredDeprecations": [
17101
+ "Deprecated"
17102
+ ],
17088
17103
  "tagging": {
17089
17104
  "taggable": true,
17090
17105
  "tagOnCreate": true,
@@ -29032,6 +29047,9 @@
29032
29047
  "TdeCredentialPassword",
29033
29048
  "DBSecurityGroups"
29034
29049
  ],
29050
+ "inferredDeprecations": [
29051
+ "DBSecurityGroups"
29052
+ ],
29035
29053
  "conditionalCreateOnly": [
29036
29054
  "AutoMinorVersionUpgrade",
29037
29055
  "AvailabilityZone",
@@ -33246,6 +33264,9 @@
33246
33264
  "deprecatedProperties": [
33247
33265
  "ImageScanningConfiguration"
33248
33266
  ],
33267
+ "inferredDeprecations": [
33268
+ "ImageScanningConfiguration"
33269
+ ],
33249
33270
  "tagging": {
33250
33271
  "taggable": true,
33251
33272
  "tagOnCreate": true,
@@ -41749,6 +41770,9 @@
41749
41770
  "deprecatedProperties": [
41750
41771
  "Runtime"
41751
41772
  ],
41773
+ "inferredDeprecations": [
41774
+ "Runtime"
41775
+ ],
41752
41776
  "conditionalCreateOnly": [
41753
41777
  "DurableConfig"
41754
41778
  ],
@@ -49621,6 +49645,10 @@
49621
49645
  "ElasticGpuSpecifications",
49622
49646
  "ElasticInferenceAccelerators"
49623
49647
  ],
49648
+ "inferredDeprecations": [
49649
+ "ElasticGpuSpecifications",
49650
+ "ElasticInferenceAccelerators"
49651
+ ],
49624
49652
  "conditionalCreateOnly": [
49625
49653
  "AdditionalInfo",
49626
49654
  "Affinity",
@@ -64878,6 +64906,9 @@
64878
64906
  "deprecatedProperties": [
64879
64907
  "DBPort"
64880
64908
  ],
64909
+ "inferredDeprecations": [
64910
+ "DBPort"
64911
+ ],
64881
64912
  "tagging": {
64882
64913
  "taggable": true,
64883
64914
  "tagOnCreate": true,
@@ -100101,6 +100132,9 @@
100101
100132
  "deprecatedProperties": [
100102
100133
  "State"
100103
100134
  ],
100135
+ "inferredDeprecations": [
100136
+ "State"
100137
+ ],
100104
100138
  "tagging": {
100105
100139
  "taggable": true,
100106
100140
  "tagOnCreate": true,
package/dist/okf/index.md CHANGED
@@ -1724,3 +1724,11 @@ okf_version: '0.2'
1724
1724
  * [WAW058](/rules/WAW058.md) - Organization audit trail missing, not logging, or scoped down to a single region
1725
1725
  * [WAW059](/rules/WAW059.md) - Wildcard Resource where the declared graph enumerates the touched set — tighten to the consumers' declared Arns
1726
1726
  * [WAW060](/rules/WAW060.md) - IAM policy attached to no principal — it grants nothing
1727
+ * [WAW061](/rules/WAW061.md) - Subnet CidrBlock falls outside its VPC's CidrBlock — fails at deploy time
1728
+ * [WAW062](/rules/WAW062.md) - Duplicate export name or explicit resource name within a template — fails at deploy time
1729
+ * [WAW063](/rules/WAW063.md) - IAM policy denies an action another attached policy on the same role allows — explicit Deny wins, runtime 403
1730
+ * [WAW064](/rules/WAW064.md) - Transit Gateway route table declares a Blackhole route — confirm the traffic drop is intentional, not an accident
1731
+ * [WAW065](/rules/WAW065.md) - Transit Gateway route table has associations but no propagations, or an attachment wired into no route table
1732
+ * [WAW066](/rules/WAW066.md) - Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
1733
+ * [WAW067](/rules/WAW067.md) - A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress
1734
+ * [WAW068](/rules/WAW068.md) - VPN Gateway or Transit Gateway has only one attached VPN Connection — no redundant path for hybrid connectivity
@@ -0,0 +1,17 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW061
4
+ description: Subnet CidrBlock falls outside its VPC's CidrBlock — fails at deploy time
5
+ id: WAW061
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ Subnet CidrBlock falls outside its VPC's CidrBlock — fails at deploy time
12
+
13
+ ## Applies to
14
+
15
+ - [Subnet](/types/Subnet.md)
16
+ - [Type](/types/Type.md)
17
+ - [Vpc](/types/Vpc.md)
@@ -0,0 +1,27 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW062
4
+ description: Duplicate export name or explicit resource name within a template — fails at deploy time
5
+ id: WAW062
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ Duplicate export name or explicit resource name within a template — fails at deploy time
12
+
13
+ ## Applies to
14
+
15
+ - [AutoScalingGroup](/types/AutoScalingGroup.md)
16
+ - [Bucket](/types/Bucket.md)
17
+ - [ECRRepository](/types/ECRRepository.md)
18
+ - [Function](/types/Function.md)
19
+ - [LaunchTemplate](/types/LaunchTemplate.md)
20
+ - [LoadBalancer](/types/LoadBalancer.md)
21
+ - [ManagedPolicy](/types/ManagedPolicy.md)
22
+ - [Map](/types/Map.md)
23
+ - [Role](/types/Role.md)
24
+ - [SecurityGroup](/types/SecurityGroup.md)
25
+ - [StateMachine](/types/StateMachine.md)
26
+ - [Table](/types/Table.md)
27
+ - [Type](/types/Type.md)
@@ -0,0 +1,19 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW063
4
+ description: IAM policy denies an action another attached policy on the same role allows — explicit Deny wins, runtime 403
5
+ id: WAW063
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ IAM policy denies an action another attached policy on the same role allows — explicit Deny wins, runtime 403
12
+
13
+ ## Applies to
14
+
15
+ - [Action](/types/Action.md)
16
+ - [IamPolicy](/types/IamPolicy.md)
17
+ - [ManagedPolicy](/types/ManagedPolicy.md)
18
+ - [Role](/types/Role.md)
19
+ - [Type](/types/Type.md)
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW064
4
+ description: Transit Gateway route table declares a Blackhole route — confirm the traffic drop is intentional, not an accident
5
+ id: WAW064
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ Transit Gateway route table declares a Blackhole route — confirm the traffic drop is intentional, not an accident
12
+
13
+ ## Applies to
14
+
15
+ - [Table](/types/Table.md)
16
+ - [TransitGateway](/types/TransitGateway.md)
17
+ - [TransitGatewayRoute](/types/TransitGatewayRoute.md)
18
+ - [Type](/types/Type.md)
@@ -0,0 +1,25 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW065
4
+ description: Transit Gateway route table has associations but no propagations, or an attachment wired into no route table
5
+ id: WAW065
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ Transit Gateway route table has associations but no propagations, or an attachment wired into no route table
12
+
13
+ ## Applies to
14
+
15
+ - [Map](/types/Map.md)
16
+ - [Table](/types/Table.md)
17
+ - [TransitGateway](/types/TransitGateway.md)
18
+ - [TransitGatewayAttachment](/types/TransitGatewayAttachment.md)
19
+ - [TransitGatewayPeeringAttachment](/types/TransitGatewayPeeringAttachment.md)
20
+ - [TransitGatewayRoute](/types/TransitGatewayRoute.md)
21
+ - [TransitGatewayRouteTable](/types/TransitGatewayRouteTable.md)
22
+ - [TransitGatewayRouteTableAssociation](/types/TransitGatewayRouteTableAssociation.md)
23
+ - [TransitGatewayRouteTablePropagation](/types/TransitGatewayRouteTablePropagation.md)
24
+ - [TransitGatewayVpcAttachment](/types/TransitGatewayVpcAttachment.md)
25
+ - [Type](/types/Type.md)
@@ -0,0 +1,22 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW066
4
+ description: Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
5
+ id: WAW066
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
12
+
13
+ ## Applies to
14
+
15
+ - [EC2Route](/types/EC2Route.md)
16
+ - [InternetGateway](/types/InternetGateway.md)
17
+ - [Map](/types/Map.md)
18
+ - [RouteTable](/types/RouteTable.md)
19
+ - [Subnet](/types/Subnet.md)
20
+ - [SubnetRouteTableAssociation](/types/SubnetRouteTableAssociation.md)
21
+ - [Table](/types/Table.md)
22
+ - [Type](/types/Type.md)
@@ -0,0 +1,20 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW067
4
+ description: A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress
5
+ id: WAW067
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress
12
+
13
+ ## Applies to
14
+
15
+ - [EC2Route](/types/EC2Route.md)
16
+ - [Map](/types/Map.md)
17
+ - [NatGateway](/types/NatGateway.md)
18
+ - [Subnet](/types/Subnet.md)
19
+ - [SubnetRouteTableAssociation](/types/SubnetRouteTableAssociation.md)
20
+ - [Type](/types/Type.md)
@@ -0,0 +1,19 @@
1
+ ---
2
+ type: post-synth-check
3
+ title: WAW068
4
+ description: VPN Gateway or Transit Gateway has only one attached VPN Connection — no redundant path for hybrid connectivity
5
+ id: WAW068
6
+ severity: error
7
+ category: post-synth
8
+ lexicon: aws
9
+ docs: https://intentius.io/chant/lexicons/aws/rules/
10
+ ---
11
+ VPN Gateway or Transit Gateway has only one attached VPN Connection — no redundant path for hybrid connectivity
12
+
13
+ ## Applies to
14
+
15
+ - [Map](/types/Map.md)
16
+ - [TransitGateway](/types/TransitGateway.md)
17
+ - [Type](/types/Type.md)
18
+ - [VPNConnection](/types/VPNConnection.md)
19
+ - [VPNGateway](/types/VPNGateway.md)
@@ -32,3 +32,4 @@ resource_type: AWS::SageMaker::Action
32
32
 
33
33
  - [WAW020](/rules/WAW020.md): IAM policy uses wildcard Action — use specific actions following least privilege
34
34
  - [WAW059](/rules/WAW059.md): Wildcard Resource where the declared graph enumerates the touched set — tighten to the consumers' declared Arns
35
+ - [WAW063](/rules/WAW063.md): IAM policy denies an action another attached policy on the same role allows — explicit Deny wins, runtime 403
@@ -57,3 +57,4 @@ resource_type: AWS::AutoScaling::AutoScalingGroup
57
57
  ## Governed by
58
58
 
59
59
  - [WAW036](/rules/WAW036.md): Non-ASCII characters in EC2/IAM/CW string properties — rejected at changeset time
60
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -64,3 +64,4 @@ resource_type: AWS::S3::Bucket
64
64
  - [WAW018](/rules/WAW018.md): S3 bucket missing public access block — all public access should be blocked
65
65
  - [WAW042](/rules/WAW042.md): S3 bucket missing a TLS-only bucket policy — deny requests over plaintext
66
66
  - [WAW059](/rules/WAW059.md): Wildcard Resource where the declared graph enumerates the touched set — tighten to the consumers' declared Arns
67
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -35,3 +35,5 @@ resource_type: AWS::EC2::Route
35
35
  ## Governed by
36
36
 
37
37
  - [WAW030](/rules/WAW030.md): Missing DependsOn for known CloudFormation ordering patterns
38
+ - [WAW066](/rules/WAW066.md): Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
39
+ - [WAW067](/rules/WAW067.md): A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress
@@ -31,3 +31,4 @@ resource_type: AWS::ECR::Repository
31
31
 
32
32
  - [WAW053](/rules/WAW053.md): ECR repository does not scan images on push
33
33
  - [WAW054](/rules/WAW054.md): ECR repository does not have immutable image tags
34
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -56,3 +56,4 @@ resource_type: AWS::Lambda::Function
56
56
  - [WAW011](/rules/WAW011.md): Deprecated Lambda runtime — flags deprecated or approaching-EOL Lambda runtimes
57
57
  - [WAW022](/rules/WAW022.md): Lambda function is not configured with a VPC — consider adding VpcConfig for network isolation
58
58
  - [WAW036](/rules/WAW036.md): Non-ASCII characters in EC2/IAM/CW string properties — rejected at changeset time
59
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -26,3 +26,4 @@ resource_type: AWS::IAM::Policy
26
26
  - [WAW020](/rules/WAW020.md): IAM policy uses wildcard Action — use specific actions following least privilege
27
27
  - [WAW059](/rules/WAW059.md): Wildcard Resource where the declared graph enumerates the touched set — tighten to the consumers' declared Arns
28
28
  - [WAW060](/rules/WAW060.md): IAM policy attached to no principal — it grants nothing
29
+ - [WAW063](/rules/WAW063.md): IAM policy denies an action another attached policy on the same role allows — explicit Deny wins, runtime 403
@@ -16,3 +16,7 @@ resource_type: AWS::EC2::InternetGateway
16
16
  ## Attributes
17
17
 
18
18
  - `InternetGatewayId`
19
+
20
+ ## Governed by
21
+
22
+ - [WAW066](/rules/WAW066.md): Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
@@ -27,3 +27,4 @@ resource_type: AWS::EC2::LaunchTemplate
27
27
  ## Governed by
28
28
 
29
29
  - [WAW036](/rules/WAW036.md): Non-ASCII characters in EC2/IAM/CW string properties — rejected at changeset time
30
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -41,3 +41,4 @@ resource_type: AWS::ElasticLoadBalancingV2::LoadBalancer
41
41
  ## Governed by
42
42
 
43
43
  - [WAW024](/rules/WAW024.md): Application Load Balancer does not have access logging enabled
44
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -42,3 +42,5 @@ resource_type: AWS::IAM::ManagedPolicy
42
42
  - [WAW020](/rules/WAW020.md): IAM policy uses wildcard Action — use specific actions following least privilege
43
43
  - [WAW059](/rules/WAW059.md): Wildcard Resource where the declared graph enumerates the touched set — tighten to the consumers' declared Arns
44
44
  - [WAW060](/rules/WAW060.md): IAM policy attached to no principal — it grants nothing
45
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
46
+ - [WAW063](/rules/WAW063.md): IAM policy denies an action another attached policy on the same role allows — explicit Deny wins, runtime 403
@@ -35,3 +35,8 @@ resource_type: AWS::Location::Map
35
35
  - [WAW016](/rules/WAW016.md): Deprecated property usage — flags properties marked as deprecated in the CloudFormation Registry
36
36
  - [WAW036](/rules/WAW036.md): Non-ASCII characters in EC2/IAM/CW string properties — rejected at changeset time
37
37
  - [WAW059](/rules/WAW059.md): Wildcard Resource where the declared graph enumerates the touched set — tighten to the consumers' declared Arns
38
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
39
+ - [WAW065](/rules/WAW065.md): Transit Gateway route table has associations but no propagations, or an attachment wired into no route table
40
+ - [WAW066](/rules/WAW066.md): Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
41
+ - [WAW067](/rules/WAW067.md): A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress
42
+ - [WAW068](/rules/WAW068.md): VPN Gateway or Transit Gateway has only one attached VPN Connection — no redundant path for hybrid connectivity
@@ -35,3 +35,7 @@ resource_type: AWS::EC2::NatGateway
35
35
  - `EniId`
36
36
  - `NatGatewayId`
37
37
  - `RouteTableId`
38
+
39
+ ## Governed by
40
+
41
+ - [WAW067](/rules/WAW067.md): A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress
@@ -32,3 +32,5 @@ resource_type: AWS::IAM::Role
32
32
  - [WAW020](/rules/WAW020.md): IAM policy uses wildcard Action — use specific actions following least privilege
33
33
  - [WAW036](/rules/WAW036.md): Non-ASCII characters in EC2/IAM/CW string properties — rejected at changeset time
34
34
  - [WAW059](/rules/WAW059.md): Wildcard Resource where the declared graph enumerates the touched set — tighten to the consumers' declared Arns
35
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
36
+ - [WAW063](/rules/WAW063.md): IAM policy denies an action another attached policy on the same role allows — explicit Deny wins, runtime 403
@@ -17,3 +17,7 @@ resource_type: AWS::EC2::RouteTable
17
17
  ## Attributes
18
18
 
19
19
  - `RouteTableId`
20
+
21
+ ## Governed by
22
+
23
+ - [WAW066](/rules/WAW066.md): Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
@@ -29,3 +29,4 @@ resource_type: AWS::EC2::SecurityGroup
29
29
  - [WAW019](/rules/WAW019.md): Security group allows unrestricted ingress on sensitive ports (SSH, RDP, database)
30
30
  - [WAW036](/rules/WAW036.md): Non-ASCII characters in EC2/IAM/CW string properties — rejected at changeset time
31
31
  - [WAW049](/rules/WAW049.md): Security group allows unrestricted ingress on a port other than ALB:80/443
32
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -30,3 +30,7 @@ resource_type: AWS::StepFunctions::StateMachine
30
30
  - `Arn`
31
31
  - `Name`
32
32
  - `StateMachineRevisionId`
33
+
34
+ ## Governed by
35
+
36
+ - [WAW062](/rules/WAW062.md): Duplicate export name or explicit resource name within a template — fails at deploy time
@@ -38,3 +38,9 @@ resource_type: AWS::EC2::Subnet
38
38
  - `Ipv6CidrBlocks`
39
39
  - `NetworkAclAssociationId`
40
40
  - `SubnetId`
41
+
42
+ ## Governed by
43
+
44
+ - [WAW061](/rules/WAW061.md): Subnet CidrBlock falls outside its VPC's CidrBlock — fails at deploy time
45
+ - [WAW066](/rules/WAW066.md): Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
46
+ - [WAW067](/rules/WAW067.md): A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress
@@ -17,3 +17,8 @@ resource_type: AWS::EC2::SubnetRouteTableAssociation
17
17
  ## Attributes
18
18
 
19
19
  - `Id`
20
+
21
+ ## Governed by
22
+
23
+ - [WAW066](/rules/WAW066.md): Private subnet's route table has no default route, or its default route targets a gateway that does not exist in the template
24
+ - [WAW067](/rules/WAW067.md): A single-AZ NAT gateway serves private subnets across multiple Availability Zones — single point of failure for cross-AZ egress