@aws/nx-plugin 1.0.0-rc.4 → 1.0.0-rc.41

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 (1138) hide show
  1. package/LICENSE-THIRD-PARTY +5449 -4980
  2. package/README.md +7 -7
  3. package/executors.json +9 -0
  4. package/generators.json +101 -2
  5. package/package.json +35 -17
  6. package/src/agentcore-gateway/attach-upstream.d.ts +33 -0
  7. package/src/agentcore-gateway/attach-upstream.js +38 -0
  8. package/src/agentcore-gateway/attach-upstream.js.map +1 -0
  9. package/src/agentcore-gateway/files/cedar/policies/README.md +52 -0
  10. package/src/agentcore-gateway/files/cedar/policies/permit-all.cedar +11 -0
  11. package/src/agentcore-gateway/files/project/local-dev.ts.template +134 -0
  12. package/src/agentcore-gateway/gateway-connection/generator.d.ts +21 -0
  13. package/src/agentcore-gateway/gateway-connection/generator.js +101 -0
  14. package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -0
  15. package/src/agentcore-gateway/gateway-connection/schema.d.js +6 -0
  16. package/src/agentcore-gateway/gateway-connection/schema.d.js.map +1 -0
  17. package/src/agentcore-gateway/gateway-connection/schema.d.ts +13 -0
  18. package/src/agentcore-gateway/gateway-connection/schema.json +31 -0
  19. package/src/agentcore-gateway/generator.d.ts +25 -0
  20. package/src/agentcore-gateway/generator.js +149 -0
  21. package/src/agentcore-gateway/generator.js.map +1 -0
  22. package/src/agentcore-gateway/mcp-connection/generator.d.ts +19 -0
  23. package/src/agentcore-gateway/mcp-connection/generator.js +59 -0
  24. package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -0
  25. package/src/agentcore-gateway/mcp-connection/schema.d.js +6 -0
  26. package/src/agentcore-gateway/mcp-connection/schema.d.js.map +1 -0
  27. package/src/agentcore-gateway/mcp-connection/schema.d.ts +13 -0
  28. package/src/agentcore-gateway/mcp-connection/schema.json +31 -0
  29. package/src/agentcore-gateway/schema.d.js +6 -0
  30. package/src/agentcore-gateway/schema.d.js.map +1 -0
  31. package/src/agentcore-gateway/schema.d.ts +17 -0
  32. package/src/agentcore-gateway/schema.json +70 -0
  33. package/src/bin/aws-nx-mcp.js +14 -0
  34. package/src/bin/aws-nx-mcp.js.map +1 -0
  35. package/src/connection/{agent-serve-local.d.ts → agent-local-dev.d.ts} +7 -7
  36. package/src/connection/agent-local-dev.js +42 -0
  37. package/src/connection/agent-local-dev.js.map +1 -0
  38. package/src/connection/agent-runtime-config.d.ts +1 -1
  39. package/src/connection/agent-runtime-config.js +9 -14
  40. package/src/connection/agent-runtime-config.js.map +1 -1
  41. package/src/connection/generator.d.ts +7 -14
  42. package/src/connection/generator.js +167 -194
  43. package/src/connection/generator.js.map +1 -1
  44. package/src/connection/local-dev.d.ts +15 -0
  45. package/src/connection/local-dev.js +37 -0
  46. package/src/connection/local-dev.js.map +1 -0
  47. package/src/connection/schema.d.js +6 -0
  48. package/src/connection/schema.d.js.map +1 -0
  49. package/src/connection/schema.d.ts +1 -0
  50. package/src/connection/schema.json +5 -0
  51. package/src/connection/supported-connections.d.ts +107 -0
  52. package/src/connection/supported-connections.js +151 -0
  53. package/src/connection/supported-connections.js.map +1 -0
  54. package/src/index.js +2 -5
  55. package/src/index.js.map +1 -1
  56. package/src/infra/app/__snapshots__/generator.spec.ts.snap +97 -85
  57. package/src/infra/app/files/app/src/main.ts.template +1 -1
  58. package/src/infra/app/files/app/src/stages/application-stage.ts.template +1 -1
  59. package/src/infra/app/generator.d.ts +3 -3
  60. package/src/infra/app/generator.js +142 -122
  61. package/src/infra/app/generator.js.map +1 -1
  62. package/src/infra/app/schema.d.js +6 -0
  63. package/src/infra/app/schema.d.js.map +1 -0
  64. package/src/infra/app/schema.d.ts +1 -1
  65. package/src/infra/app/schema.json +5 -0
  66. package/src/init/generator.d.ts +18 -0
  67. package/src/init/generator.js +35 -0
  68. package/src/init/generator.js.map +1 -0
  69. package/src/init/schema.d.js +6 -0
  70. package/src/init/schema.d.js.map +1 -0
  71. package/src/init/schema.d.ts +16 -0
  72. package/src/init/schema.json +35 -0
  73. package/src/license/__snapshots__/config.spec.ts.snap +23 -0
  74. package/src/license/config-types.d.ts +18 -1
  75. package/src/license/config-types.js +8 -2
  76. package/src/license/config-types.js.map +1 -1
  77. package/src/license/config.d.ts +65 -7
  78. package/src/license/config.js +442 -109
  79. package/src/license/config.js.map +1 -1
  80. package/src/license/dependency-check/check.d.ts +16 -0
  81. package/src/license/dependency-check/check.js +116 -0
  82. package/src/license/dependency-check/check.js.map +1 -0
  83. package/src/license/dependency-check/collectors/collector.d.ts +21 -0
  84. package/src/license/dependency-check/collectors/collector.js +46 -0
  85. package/src/license/dependency-check/collectors/collector.js.map +1 -0
  86. package/src/license/dependency-check/collectors/npm-collector.d.ts +10 -0
  87. package/src/license/dependency-check/collectors/npm-collector.js +68 -0
  88. package/src/license/dependency-check/collectors/npm-collector.js.map +1 -0
  89. package/src/license/dependency-check/collectors/python-collector.d.ts +23 -0
  90. package/src/license/dependency-check/collectors/python-collector.js +114 -0
  91. package/src/license/dependency-check/collectors/python-collector.js.map +1 -0
  92. package/src/license/dependency-check/evaluator.d.ts +9 -0
  93. package/src/license/dependency-check/evaluator.js +94 -0
  94. package/src/license/dependency-check/evaluator.js.map +1 -0
  95. package/src/license/dependency-check/executor-schema.json +6 -0
  96. package/src/license/dependency-check/executor.d.ts +9 -0
  97. package/src/license/dependency-check/executor.js +51 -0
  98. package/src/license/dependency-check/executor.js.map +1 -0
  99. package/src/license/dependency-check/pre-approved.d.ts +6 -0
  100. package/src/license/dependency-check/pre-approved.js +1893 -0
  101. package/src/license/dependency-check/pre-approved.js.map +1 -0
  102. package/src/license/dependency-check/types.d.ts +45 -0
  103. package/src/license/dependency-check/types.js +6 -0
  104. package/src/license/dependency-check/types.js.map +1 -0
  105. package/src/license/generator.d.ts +3 -3
  106. package/src/license/generator.js +126 -30
  107. package/src/license/generator.js.map +1 -1
  108. package/src/license/index.d.ts +8 -0
  109. package/src/license/index.js +7 -0
  110. package/src/license/index.js.map +1 -0
  111. package/src/license/known-exceptions.d.ts +7 -0
  112. package/src/license/known-exceptions.js +39 -0
  113. package/src/license/known-exceptions.js.map +1 -0
  114. package/src/license/schema.d.js +6 -0
  115. package/src/license/schema.d.js.map +1 -0
  116. package/src/license/schema.d.ts +7 -0
  117. package/src/license/schema.json +11 -0
  118. package/src/license/sync/generator.d.ts +2 -2
  119. package/src/license/sync/generator.js +100 -125
  120. package/src/license/sync/generator.js.map +1 -1
  121. package/src/license/sync/project-file-sync.d.ts +3 -3
  122. package/src/license/sync/project-file-sync.js +28 -35
  123. package/src/license/sync/project-file-sync.js.map +1 -1
  124. package/src/mcp-server/generator-info.d.ts +5 -1
  125. package/src/mcp-server/generator-info.js +149 -165
  126. package/src/mcp-server/generator-info.js.map +1 -1
  127. package/src/mcp-server/guide-pipeline.d.ts +1 -1
  128. package/src/mcp-server/guide-pipeline.js +199 -206
  129. package/src/mcp-server/guide-pipeline.js.map +1 -1
  130. package/src/mcp-server/guide-render.js +10 -25
  131. package/src/mcp-server/guide-render.js.map +1 -1
  132. package/src/mcp-server/index.js +6 -10
  133. package/src/mcp-server/index.js.map +1 -1
  134. package/src/mcp-server/mdx-ast.js +42 -56
  135. package/src/mcp-server/mdx-ast.js.map +1 -1
  136. package/src/mcp-server/option-filter.js +33 -47
  137. package/src/mcp-server/option-filter.js.map +1 -1
  138. package/src/mcp-server/schema-registry.d.ts +9 -3
  139. package/src/mcp-server/schema-registry.js +41 -38
  140. package/src/mcp-server/schema-registry.js.map +1 -1
  141. package/src/mcp-server/schema.js +9 -7
  142. package/src/mcp-server/schema.js.map +1 -1
  143. package/src/mcp-server/server.js +22 -24
  144. package/src/mcp-server/server.js.map +1 -1
  145. package/src/mcp-server/tools/add-to-existing-project.d.ts +12 -0
  146. package/src/mcp-server/tools/add-to-existing-project.js +36 -0
  147. package/src/mcp-server/tools/add-to-existing-project.js.map +1 -0
  148. package/src/mcp-server/tools/create-workspace-command.d.ts +1 -1
  149. package/src/mcp-server/tools/create-workspace-command.js +23 -24
  150. package/src/mcp-server/tools/create-workspace-command.js.map +1 -1
  151. package/src/mcp-server/tools/general-guidance.d.ts +3 -3
  152. package/src/mcp-server/tools/general-guidance.js +47 -25
  153. package/src/mcp-server/tools/general-guidance.js.map +1 -1
  154. package/src/mcp-server/tools/generator-guide.d.ts +2 -2
  155. package/src/mcp-server/tools/generator-guide.js +29 -37
  156. package/src/mcp-server/tools/generator-guide.js.map +1 -1
  157. package/src/mcp-server/tools/list-generators.d.ts +2 -2
  158. package/src/mcp-server/tools/list-generators.js +19 -25
  159. package/src/mcp-server/tools/list-generators.js.map +1 -1
  160. package/src/open-api/ts-client/__snapshots__/generator.additional-properties.spec.ts.snap +147 -33
  161. package/src/open-api/ts-client/__snapshots__/generator.arrays.spec.ts.snap +308 -75
  162. package/src/open-api/ts-client/__snapshots__/generator.complex-types.spec.ts.snap +298 -74
  163. package/src/open-api/ts-client/__snapshots__/generator.composite-types.spec.ts.snap +748 -103
  164. package/src/open-api/ts-client/__snapshots__/generator.content-type.spec.ts.snap +230 -37
  165. package/src/open-api/ts-client/__snapshots__/generator.duplicate-types.spec.ts.snap +249 -52
  166. package/src/open-api/ts-client/__snapshots__/generator.edge-cases.spec.ts.snap +5535 -0
  167. package/src/open-api/ts-client/__snapshots__/generator.fast-api-gaps.spec.ts.snap +736 -0
  168. package/src/open-api/ts-client/__snapshots__/generator.fast-api.spec.ts.snap +305 -71
  169. package/src/open-api/ts-client/__snapshots__/generator.multipart.spec.ts.snap +298 -0
  170. package/src/open-api/ts-client/__snapshots__/generator.primitive-types.spec.ts.snap +353 -82
  171. package/src/open-api/ts-client/__snapshots__/generator.request.spec.ts.snap +176 -55
  172. package/src/open-api/ts-client/__snapshots__/generator.reserved-keywords.spec.ts.snap +101 -25
  173. package/src/open-api/ts-client/__snapshots__/generator.response.spec.ts.snap +147 -33
  174. package/src/open-api/ts-client/__snapshots__/generator.spec-compliance.spec.ts.snap +1883 -0
  175. package/src/open-api/ts-client/__snapshots__/generator.streaming.spec.ts.snap +392 -88
  176. package/src/open-api/ts-client/__snapshots__/generator.tags.spec.ts.snap +200 -48
  177. package/src/open-api/ts-client/files/client.gen.ts.template +358 -24
  178. package/src/open-api/ts-client/files/types.gen.ts.template +6 -4
  179. package/src/open-api/ts-client/generator.d.ts +3 -3
  180. package/src/open-api/ts-client/generator.js +41 -26
  181. package/src/open-api/ts-client/generator.js.map +1 -1
  182. package/src/open-api/ts-client/schema.d.js +6 -0
  183. package/src/open-api/ts-client/schema.d.js.map +1 -0
  184. package/src/open-api/ts-hooks/files/options-proxy.gen.ts.template +7 -2
  185. package/src/open-api/ts-hooks/generator.d.ts +3 -3
  186. package/src/open-api/ts-hooks/generator.js +17 -21
  187. package/src/open-api/ts-hooks/generator.js.map +1 -1
  188. package/src/open-api/ts-hooks/generator.spec.tsx +84 -14
  189. package/src/open-api/ts-hooks/schema.d.js +6 -0
  190. package/src/open-api/ts-hooks/schema.d.js.map +1 -0
  191. package/src/open-api/ts-metadata/generator.d.ts +3 -3
  192. package/src/open-api/ts-metadata/generator.js +12 -20
  193. package/src/open-api/ts-metadata/generator.js.map +1 -1
  194. package/src/open-api/ts-metadata/schema.d.js +6 -0
  195. package/src/open-api/ts-metadata/schema.d.js.map +1 -0
  196. package/src/open-api/utils/codegen-data/languages.d.ts +3 -5
  197. package/src/open-api/utils/codegen-data/languages.js +59 -66
  198. package/src/open-api/utils/codegen-data/languages.js.map +1 -1
  199. package/src/open-api/utils/codegen-data/types.d.ts +255 -10
  200. package/src/open-api/utils/codegen-data/types.js +54 -30
  201. package/src/open-api/utils/codegen-data/types.js.map +1 -1
  202. package/src/open-api/utils/codegen-data.d.ts +8 -4
  203. package/src/open-api/utils/codegen-data.js +494 -674
  204. package/src/open-api/utils/codegen-data.js.map +1 -1
  205. package/src/open-api/utils/normalise.d.ts +5 -1
  206. package/src/open-api/utils/normalise.js +437 -246
  207. package/src/open-api/utils/normalise.js.map +1 -1
  208. package/src/open-api/utils/parse.d.ts +2 -2
  209. package/src/open-api/utils/parse.js +11 -13
  210. package/src/open-api/utils/parse.js.map +1 -1
  211. package/src/open-api/utils/parser.d.ts +55 -0
  212. package/src/open-api/utils/parser.js +787 -0
  213. package/src/open-api/utils/parser.js.map +1 -0
  214. package/src/open-api/utils/refs.d.ts +1 -1
  215. package/src/open-api/utils/refs.js +12 -22
  216. package/src/open-api/utils/refs.js.map +1 -1
  217. package/src/open-api/utils/types.d.ts +18 -0
  218. package/src/open-api/utils/types.js +5 -2
  219. package/src/open-api/utils/types.js.map +1 -1
  220. package/src/preset/__snapshots__/generator.spec.ts.snap +109 -28
  221. package/src/preset/generator.d.ts +4 -4
  222. package/src/preset/generator.js +64 -147
  223. package/src/preset/generator.js.map +1 -1
  224. package/src/preset/schema.d.js +6 -0
  225. package/src/preset/schema.d.js.map +1 -0
  226. package/src/preset/schema.d.ts +5 -2
  227. package/src/preset/schema.json +11 -5
  228. package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +320 -0
  229. package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +734 -0
  230. package/src/py/agent/__snapshots__/{generator.spec.ts.snap → generator.protocols.spec.ts.snap} +182 -314
  231. package/src/py/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +189 -0
  232. package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client_strands.py.template +30 -0
  233. package/src/py/agent/a2a-connection/files/langchain/agent-connection/app/__targetAgentSnakeCase___client_langchain.py.template +28 -0
  234. package/src/py/agent/a2a-connection/generator.d.ts +3 -3
  235. package/src/py/agent/a2a-connection/generator.js +113 -85
  236. package/src/py/agent/a2a-connection/generator.js.map +1 -1
  237. package/src/py/agent/a2a-connection/schema.d.js +8 -0
  238. package/src/py/agent/a2a-connection/schema.d.js.map +1 -0
  239. package/src/py/agent/a2a-connection/schema.d.ts +1 -0
  240. package/src/py/agent/a2a-connection/schema.json +5 -0
  241. package/src/py/agent/files/a2a-langchain/main.py.template +89 -0
  242. package/src/py/agent/files/ag-ui-langchain/main.py.template +83 -0
  243. package/src/py/agent/files/common/agent.py.template +2 -0
  244. package/src/py/agent/files/common-langchain/agent.py.template +30 -0
  245. package/src/py/agent/files/deploy/Dockerfile.template +1 -1
  246. package/src/py/agent/files/http/init.py.template +7 -25
  247. package/src/py/agent/files/http/main.py.template +3 -4
  248. package/src/py/agent/files/http-langchain/main.py.template +84 -0
  249. package/src/py/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +184 -0
  250. package/src/py/agent/gateway-connection/files/agent-connection/app/__gatewaySnakeCase___client_strands.py.template +35 -0
  251. package/src/py/agent/gateway-connection/files/langchain/agent-connection/app/__gatewaySnakeCase___client_langchain.py.template +34 -0
  252. package/src/py/agent/gateway-connection/generator.d.ts +10 -0
  253. package/src/py/agent/gateway-connection/generator.js +119 -0
  254. package/src/py/agent/gateway-connection/generator.js.map +1 -0
  255. package/src/py/agent/gateway-connection/schema.d.js +6 -0
  256. package/src/py/agent/gateway-connection/schema.d.js.map +1 -0
  257. package/src/py/agent/gateway-connection/schema.d.ts +13 -0
  258. package/src/py/agent/gateway-connection/schema.json +31 -0
  259. package/src/py/agent/generator.d.ts +3 -3
  260. package/src/py/agent/generator.js +290 -179
  261. package/src/py/agent/generator.js.map +1 -1
  262. package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +153 -89
  263. package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client_strands.py.template +30 -0
  264. package/src/py/agent/mcp-connection/files/langchain/agent-connection/app/__mcpServerSnakeCase___client_langchain.py.template +30 -0
  265. package/src/py/agent/mcp-connection/generator.d.ts +3 -3
  266. package/src/py/agent/mcp-connection/generator.js +65 -126
  267. package/src/py/agent/mcp-connection/generator.js.map +1 -1
  268. package/src/py/agent/mcp-connection/schema.d.js +8 -0
  269. package/src/py/agent/mcp-connection/schema.d.js.map +1 -0
  270. package/src/py/agent/mcp-connection/schema.d.ts +1 -0
  271. package/src/py/agent/mcp-connection/schema.json +5 -0
  272. package/src/py/agent/react-connection/__snapshots__/generator.spec.ts.snap +11 -19
  273. package/src/py/agent/react-connection/generator.d.ts +4 -4
  274. package/src/py/agent/react-connection/generator.js +55 -59
  275. package/src/py/agent/react-connection/generator.js.map +1 -1
  276. package/src/py/agent/react-connection/{serve-local.d.ts → local-dev.d.ts} +6 -6
  277. package/src/py/agent/react-connection/local-dev.js +36 -0
  278. package/src/py/agent/react-connection/local-dev.js.map +1 -0
  279. package/src/py/agent/react-connection/schema.d.js +8 -0
  280. package/src/py/agent/react-connection/schema.d.js.map +1 -0
  281. package/src/py/agent/react-connection/schema.d.ts +1 -0
  282. package/src/py/agent/react-connection/schema.json +5 -0
  283. package/src/py/agent/schema.d.js +6 -0
  284. package/src/py/agent/schema.d.js.map +1 -0
  285. package/src/py/agent/schema.d.ts +2 -1
  286. package/src/py/agent/schema.json +6 -1
  287. package/src/py/api/generator.d.ts +3 -3
  288. package/src/py/api/generator.js +12 -11
  289. package/src/py/api/generator.js.map +1 -1
  290. package/src/py/api/schema.d.js +6 -0
  291. package/src/py/api/schema.d.js.map +1 -0
  292. package/src/py/api/schema.d.ts +1 -0
  293. package/src/py/api/schema.json +5 -0
  294. package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +1526 -0
  295. package/src/py/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +45 -0
  296. package/src/py/dynamodb/agent-connection/generator.d.ts +10 -0
  297. package/src/py/dynamodb/agent-connection/generator.js +39 -0
  298. package/src/py/dynamodb/agent-connection/generator.js.map +1 -0
  299. package/src/py/dynamodb/agent-connection/schema.d.js +8 -0
  300. package/src/py/dynamodb/agent-connection/schema.d.js.map +1 -0
  301. package/src/py/dynamodb/agent-connection/schema.d.ts +15 -0
  302. package/src/py/dynamodb/agent-connection/schema.json +27 -0
  303. package/src/py/dynamodb/fast-api-connection/__snapshots__/generator.spec.ts.snap +23 -0
  304. package/src/py/dynamodb/fast-api-connection/generator.d.ts +10 -0
  305. package/src/py/dynamodb/fast-api-connection/generator.js +37 -0
  306. package/src/py/dynamodb/fast-api-connection/generator.js.map +1 -0
  307. package/src/py/dynamodb/fast-api-connection/schema.d.js +8 -0
  308. package/src/py/dynamodb/fast-api-connection/schema.d.js.map +1 -0
  309. package/src/py/dynamodb/fast-api-connection/schema.d.ts +13 -0
  310. package/src/py/dynamodb/fast-api-connection/schema.json +23 -0
  311. package/src/py/dynamodb/files/__name__/__init__.py.template +6 -0
  312. package/src/py/dynamodb/files/__name__/client.py.template +39 -0
  313. package/src/py/dynamodb/files/__name__/entities/__init__.py.template +4 -0
  314. package/src/py/dynamodb/files/__name__/entities/base.py.template +63 -0
  315. package/src/py/dynamodb/files/__name__/entities/example.py.template +64 -0
  316. package/src/py/dynamodb/files/config.json.template +24 -0
  317. package/src/py/dynamodb/generator.d.ts +10 -0
  318. package/src/py/dynamodb/generator.js +110 -0
  319. package/src/py/dynamodb/generator.js.map +1 -0
  320. package/src/py/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +45 -0
  321. package/src/py/dynamodb/mcp-server-connection/generator.d.ts +10 -0
  322. package/src/py/dynamodb/mcp-server-connection/generator.js +39 -0
  323. package/src/py/dynamodb/mcp-server-connection/generator.js.map +1 -0
  324. package/src/py/dynamodb/mcp-server-connection/schema.d.js +8 -0
  325. package/src/py/dynamodb/mcp-server-connection/schema.d.js.map +1 -0
  326. package/src/py/dynamodb/mcp-server-connection/schema.d.ts +15 -0
  327. package/src/py/dynamodb/mcp-server-connection/schema.json +27 -0
  328. package/src/py/dynamodb/schema.d.js +6 -0
  329. package/src/py/dynamodb/schema.d.js.map +1 -0
  330. package/src/py/dynamodb/schema.d.ts +16 -0
  331. package/src/py/dynamodb/schema.json +75 -0
  332. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +212 -4678
  333. package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +5409 -0
  334. package/src/py/fast-api/files/app/__name__/init.py.template +5 -22
  335. package/src/py/fast-api/files/app/__name__/main.py.template +4 -1
  336. package/src/py/fast-api/generator.d.ts +3 -3
  337. package/src/py/fast-api/generator.js +90 -87
  338. package/src/py/fast-api/generator.js.map +1 -1
  339. package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +4 -3
  340. package/src/py/fast-api/react/generator.d.ts +4 -4
  341. package/src/py/fast-api/react/generator.js +25 -25
  342. package/src/py/fast-api/react/generator.js.map +1 -1
  343. package/src/py/fast-api/react/open-api.d.ts +1 -1
  344. package/src/py/fast-api/react/open-api.js +31 -29
  345. package/src/py/fast-api/react/open-api.js.map +1 -1
  346. package/src/py/fast-api/react/schema.d.js +6 -0
  347. package/src/py/fast-api/react/schema.d.js.map +1 -0
  348. package/src/py/fast-api/react/schema.d.ts +1 -0
  349. package/src/py/fast-api/react/schema.json +5 -0
  350. package/src/py/fast-api/schema.d.js +6 -0
  351. package/src/py/fast-api/schema.d.js.map +1 -0
  352. package/src/py/fast-api/schema.d.ts +1 -0
  353. package/src/py/fast-api/schema.json +5 -0
  354. package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +4 -4
  355. package/src/py/lambda-function/generator.d.ts +3 -3
  356. package/src/py/lambda-function/generator.js +60 -59
  357. package/src/py/lambda-function/generator.js.map +1 -1
  358. package/src/py/lambda-function/schema.d.js +6 -0
  359. package/src/py/lambda-function/schema.d.js.map +1 -0
  360. package/src/py/lambda-function/schema.d.ts +1 -0
  361. package/src/py/lambda-function/schema.json +5 -0
  362. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +208 -19
  363. package/src/py/mcp-server/files/deploy/Dockerfile.template +1 -1
  364. package/src/py/mcp-server/generator.d.ts +3 -3
  365. package/src/py/mcp-server/generator.js +162 -124
  366. package/src/py/mcp-server/generator.js.map +1 -1
  367. package/src/py/mcp-server/schema.d.js +6 -0
  368. package/src/py/mcp-server/schema.d.js.map +1 -0
  369. package/src/py/mcp-server/schema.d.ts +1 -0
  370. package/src/py/mcp-server/schema.json +5 -0
  371. package/src/py/project/generator.d.ts +17 -4
  372. package/src/py/project/generator.js +205 -127
  373. package/src/py/project/generator.js.map +1 -1
  374. package/src/py/project/schema.d.js +6 -0
  375. package/src/py/project/schema.d.js.map +1 -0
  376. package/src/py/project/schema.d.ts +1 -0
  377. package/src/py/project/schema.json +5 -0
  378. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +2038 -0
  379. package/src/py/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +104 -0
  380. package/src/py/rdb/agent-connection/generator.d.ts +10 -0
  381. package/src/py/rdb/agent-connection/generator.js +46 -0
  382. package/src/py/rdb/agent-connection/generator.js.map +1 -0
  383. package/src/py/rdb/agent-connection/schema.d.js +8 -0
  384. package/src/py/rdb/agent-connection/schema.d.js.map +1 -0
  385. package/src/py/rdb/agent-connection/schema.d.ts +15 -0
  386. package/src/py/rdb/agent-connection/schema.json +27 -0
  387. package/src/py/rdb/fast-api-connection/__snapshots__/generator.spec.ts.snap +44 -0
  388. package/src/py/rdb/fast-api-connection/files/__apiModuleName__/dependencies/__rdbNameSnake__.py.template +14 -0
  389. package/src/py/rdb/fast-api-connection/generator.d.ts +10 -0
  390. package/src/py/rdb/fast-api-connection/generator.js +54 -0
  391. package/src/py/rdb/fast-api-connection/generator.js.map +1 -0
  392. package/src/py/rdb/fast-api-connection/schema.d.js +8 -0
  393. package/src/py/rdb/fast-api-connection/schema.d.js.map +1 -0
  394. package/src/py/rdb/fast-api-connection/schema.d.ts +13 -0
  395. package/src/py/rdb/fast-api-connection/schema.json +23 -0
  396. package/src/py/rdb/files/Dockerfile.create-db-user.template +10 -0
  397. package/src/py/rdb/files/Dockerfile.migration.template +10 -0
  398. package/src/py/rdb/files/__name__/__init__.py.template +3 -0
  399. package/src/py/rdb/files/__name__/connection.py.template +55 -0
  400. package/src/py/rdb/files/__name__/create_db_user_handler.py.template +97 -0
  401. package/src/py/rdb/files/__name__/migration_handler.py.template +36 -0
  402. package/src/py/rdb/files/__name__/models/__init__.py.template +3 -0
  403. package/src/py/rdb/files/__name__/models/example.py.template +8 -0
  404. package/src/py/rdb/files/__name__/utils.py.template +104 -0
  405. package/src/py/rdb/files/alembic.ini.template +38 -0
  406. package/src/py/rdb/files/config.json.template +14 -0
  407. package/src/py/rdb/files/migrations/env.py.template +80 -0
  408. package/src/py/rdb/files/migrations/script.py.mako.template +28 -0
  409. package/src/py/rdb/generator.d.ts +6 -0
  410. package/src/py/rdb/generator.js +274 -0
  411. package/src/py/rdb/generator.js.map +1 -0
  412. package/src/py/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +101 -0
  413. package/src/py/rdb/mcp-server-connection/generator.d.ts +10 -0
  414. package/src/py/rdb/mcp-server-connection/generator.js +46 -0
  415. package/src/py/rdb/mcp-server-connection/generator.js.map +1 -0
  416. package/src/py/rdb/mcp-server-connection/schema.d.js +8 -0
  417. package/src/py/rdb/mcp-server-connection/schema.d.js.map +1 -0
  418. package/src/py/rdb/mcp-server-connection/schema.d.ts +15 -0
  419. package/src/py/rdb/mcp-server-connection/schema.json +27 -0
  420. package/src/py/rdb/schema.d.js +6 -0
  421. package/src/py/rdb/schema.d.js.map +1 -0
  422. package/src/py/rdb/schema.d.ts +16 -0
  423. package/src/py/rdb/schema.json +77 -0
  424. package/src/py/rdb/utils.d.ts +6 -0
  425. package/src/py/rdb/utils.js +16 -0
  426. package/src/py/rdb/utils.js.map +1 -0
  427. package/src/sdk/agentcore-gateway.d.ts +6 -0
  428. package/src/sdk/agentcore-gateway.js +7 -0
  429. package/src/sdk/agentcore-gateway.js.map +1 -0
  430. package/src/sdk/connection.d.ts +6 -0
  431. package/src/sdk/connection.js +6 -0
  432. package/src/sdk/connection.js.map +1 -0
  433. package/src/sdk/license.d.ts +8 -0
  434. package/src/sdk/license.js +7 -0
  435. package/src/sdk/license.js.map +1 -0
  436. package/src/sdk/open-api.d.ts +10 -0
  437. package/src/sdk/open-api.js +8 -0
  438. package/src/sdk/open-api.js.map +1 -0
  439. package/src/sdk/py.d.ts +16 -0
  440. package/src/sdk/py.js +11 -0
  441. package/src/sdk/py.js.map +1 -0
  442. package/src/sdk/terraform.d.ts +6 -0
  443. package/src/sdk/terraform.js +7 -0
  444. package/src/sdk/terraform.js.map +1 -0
  445. package/src/sdk/ts.d.ts +33 -0
  446. package/src/sdk/ts.js +35 -0
  447. package/src/sdk/ts.js.map +1 -0
  448. package/{sdk → src/sdk}/utils/ast.d.ts +1 -2
  449. package/src/sdk/utils/ast.js +6 -0
  450. package/src/sdk/utils/ast.js.map +1 -0
  451. package/{sdk → src/sdk}/utils/format.d.ts +1 -1
  452. package/src/sdk/utils/format.js +6 -0
  453. package/src/sdk/utils/format.js.map +1 -0
  454. package/{sdk → src/sdk}/utils/test.d.ts +1 -1
  455. package/src/sdk/utils/test.js +6 -0
  456. package/src/sdk/utils/test.js.map +1 -0
  457. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +19 -24
  458. package/src/smithy/project/files/build.Dockerfile.template +1 -4
  459. package/src/smithy/project/files/src/operations/echo.smithy.template +1 -0
  460. package/src/smithy/project/generator.d.ts +3 -3
  461. package/src/smithy/project/generator.js +64 -57
  462. package/src/smithy/project/generator.js.map +1 -1
  463. package/src/smithy/project/schema.d.js +6 -0
  464. package/src/smithy/project/schema.d.js.map +1 -0
  465. package/src/smithy/project/schema.d.ts +1 -0
  466. package/src/smithy/project/schema.json +5 -0
  467. package/src/smithy/react-connection/__snapshots__/generator.spec.ts.snap +1 -1
  468. package/src/smithy/react-connection/generator.d.ts +3 -3
  469. package/src/smithy/react-connection/generator.js +39 -47
  470. package/src/smithy/react-connection/generator.js.map +1 -1
  471. package/src/smithy/react-connection/schema.d.js +6 -0
  472. package/src/smithy/react-connection/schema.d.js.map +1 -0
  473. package/src/smithy/react-connection/schema.d.ts +1 -0
  474. package/src/smithy/react-connection/schema.json +5 -0
  475. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +824 -120
  476. package/src/smithy/ts/api/files/handler.ts.template +2 -2
  477. package/src/smithy/ts/api/files/local-server.ts.template +2 -2
  478. package/src/smithy/ts/api/files/operations/echo.ts.template +2 -2
  479. package/src/smithy/ts/api/files/service.ts.template +3 -3
  480. package/src/smithy/ts/api/generator.d.ts +3 -3
  481. package/src/smithy/ts/api/generator.js +128 -105
  482. package/src/smithy/ts/api/generator.js.map +1 -1
  483. package/src/smithy/ts/api/schema.d.js +6 -0
  484. package/src/smithy/ts/api/schema.d.js.map +1 -0
  485. package/src/smithy/ts/api/schema.d.ts +1 -0
  486. package/src/smithy/ts/api/schema.json +5 -0
  487. package/src/terraform/project/files/application/src/main.tf.template +6 -1
  488. package/src/terraform/project/files/application/src/providers.tf.template +1 -1
  489. package/src/terraform/project/generator.d.ts +3 -3
  490. package/src/terraform/project/generator.js +156 -104
  491. package/src/terraform/project/generator.js.map +1 -1
  492. package/src/terraform/project/schema.d.js +9 -0
  493. package/src/terraform/project/schema.d.js.map +1 -0
  494. package/src/terraform/project/schema.d.ts +1 -0
  495. package/src/terraform/project/schema.json +5 -0
  496. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +1099 -134
  497. package/src/trpc/backend/files/src/client/index.ts.template +1 -1
  498. package/src/trpc/backend/files/src/handler.ts.template +1 -1
  499. package/src/trpc/backend/files/src/index.ts.template +5 -5
  500. package/src/trpc/backend/files/src/init.ts.template +1 -1
  501. package/src/trpc/backend/files/src/local-server.ts.template +1 -1
  502. package/src/trpc/backend/files/src/middleware/index.ts.template +7 -7
  503. package/src/trpc/backend/files/src/procedures/echo.ts.template +3 -3
  504. package/src/trpc/backend/files/src/router.ts.template +2 -2
  505. package/src/trpc/backend/files/src/schema/echo.ts.template +2 -2
  506. package/src/trpc/backend/files/src/schema/index.ts.template +1 -1
  507. package/src/trpc/backend/generator.d.ts +4 -4
  508. package/src/trpc/backend/generator.js +98 -84
  509. package/src/trpc/backend/generator.js.map +1 -1
  510. package/src/trpc/backend/schema.d.js +6 -0
  511. package/src/trpc/backend/schema.d.js.map +1 -0
  512. package/src/trpc/backend/schema.d.ts +3 -2
  513. package/src/trpc/backend/schema.json +5 -0
  514. package/src/trpc/react/__snapshots__/generator.spec.ts.snap +4 -4
  515. package/src/trpc/react/files/src/components/__apiNameClassName__ClientProvider.tsx.template +3 -3
  516. package/src/trpc/react/generator.d.ts +4 -4
  517. package/src/trpc/react/generator.js +63 -58
  518. package/src/trpc/react/generator.js.map +1 -1
  519. package/src/trpc/react/schema.d.js +6 -0
  520. package/src/trpc/react/schema.d.js.map +1 -0
  521. package/src/trpc/react/schema.d.ts +1 -0
  522. package/src/trpc/react/schema.json +5 -0
  523. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +781 -22
  524. package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +256 -0
  525. package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client-strands.ts.template +23 -0
  526. package/src/ts/agent/a2a-connection/generator.d.ts +3 -3
  527. package/src/ts/agent/a2a-connection/generator.js +64 -55
  528. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  529. package/src/ts/agent/a2a-connection/schema.d.js +8 -0
  530. package/src/ts/agent/a2a-connection/schema.d.js.map +1 -0
  531. package/src/ts/agent/a2a-connection/schema.d.ts +1 -0
  532. package/src/ts/agent/a2a-connection/schema.json +5 -0
  533. package/src/ts/agent/files/a2a/index.ts.template +1 -1
  534. package/src/ts/agent/files/ag-ui/index.ts.template +1 -1
  535. package/src/ts/agent/files/common/agent.ts.template +6 -2
  536. package/src/ts/agent/files/deploy/Dockerfile.template +4 -1
  537. package/src/ts/agent/files/http/client.ts.template +2 -2
  538. package/src/ts/agent/files/http/index.ts.template +2 -2
  539. package/src/ts/agent/files/http/router.ts.template +5 -5
  540. package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +220 -0
  541. package/src/ts/agent/gateway-connection/files/agent-connection/app/__gatewayKebabCase__-client-strands.ts.template +30 -0
  542. package/src/ts/agent/gateway-connection/generator.d.ts +10 -0
  543. package/src/ts/agent/gateway-connection/generator.js +116 -0
  544. package/src/ts/agent/gateway-connection/generator.js.map +1 -0
  545. package/src/ts/agent/gateway-connection/schema.d.js +6 -0
  546. package/src/ts/agent/gateway-connection/schema.d.js.map +1 -0
  547. package/src/ts/agent/gateway-connection/schema.d.ts +13 -0
  548. package/src/ts/agent/gateway-connection/schema.json +31 -0
  549. package/src/ts/agent/generator.d.ts +3 -3
  550. package/src/ts/agent/generator.js +203 -144
  551. package/src/ts/agent/generator.js.map +1 -1
  552. package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +192 -111
  553. package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client-strands.ts.template +22 -0
  554. package/src/ts/agent/mcp-connection/generator.d.ts +3 -3
  555. package/src/ts/agent/mcp-connection/generator.js +54 -59
  556. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  557. package/src/ts/agent/mcp-connection/schema.d.js +8 -0
  558. package/src/ts/agent/mcp-connection/schema.d.js.map +1 -0
  559. package/src/ts/agent/mcp-connection/schema.d.ts +1 -0
  560. package/src/ts/agent/mcp-connection/schema.json +5 -0
  561. package/src/ts/agent/react-connection/generator.d.ts +4 -4
  562. package/src/ts/agent/react-connection/generator.js +86 -80
  563. package/src/ts/agent/react-connection/generator.js.map +1 -1
  564. package/src/ts/agent/react-connection/local-dev.d.ts +13 -0
  565. package/src/ts/agent/react-connection/local-dev.js +17 -0
  566. package/src/ts/agent/react-connection/local-dev.js.map +1 -0
  567. package/src/ts/agent/react-connection/schema.d.js +8 -0
  568. package/src/ts/agent/react-connection/schema.d.js.map +1 -0
  569. package/src/ts/agent/react-connection/schema.d.ts +1 -0
  570. package/src/ts/agent/react-connection/schema.json +5 -0
  571. package/src/ts/agent/schema.d.js +6 -0
  572. package/src/ts/agent/schema.d.js.map +1 -0
  573. package/src/ts/agent/schema.d.ts +1 -0
  574. package/src/ts/agent/schema.json +5 -0
  575. package/src/ts/api/generator.d.ts +3 -3
  576. package/src/ts/api/generator.js +16 -16
  577. package/src/ts/api/generator.js.map +1 -1
  578. package/src/ts/api/schema.d.js +6 -0
  579. package/src/ts/api/schema.d.js.map +1 -0
  580. package/src/ts/api/schema.d.ts +3 -1
  581. package/src/ts/api/schema.json +5 -0
  582. package/src/ts/astro-docs/__snapshots__/generator.spec.ts.snap +15 -16
  583. package/src/ts/astro-docs/files/translation/scripts/translate.ts.template +3 -2
  584. package/src/ts/astro-docs/generator.d.ts +3 -3
  585. package/src/ts/astro-docs/generator.js +71 -54
  586. package/src/ts/astro-docs/generator.js.map +1 -1
  587. package/src/ts/astro-docs/schema.d.js +6 -0
  588. package/src/ts/astro-docs/schema.d.js.map +1 -0
  589. package/src/ts/astro-docs/schema.d.ts +2 -2
  590. package/src/ts/astro-docs/schema.json +3 -3
  591. package/src/ts/docs/generator.d.ts +3 -3
  592. package/src/ts/docs/generator.js +10 -10
  593. package/src/ts/docs/generator.js.map +1 -1
  594. package/src/ts/docs/schema.d.js +6 -0
  595. package/src/ts/docs/schema.d.js.map +1 -0
  596. package/src/ts/docs/schema.d.ts +1 -4
  597. package/src/ts/docs/schema.json +3 -3
  598. package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +400 -512
  599. package/src/ts/dynamodb/agent-connection/__snapshots__/generator.spec.ts.snap +5 -5
  600. package/src/ts/dynamodb/agent-connection/generator.d.ts +3 -3
  601. package/src/ts/dynamodb/agent-connection/generator.js +21 -23
  602. package/src/ts/dynamodb/agent-connection/generator.js.map +1 -1
  603. package/src/ts/dynamodb/agent-connection/schema.d.js +8 -0
  604. package/src/ts/dynamodb/agent-connection/schema.d.js.map +1 -0
  605. package/src/ts/dynamodb/agent-connection/schema.d.ts +1 -0
  606. package/src/ts/dynamodb/agent-connection/schema.json +5 -0
  607. package/src/ts/dynamodb/files/config.json.template +24 -0
  608. package/src/ts/dynamodb/files/src/client.ts.template +30 -11
  609. package/src/ts/dynamodb/files/src/entities/example.ts.template +1 -1
  610. package/src/ts/dynamodb/files/src/entities/index.ts.template +1 -1
  611. package/src/ts/dynamodb/files/src/index.ts.template +2 -11
  612. package/src/ts/dynamodb/generator.d.ts +3 -3
  613. package/src/ts/dynamodb/generator.js +73 -63
  614. package/src/ts/dynamodb/generator.js.map +1 -1
  615. package/src/ts/dynamodb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +5 -5
  616. package/src/ts/dynamodb/mcp-server-connection/generator.d.ts +3 -3
  617. package/src/ts/dynamodb/mcp-server-connection/generator.js +21 -23
  618. package/src/ts/dynamodb/mcp-server-connection/generator.js.map +1 -1
  619. package/src/ts/dynamodb/mcp-server-connection/schema.d.js +8 -0
  620. package/src/ts/dynamodb/mcp-server-connection/schema.d.js.map +1 -0
  621. package/src/ts/dynamodb/mcp-server-connection/schema.d.ts +1 -0
  622. package/src/ts/dynamodb/mcp-server-connection/schema.json +5 -0
  623. package/src/ts/dynamodb/schema.d.js +6 -0
  624. package/src/ts/dynamodb/schema.d.js.map +1 -0
  625. package/src/ts/dynamodb/schema.d.ts +2 -0
  626. package/src/ts/dynamodb/schema.json +25 -2
  627. package/src/ts/dynamodb/smithy-connection/__snapshots__/generator.spec.ts.snap +3 -3
  628. package/src/ts/dynamodb/smithy-connection/generator.d.ts +3 -3
  629. package/src/ts/dynamodb/smithy-connection/generator.js +20 -22
  630. package/src/ts/dynamodb/smithy-connection/generator.js.map +1 -1
  631. package/src/ts/dynamodb/smithy-connection/schema.d.js +8 -0
  632. package/src/ts/dynamodb/smithy-connection/schema.d.js.map +1 -0
  633. package/src/ts/dynamodb/smithy-connection/schema.d.ts +1 -0
  634. package/src/ts/dynamodb/smithy-connection/schema.json +5 -0
  635. package/src/ts/dynamodb/trpc-connection/__snapshots__/generator.spec.ts.snap +3 -3
  636. package/src/ts/dynamodb/trpc-connection/generator.d.ts +3 -3
  637. package/src/ts/dynamodb/trpc-connection/generator.js +20 -22
  638. package/src/ts/dynamodb/trpc-connection/generator.js.map +1 -1
  639. package/src/ts/dynamodb/trpc-connection/schema.d.js +8 -0
  640. package/src/ts/dynamodb/trpc-connection/schema.d.js.map +1 -0
  641. package/src/ts/dynamodb/trpc-connection/schema.d.ts +1 -0
  642. package/src/ts/dynamodb/trpc-connection/schema.json +5 -0
  643. package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +4 -4
  644. package/src/ts/lambda-function/generator.d.ts +3 -3
  645. package/src/ts/lambda-function/generator.js +59 -56
  646. package/src/ts/lambda-function/generator.js.map +1 -1
  647. package/src/ts/lambda-function/io.js +83 -52
  648. package/src/ts/lambda-function/io.js.map +1 -1
  649. package/src/ts/lambda-function/schema.d.js +6 -0
  650. package/src/ts/lambda-function/schema.d.js.map +1 -0
  651. package/src/ts/lambda-function/schema.d.ts +1 -0
  652. package/src/ts/lambda-function/schema.json +5 -0
  653. package/src/ts/lib/__snapshots__/generator.spec.ts.snap +98 -93
  654. package/src/ts/lib/__snapshots__/vitest.spec.ts.snap +24 -0
  655. package/src/ts/lib/biome.d.ts +7 -0
  656. package/src/ts/lib/biome.js +91 -0
  657. package/src/ts/lib/biome.js.map +1 -0
  658. package/src/ts/lib/generator.d.ts +3 -3
  659. package/src/ts/lib/generator.js +107 -108
  660. package/src/ts/lib/generator.js.map +1 -1
  661. package/src/ts/lib/grit/vitest-pass-with-no-tests.grit +1 -4
  662. package/src/ts/lib/schema.d.js +6 -0
  663. package/src/ts/lib/schema.d.js.map +1 -0
  664. package/src/ts/lib/schema.d.ts +1 -1
  665. package/src/ts/lib/schema.json +5 -0
  666. package/src/ts/lib/ts-project-utils.d.ts +12 -2
  667. package/src/ts/lib/ts-project-utils.js +90 -67
  668. package/src/ts/lib/ts-project-utils.js.map +1 -1
  669. package/src/ts/lib/types.d.ts +6 -0
  670. package/src/ts/lib/types.js +5 -2
  671. package/src/ts/lib/types.js.map +1 -1
  672. package/src/ts/lib/vitest.d.ts +2 -2
  673. package/src/ts/lib/vitest.js +29 -26
  674. package/src/ts/lib/vitest.js.map +1 -1
  675. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +208 -42
  676. package/src/ts/mcp-server/files/Dockerfile.template +4 -1
  677. package/src/ts/mcp-server/generator.d.ts +3 -3
  678. package/src/ts/mcp-server/generator.js +181 -136
  679. package/src/ts/mcp-server/generator.js.map +1 -1
  680. package/src/ts/mcp-server/schema.d.js +6 -0
  681. package/src/ts/mcp-server/schema.d.js.map +1 -0
  682. package/src/ts/mcp-server/schema.d.ts +1 -0
  683. package/src/ts/mcp-server/schema.json +5 -0
  684. package/src/ts/nx-generator/__snapshots__/generator.spec.ts.snap +46 -26
  685. package/src/ts/nx-generator/files/common/schema.d.ts.template +1 -0
  686. package/src/ts/nx-generator/files/common/schema.json.template +5 -0
  687. package/src/ts/nx-generator/files/local/generator.ts.template +3 -3
  688. package/src/ts/nx-generator/files/nx-plugin-for-aws/generator/generator.ts.template +6 -7
  689. package/src/ts/nx-generator/generator.d.ts +2 -2
  690. package/src/ts/nx-generator/generator.js +113 -73
  691. package/src/ts/nx-generator/generator.js.map +1 -1
  692. package/src/ts/nx-generator/schema.d.js +6 -0
  693. package/src/ts/nx-generator/schema.d.js.map +1 -0
  694. package/src/ts/nx-generator/schema.d.ts +1 -0
  695. package/src/ts/nx-generator/schema.json +5 -0
  696. package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +30 -18
  697. package/src/ts/nx-plugin/files/mcp-server/server.ts.template +5 -5
  698. package/src/ts/nx-plugin/files/mcp-server/tools/create-workspace-command.ts.template +2 -2
  699. package/src/ts/nx-plugin/files/mcp-server/tools/general-guidance.ts.template +1 -1
  700. package/src/ts/nx-plugin/files/mcp-server/tools/generator-guide.ts.template +2 -2
  701. package/src/ts/nx-plugin/files/mcp-server/tools/list-generators.ts.template +2 -2
  702. package/src/ts/nx-plugin/files/mcp-server/utils.ts.template +3 -3
  703. package/src/ts/nx-plugin/generator.d.ts +3 -3
  704. package/src/ts/nx-plugin/generator.js +61 -50
  705. package/src/ts/nx-plugin/generator.js.map +1 -1
  706. package/src/ts/nx-plugin/schema.d.js +9 -0
  707. package/src/ts/nx-plugin/schema.d.js.map +1 -0
  708. package/src/ts/nx-plugin/schema.json +5 -0
  709. package/src/ts/nx-plugin/utils.d.ts +1 -1
  710. package/src/ts/nx-plugin/utils.js +36 -39
  711. package/src/ts/nx-plugin/utils.js.map +1 -1
  712. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +455 -646
  713. package/src/ts/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +6 -6
  714. package/src/ts/rdb/agent-connection/generator.d.ts +3 -3
  715. package/src/ts/rdb/agent-connection/generator.js +38 -39
  716. package/src/ts/rdb/agent-connection/generator.js.map +1 -1
  717. package/src/ts/rdb/agent-connection/schema.d.js +8 -0
  718. package/src/ts/rdb/agent-connection/schema.d.js.map +1 -0
  719. package/src/ts/rdb/agent-connection/schema.d.ts +1 -0
  720. package/src/ts/rdb/agent-connection/schema.json +5 -0
  721. package/src/ts/rdb/files/Dockerfile.template +8 -1
  722. package/src/ts/rdb/files/config.json.template +14 -0
  723. package/src/ts/rdb/files/prisma.config.ts.template +6 -5
  724. package/src/ts/rdb/files/src/create-db-user-handler.ts.template +9 -11
  725. package/src/ts/rdb/files/src/index.ts.template +1 -2
  726. package/src/ts/rdb/files/src/migration-handler.ts.template +2 -29
  727. package/src/ts/rdb/files/src/prisma.ts.template +33 -25
  728. package/src/ts/rdb/files/src/utils.ts.template +3 -0
  729. package/src/ts/rdb/generator.d.ts +3 -7
  730. package/src/ts/rdb/generator.js +173 -131
  731. package/src/ts/rdb/generator.js.map +1 -1
  732. package/src/ts/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +6 -6
  733. package/src/ts/rdb/mcp-server-connection/generator.d.ts +3 -3
  734. package/src/ts/rdb/mcp-server-connection/generator.js +36 -37
  735. package/src/ts/rdb/mcp-server-connection/generator.js.map +1 -1
  736. package/src/ts/rdb/mcp-server-connection/schema.d.js +8 -0
  737. package/src/ts/rdb/mcp-server-connection/schema.d.js.map +1 -0
  738. package/src/ts/rdb/mcp-server-connection/schema.d.ts +1 -0
  739. package/src/ts/rdb/mcp-server-connection/schema.json +5 -0
  740. package/src/ts/rdb/schema.d.js +6 -0
  741. package/src/ts/rdb/schema.d.js.map +1 -0
  742. package/src/ts/rdb/schema.d.ts +1 -0
  743. package/src/ts/rdb/schema.json +6 -1
  744. package/src/ts/rdb/smithy-connection/__snapshots__/generator.spec.ts.snap +3 -3
  745. package/src/ts/rdb/smithy-connection/generator.d.ts +3 -3
  746. package/src/ts/rdb/smithy-connection/generator.js +46 -43
  747. package/src/ts/rdb/smithy-connection/generator.js.map +1 -1
  748. package/src/ts/rdb/smithy-connection/schema.d.js +8 -0
  749. package/src/ts/rdb/smithy-connection/schema.d.js.map +1 -0
  750. package/src/ts/rdb/smithy-connection/schema.d.ts +1 -0
  751. package/src/ts/rdb/smithy-connection/schema.json +5 -0
  752. package/src/ts/rdb/trpc-connection/__snapshots__/generator.spec.ts.snap +3 -3
  753. package/src/ts/rdb/trpc-connection/generator.d.ts +3 -3
  754. package/src/ts/rdb/trpc-connection/generator.js +36 -31
  755. package/src/ts/rdb/trpc-connection/generator.js.map +1 -1
  756. package/src/ts/rdb/trpc-connection/schema.d.js +8 -0
  757. package/src/ts/rdb/trpc-connection/schema.d.js.map +1 -0
  758. package/src/ts/rdb/trpc-connection/schema.d.ts +1 -0
  759. package/src/ts/rdb/trpc-connection/schema.json +5 -0
  760. package/src/ts/rdb/utils.d.ts +1 -1
  761. package/src/ts/rdb/utils.js +9 -11
  762. package/src/ts/rdb/utils.js.map +1 -1
  763. package/src/ts/react-website/agui/files/common/src/hooks/useAgui__agentNameClassName__.tsx.template +1 -16
  764. package/src/ts/react-website/agui/generator.d.ts +1 -1
  765. package/src/ts/react-website/agui/generator.js +69 -62
  766. package/src/ts/react-website/agui/generator.js.map +1 -1
  767. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +1190 -799
  768. package/src/ts/react-website/app/generator.d.ts +4 -4
  769. package/src/ts/react-website/app/generator.js +217 -192
  770. package/src/ts/react-website/app/generator.js.map +1 -1
  771. package/src/ts/react-website/app/schema.d.js +6 -0
  772. package/src/ts/react-website/app/schema.d.js.map +1 -0
  773. package/src/ts/react-website/app/schema.d.ts +1 -1
  774. package/src/ts/react-website/app/schema.json +11 -6
  775. package/src/ts/react-website/cognito-auth/__snapshots__/generator.spec.ts.snap +129 -18
  776. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +36 -10
  777. package/src/ts/react-website/cognito-auth/__snapshots__/generator.ux-provider.spec.ts.snap +0 -20
  778. package/src/ts/react-website/cognito-auth/files/app/components/CognitoAuth/index.tsx.template +2 -2
  779. package/src/ts/react-website/cognito-auth/generator.d.ts +4 -4
  780. package/src/ts/react-website/cognito-auth/generator.js +64 -63
  781. package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
  782. package/src/ts/react-website/cognito-auth/grit/cloudscape-auth-menu.grit +8 -6
  783. package/src/ts/react-website/cognito-auth/grit/cognito-auth-wrapper.grit +1 -1
  784. package/src/ts/react-website/cognito-auth/grit/none-auth-menu.grit +1 -0
  785. package/src/ts/react-website/cognito-auth/grit/shadcn-auth-menu.grit +3 -1
  786. package/src/ts/react-website/cognito-auth/grit/shadcn-state-declarations.grit +3 -1
  787. package/src/ts/react-website/cognito-auth/schema.d.js +6 -0
  788. package/src/ts/react-website/cognito-auth/schema.d.js.map +1 -0
  789. package/src/ts/react-website/cognito-auth/schema.d.ts +1 -0
  790. package/src/ts/react-website/cognito-auth/schema.json +5 -0
  791. package/src/ts/react-website/cognito-auth/utils.d.ts +1 -1
  792. package/src/ts/react-website/cognito-auth/utils.js +34 -32
  793. package/src/ts/react-website/cognito-auth/utils.js.map +1 -1
  794. package/src/ts/react-website/runtime-config/__snapshots__/generator.spec.ts.snap +2 -2
  795. package/src/ts/react-website/runtime-config/files/app/components/RuntimeConfig/index.tsx.template +2 -2
  796. package/src/ts/react-website/runtime-config/generator.d.ts +3 -3
  797. package/src/ts/react-website/runtime-config/generator.js +29 -31
  798. package/src/ts/react-website/runtime-config/generator.js.map +1 -1
  799. package/src/ts/react-website/runtime-config/schema.d.js +6 -0
  800. package/src/ts/react-website/runtime-config/schema.d.js.map +1 -0
  801. package/src/ts/react-website/runtime-config/schema.d.ts +1 -0
  802. package/src/ts/react-website/runtime-config/schema.json +5 -0
  803. package/src/ts/sync/generator.d.ts +3 -3
  804. package/src/ts/sync/generator.js +58 -59
  805. package/src/ts/sync/generator.js.map +1 -1
  806. package/src/ts/website/app/generator.d.ts +3 -3
  807. package/src/ts/website/app/generator.js +10 -10
  808. package/src/ts/website/app/generator.js.map +1 -1
  809. package/src/ts/website/app/schema.d.js +6 -0
  810. package/src/ts/website/app/schema.d.js.map +1 -0
  811. package/src/ts/website/app/schema.d.ts +1 -1
  812. package/src/ts/website/app/schema.json +11 -6
  813. package/src/ts/website/auth/generator.d.ts +4 -4
  814. package/src/ts/website/auth/generator.js +11 -10
  815. package/src/ts/website/auth/generator.js.map +1 -1
  816. package/src/ts/website/auth/schema.d.js +6 -0
  817. package/src/ts/website/auth/schema.d.js.map +1 -0
  818. package/src/ts/website/auth/schema.d.ts +1 -0
  819. package/src/ts/website/auth/schema.json +5 -0
  820. package/src/utils/agent-chat/agent-chat.d.ts +31 -0
  821. package/src/utils/agent-chat/agent-chat.js +31 -0
  822. package/src/utils/agent-chat/agent-chat.js.map +1 -0
  823. package/src/utils/agent-chat/files/a2a/chat.ts.template +33 -0
  824. package/src/utils/agent-chat/files/ag-ui/chat.ts.template +17 -0
  825. package/src/utils/agent-chat/files/common/agentcore.ts.template +81 -0
  826. package/src/utils/agent-chat/files/http-py/chat.ts.template +43 -0
  827. package/src/utils/agent-chat/files/http-ts/chat.ts.template +54 -0
  828. package/src/utils/agent-connection/agent-connection.d.ts +117 -25
  829. package/src/utils/agent-connection/agent-connection.js +414 -103
  830. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  831. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +93 -0
  832. package/src/utils/agent-connection/files/core-auth/agentcore-endpoints.ts.template +37 -0
  833. package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +54 -0
  834. package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +41 -0
  835. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +70 -0
  836. package/src/utils/agent-connection/files/core-runtime-config/runtime-config.ts.template +22 -32
  837. package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +39 -0
  838. package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +61 -0
  839. package/src/utils/agent-connection/files/core-strands/base/model-errors-strands.ts.template +36 -0
  840. package/src/utils/agent-connection/files/{core-runtime-config/with-session-id.ts.template → core-strands/base/with-session-id-strands.ts.template} +1 -1
  841. package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +26 -0
  842. package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +27 -0
  843. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client_config.py.template +43 -0
  844. package/src/utils/agent-connection/files/py-core-auth/agentcore_endpoints.py.template +47 -0
  845. package/src/utils/agent-connection/files/py-core-auth/auth/session.py.template +51 -0
  846. package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_transport.py.template +28 -0
  847. package/src/utils/agent-connection/files/py-core-langchain/a2a/agentcore_a2a_client_langchain.py.template +99 -0
  848. package/src/utils/agent-connection/files/py-core-langchain/gateway/agentcore_gateway_mcp_client_langchain.py.template +57 -0
  849. package/src/utils/agent-connection/files/py-core-langchain/mcp/agentcore_mcp_client_langchain.py.template +64 -0
  850. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_transport.py.template +34 -0
  851. package/src/utils/agent-connection/files/py-core-runtime-config/runtime_config.py.template +5 -18
  852. package/src/utils/agent-connection/files/py-core-shared/agentcore_transport.py.template +40 -0
  853. package/src/utils/agent-connection/files/py-core-strands/a2a/agentcore_a2a_client_strands.py.template +66 -0
  854. package/src/utils/agent-connection/files/py-core-strands/base/model_errors_strands.py.template +40 -0
  855. package/src/utils/agent-connection/files/py-core-strands/gateway/agentcore_gateway_mcp_client_strands.py.template +22 -0
  856. package/src/utils/agent-connection/files/py-core-strands/mcp/agentcore_mcp_client_strands.py.template +30 -0
  857. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +11 -3
  858. package/src/utils/agent-core-constructs/agent-core-constructs.js +93 -38
  859. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  860. package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +31 -4
  861. package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +50 -0
  862. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +487 -0
  863. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/readiness-probe/index.js.template +55 -0
  864. package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +32 -0
  865. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +449 -0
  866. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/render-cedar.cjs.template +13 -0
  867. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +151 -13
  868. package/src/utils/agent-core-constructs/files/terraform/core/agentcore-gateway/gateway.tf.template +14 -0
  869. package/src/utils/api-constructs/api-constructs.d.ts +2 -2
  870. package/src/utils/api-constructs/api-constructs.js +36 -31
  871. package/src/utils/api-constructs/api-constructs.js.map +1 -1
  872. package/src/utils/api-constructs/files/cdk/app/apis/http/__apiNameKebabCase__.ts.template +8 -8
  873. package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +11 -8
  874. package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +26 -9
  875. package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account/index.js.template +70 -0
  876. package/src/utils/api-constructs/files/cdk/core/api/rest/api-gateway-account.ts.template +82 -0
  877. package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +54 -18
  878. package/src/utils/api-constructs/files/cdk/core/api/trpc/trpc-utils.ts.template +1 -1
  879. package/src/utils/api-constructs/files/cdk/core/api/utils/utils.ts.template +61 -7
  880. package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +101 -12
  881. package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +194 -8
  882. package/src/utils/api-constructs/files/terraform/core/api/http/http-api/http-api.tf.template +1 -1
  883. package/src/utils/api-constructs/files/terraform/core/api/rest/api-gateway-account/api-gateway-account.tf.template +83 -0
  884. package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +5 -11
  885. package/src/utils/api-constructs/open-api-metadata.d.ts +2 -2
  886. package/src/utils/api-constructs/open-api-metadata.js +22 -22
  887. package/src/utils/api-constructs/open-api-metadata.js.map +1 -1
  888. package/src/utils/ast/website.d.ts +5 -1
  889. package/src/utils/ast/website.js +18 -20
  890. package/src/utils/ast/website.js.map +1 -1
  891. package/src/utils/ast.d.ts +33 -1
  892. package/src/utils/ast.js +146 -70
  893. package/src/utils/ast.js.map +1 -1
  894. package/src/utils/base-tsconfig.d.ts +30 -0
  895. package/src/utils/base-tsconfig.js +32 -0
  896. package/src/utils/base-tsconfig.js.map +1 -0
  897. package/src/utils/bundle/bundle.d.ts +1 -1
  898. package/src/utils/bundle/bundle.js +50 -47
  899. package/src/utils/bundle/bundle.js.map +1 -1
  900. package/src/utils/commands.d.ts +10 -3
  901. package/src/utils/commands.js +60 -26
  902. package/src/utils/commands.js.map +1 -1
  903. package/src/utils/config/index.d.ts +5 -5
  904. package/src/utils/config/index.js +5 -4
  905. package/src/utils/config/index.js.map +1 -1
  906. package/src/utils/config/utils.d.ts +13 -3
  907. package/src/utils/config/utils.js +65 -43
  908. package/src/utils/config/utils.js.map +1 -1
  909. package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +1 -1
  910. package/src/utils/connection/open-api/react.d.ts +6 -6
  911. package/src/utils/connection/open-api/react.js +81 -77
  912. package/src/utils/connection/open-api/react.js.map +1 -1
  913. package/src/utils/containers.d.ts +1 -1
  914. package/src/utils/containers.js +22 -23
  915. package/src/utils/containers.js.map +1 -1
  916. package/src/utils/docker.d.ts +44 -0
  917. package/src/utils/docker.js +81 -0
  918. package/src/utils/docker.js.map +1 -0
  919. package/src/utils/dynamodb-constructs/dynamodb-constructs.d.ts +3 -3
  920. package/src/utils/dynamodb-constructs/dynamodb-constructs.js +39 -41
  921. package/src/utils/dynamodb-constructs/dynamodb-constructs.js.map +1 -1
  922. package/src/utils/dynamodb-constructs/files/cdk/app/dynamodb/__nameKebabCase__.ts.template +18 -5
  923. package/src/utils/dynamodb-constructs/files/cdk/core/dynamodb.ts.template +1 -1
  924. package/src/utils/dynamodb-constructs/files/terraform/app/dynamodb/__nameKebabCase__/__nameKebabCase__.tf.template +24 -17
  925. package/src/utils/dynamodb-constructs/files/terraform/core/dynamodb/dynamodb.tf.template +1 -1
  926. package/src/utils/files/common/constructs/src/core/index.ts.template +4 -4
  927. package/src/utils/files/common/constructs/src/index.ts.template +2 -2
  928. package/src/utils/files/common/infra-config/src/index.ts.template +3 -3
  929. package/src/utils/files/common/infra-config/src/resolve-stage.ts.template +2 -2
  930. package/src/utils/files/common/infra-config/src/stages.config.ts.template +1 -1
  931. package/src/{ts/dynamodb/files/scripts → utils/files/common/scripts/src/dynamodb}/create-local-table.ts.template +65 -31
  932. package/src/utils/files/common/scripts/src/dynamodb/pull-image.ts.template +13 -0
  933. package/src/utils/files/common/scripts/src/dynamodb/start-container.ts.template +106 -0
  934. package/src/utils/files/common/scripts/src/infra/infra-deploy.ts.template +2 -0
  935. package/src/utils/files/common/scripts/src/infra/infra-destroy.ts.template +2 -0
  936. package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/cdk-command.ts.template +6 -3
  937. package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/run.ts.template +3 -3
  938. package/src/utils/files/common/scripts/src/rdb/mysql/wait-for-mysql-db.ts.template +32 -0
  939. package/src/utils/files/common/scripts/src/rdb/postgres/wait-for-postgres-db.ts.template +32 -0
  940. package/src/utils/files/common/scripts/src/rdb/shared/pull-image.ts.template +16 -0
  941. package/src/utils/files/common/scripts/src/rdb/shared/start-container.ts.template +117 -0
  942. package/src/utils/files/common/shadcn/src/index.ts.template +2 -2
  943. package/src/utils/files/terraform/src/core/asset-bucket/asset-bucket.tf.template +63 -72
  944. package/src/utils/files/terraform/src/core/runtime-config/appconfig/appconfig.tf.template +1 -1
  945. package/src/utils/files/terraform/src/core/runtime-config/appconfig-deployment/appconfig-deployment.tf.template +12 -6
  946. package/src/utils/files/terraform/src/core/runtime-config/entry/entry.tf.template +1 -1
  947. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +9 -4
  948. package/src/utils/files/website/hooks/sigv4/useSigV4.tsx.template +1 -1
  949. package/src/utils/format.d.ts +45 -2
  950. package/src/utils/format.js +332 -81
  951. package/src/utils/format.js.map +1 -1
  952. package/src/utils/fs.d.ts +1 -1
  953. package/src/utils/fs.js +14 -13
  954. package/src/utils/fs.js.map +1 -1
  955. package/src/utils/function-constructs/files/cdk/app/lambda-functions/__nameKebabCase__.ts.template +1 -1
  956. package/src/utils/function-constructs/files/terraform/app/lambda-functions/__nameKebabCase__/__nameKebabCase__.tf.template +2 -2
  957. package/src/utils/function-constructs/function-constructs.d.ts +2 -2
  958. package/src/utils/function-constructs/function-constructs.js +22 -25
  959. package/src/utils/function-constructs/function-constructs.js.map +1 -1
  960. package/src/utils/generators.d.ts +4 -0
  961. package/src/utils/generators.js +18 -20
  962. package/src/utils/generators.js.map +1 -1
  963. package/src/utils/git.d.ts +1 -1
  964. package/src/utils/git.js +19 -34
  965. package/src/utils/git.js.map +1 -1
  966. package/src/utils/iac-providers.js +5 -5
  967. package/src/utils/iac-providers.js.map +1 -1
  968. package/src/utils/iac.d.ts +1 -1
  969. package/src/utils/iac.js +12 -14
  970. package/src/utils/iac.js.map +1 -1
  971. package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +125 -16
  972. package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +28 -9
  973. package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +106 -6
  974. package/src/utils/identity-constructs/files/terraform/core/user-identity/main.tf.template +7 -0
  975. package/src/utils/identity-constructs/identity-constructs.d.ts +2 -2
  976. package/src/utils/identity-constructs/identity-constructs.js +28 -28
  977. package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
  978. package/src/utils/init.d.ts +53 -0
  979. package/src/utils/init.js +252 -0
  980. package/src/utils/init.js.map +1 -0
  981. package/src/utils/install.d.ts +32 -0
  982. package/src/utils/install.js +56 -0
  983. package/src/utils/install.js.map +1 -0
  984. package/src/utils/js.d.ts +4 -0
  985. package/src/utils/js.js +27 -20
  986. package/src/utils/js.js.map +1 -1
  987. package/src/utils/mcp.d.ts +1 -1
  988. package/src/utils/mcp.js +34 -41
  989. package/src/utils/mcp.js.map +1 -1
  990. package/src/utils/metrics.d.ts +9 -3
  991. package/src/utils/metrics.js +61 -46
  992. package/src/utils/metrics.js.map +1 -1
  993. package/src/utils/mock-project-graph.js +8 -12
  994. package/src/utils/mock-project-graph.js.map +1 -1
  995. package/src/utils/module-format.d.ts +28 -0
  996. package/src/utils/module-format.js +28 -0
  997. package/src/utils/module-format.js.map +1 -0
  998. package/src/utils/names.d.ts +22 -0
  999. package/src/utils/names.js +44 -48
  1000. package/src/utils/names.js.map +1 -1
  1001. package/src/utils/npm-scope.d.ts +1 -1
  1002. package/src/utils/npm-scope.js +9 -17
  1003. package/src/utils/npm-scope.js.map +1 -1
  1004. package/src/utils/nx.d.ts +39 -4
  1005. package/src/utils/nx.js +169 -75
  1006. package/src/utils/nx.js.map +1 -1
  1007. package/src/utils/nxlv-python.d.ts +1 -1
  1008. package/src/utils/nxlv-python.js +27 -15
  1009. package/src/utils/nxlv-python.js.map +1 -1
  1010. package/src/utils/object.js +5 -11
  1011. package/src/utils/object.js.map +1 -1
  1012. package/src/utils/paths.d.ts +1 -1
  1013. package/src/utils/paths.js +11 -15
  1014. package/src/utils/paths.js.map +1 -1
  1015. package/src/utils/pkg-manager.js +4 -9
  1016. package/src/utils/pkg-manager.js.map +1 -1
  1017. package/src/utils/pnpm-workspace.d.ts +1 -1
  1018. package/src/utils/pnpm-workspace.js +22 -22
  1019. package/src/utils/pnpm-workspace.js.map +1 -1
  1020. package/src/utils/port.d.ts +29 -7
  1021. package/src/utils/port.js +67 -28
  1022. package/src/utils/port.js.map +1 -1
  1023. package/src/utils/py.d.ts +16 -3
  1024. package/src/utils/py.js +72 -47
  1025. package/src/utils/py.js.map +1 -1
  1026. package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +72 -18
  1027. package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +97 -88
  1028. package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +127 -53
  1029. package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +36 -48
  1030. package/src/utils/rdb-constructs/rdb-constructs.d.ts +16 -5
  1031. package/src/utils/rdb-constructs/rdb-constructs.js +38 -41
  1032. package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
  1033. package/src/utils/shared-constructs-constants.d.ts +1 -0
  1034. package/src/utils/shared-constructs-constants.js +16 -15
  1035. package/src/utils/shared-constructs-constants.js.map +1 -1
  1036. package/src/utils/shared-constructs.d.ts +2 -2
  1037. package/src/utils/shared-constructs.js +60 -67
  1038. package/src/utils/shared-constructs.js.map +1 -1
  1039. package/src/utils/shared-dynamodb-scripts.d.ts +11 -0
  1040. package/src/utils/shared-dynamodb-scripts.js +25 -0
  1041. package/src/utils/shared-dynamodb-scripts.js.map +1 -0
  1042. package/src/utils/shared-infra-config.d.ts +1 -1
  1043. package/src/utils/shared-infra-config.js +31 -30
  1044. package/src/utils/shared-infra-config.js.map +1 -1
  1045. package/src/utils/shared-infra-scripts.d.ts +11 -0
  1046. package/src/utils/shared-infra-scripts.js +42 -0
  1047. package/src/utils/shared-infra-scripts.js.map +1 -0
  1048. package/src/utils/shared-rdb-scripts.d.ts +16 -0
  1049. package/src/utils/shared-rdb-scripts.js +32 -0
  1050. package/src/utils/shared-rdb-scripts.js.map +1 -0
  1051. package/src/utils/shared-scripts.d.ts +2 -5
  1052. package/src/utils/shared-scripts.js +12 -38
  1053. package/src/utils/shared-scripts.js.map +1 -1
  1054. package/src/utils/shared-shadcn.d.ts +1 -1
  1055. package/src/utils/shared-shadcn.js +65 -71
  1056. package/src/utils/shared-shadcn.js.map +1 -1
  1057. package/src/utils/test.d.ts +15 -1
  1058. package/src/utils/test.js +41 -23
  1059. package/src/utils/test.js.map +1 -1
  1060. package/src/utils/toml.d.ts +1 -1
  1061. package/src/utils/toml.js +10 -14
  1062. package/src/utils/toml.js.map +1 -1
  1063. package/src/utils/versions.d.ts +150 -97
  1064. package/src/utils/versions.js +157 -115
  1065. package/src/utils/versions.js.map +1 -1
  1066. package/src/utils/warm-ruff-cache.d.ts +12 -0
  1067. package/src/utils/warm-ruff-cache.js +39 -0
  1068. package/src/utils/warm-ruff-cache.js.map +1 -0
  1069. package/src/utils/website-constructs/files/cdk/app/static-websites/__websiteNameKebabCase__.ts.template +2 -2
  1070. package/src/utils/website-constructs/files/cdk/core/static-website.ts.template +200 -41
  1071. package/src/utils/website-constructs/files/terraform/app/static-websites/__websiteNameKebabCase__/__websiteNameKebabCase__.tf.template +1 -1
  1072. package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +145 -93
  1073. package/src/utils/website-constructs/website-constructs.d.ts +2 -2
  1074. package/src/utils/website-constructs/website-constructs.js +38 -30
  1075. package/src/utils/website-constructs/website-constructs.js.map +1 -1
  1076. package/bin/aws-nx-mcp.js +0 -17
  1077. package/bin/aws-nx-mcp.js.map +0 -1
  1078. package/sdk/connection.d.ts +0 -6
  1079. package/sdk/connection.js +0 -10
  1080. package/sdk/connection.js.map +0 -1
  1081. package/sdk/open-api.d.ts +0 -10
  1082. package/sdk/open-api.js +0 -15
  1083. package/sdk/open-api.js.map +0 -1
  1084. package/sdk/py.d.ts +0 -14
  1085. package/sdk/py.js +0 -18
  1086. package/sdk/py.js.map +0 -1
  1087. package/sdk/terraform.d.ts +0 -6
  1088. package/sdk/terraform.js +0 -11
  1089. package/sdk/terraform.js.map +0 -1
  1090. package/sdk/ts.d.ts +0 -29
  1091. package/sdk/ts.js +0 -47
  1092. package/sdk/ts.js.map +0 -1
  1093. package/sdk/utils/ast.js +0 -12
  1094. package/sdk/utils/ast.js.map +0 -1
  1095. package/sdk/utils/format.js +0 -10
  1096. package/sdk/utils/format.js.map +0 -1
  1097. package/sdk/utils/test.js +0 -10
  1098. package/sdk/utils/test.js.map +0 -1
  1099. package/src/connection/agent-serve-local.js +0 -48
  1100. package/src/connection/agent-serve-local.js.map +0 -1
  1101. package/src/connection/serve-local.d.ts +0 -15
  1102. package/src/connection/serve-local.js +0 -41
  1103. package/src/connection/serve-local.js.map +0 -1
  1104. package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client.py.template +0 -22
  1105. package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client.py.template +0 -22
  1106. package/src/py/agent/react-connection/serve-local.js +0 -30
  1107. package/src/py/agent/react-connection/serve-local.js.map +0 -1
  1108. package/src/py/agent/scripts/http/chat.ts.template +0 -38
  1109. package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client.ts.template +0 -19
  1110. package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client.ts.template +0 -19
  1111. package/src/ts/agent/react-connection/serve-local.d.ts +0 -13
  1112. package/src/ts/agent/react-connection/serve-local.js +0 -19
  1113. package/src/ts/agent/react-connection/serve-local.js.map +0 -1
  1114. package/src/ts/agent/scripts/http/chat.ts.template +0 -35
  1115. package/src/ts/dynamodb/files/scripts/pull-image.ts.template +0 -15
  1116. package/src/ts/dynamodb/files/scripts/start-container.ts.template +0 -81
  1117. package/src/ts/dynamodb/files/src/constants.ts.template +0 -9
  1118. package/src/ts/dynamodb/files/src/gsi.ts.template +0 -14
  1119. package/src/ts/lib/eslint.d.ts +0 -14
  1120. package/src/ts/lib/eslint.js +0 -90
  1121. package/src/ts/lib/eslint.js.map +0 -1
  1122. package/src/ts/lib/grit/eslint-dependency-checks-warn.grit +0 -1
  1123. package/src/ts/rdb/files/scripts/docker-pull.ts.template +0 -15
  1124. package/src/ts/rdb/files/scripts/docker-start.ts.template +0 -84
  1125. package/src/ts/rdb/files/scripts/wait-for-db.ts.template +0 -55
  1126. package/src/ts/rdb/files/src/constants.ts.template +0 -8
  1127. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client.ts.template +0 -123
  1128. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-client.ts.template +0 -128
  1129. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client.py.template +0 -120
  1130. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_client.py.template +0 -89
  1131. package/src/utils/files/common/scripts/src/infra-deploy.ts.template +0 -2
  1132. package/src/utils/files/common/scripts/src/infra-destroy.ts.template +0 -2
  1133. package/src/utils/files/terraform/scripts/reset-runtime-config.ts.template +0 -25
  1134. /package/{bin → src/bin}/aws-nx-mcp.d.ts +0 -0
  1135. /package/src/utils/agent-connection/files/{py-core-runtime-config/with_session_id.py.template → py-core-strands/base/with_session_id_strands.py.template} +0 -0
  1136. /package/src/utils/files/common/scripts/src/{index.ts.template → infra/index.ts.template} +0 -0
  1137. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/credentials.ts.template +0 -0
  1138. /package/src/utils/files/common/scripts/src/{stage-credentials → infra/stage-credentials}/stage-parser.ts.template +0 -0
@@ -281,7 +281,7 @@ import { EchoInputSchema, EchoOutputSchema } from '../schema/index.js';
281
281
  export const echo = publicProcedure
282
282
  .input(EchoInputSchema)
283
283
  .output(EchoOutputSchema)
284
- .query((opts) => ({ result: opts.input.message }));
284
+ .query((opts) => ({ message: opts.input.message }));
285
285
  "
286
286
  `;
287
287
 
@@ -303,13 +303,13 @@ exports[`trpc backend generator > should generate the project > apps/test-api/sr
303
303
  "import { z } from 'zod';
304
304
 
305
305
  export const EchoInputSchema = z.object({
306
- message: z.string(),
306
+ message: z.string().max(1024),
307
307
  });
308
308
 
309
309
  export type IEchoInput = z.TypeOf<typeof EchoInputSchema>;
310
310
 
311
311
  export const EchoOutputSchema = z.object({
312
- result: z.string(),
312
+ message: z.string().max(1024),
313
313
  });
314
314
 
315
315
  export type IEchoOutput = z.TypeOf<typeof EchoOutputSchema>;
@@ -478,6 +478,9 @@ export class TestApi<
478
478
  authorizer: new CognitoUserPoolsAuthorizer(scope, 'TestApiAuthorizer', {
479
479
  cognitoUserPools: [props.identity.userPool],
480
480
  }),
481
+ // Accept access tokens from both sign-in flows: 'openid' (Cognito hosted UI)
482
+ // and 'aws.cognito.signin.user.admin' (Cognito admin/SRP auth APIs).
483
+ authorizationScopes: ['openid', 'aws.cognito.signin.user.admin'],
481
484
  },
482
485
  deployOptions: {
483
486
  tracingEnabled: true,
@@ -1199,15 +1202,18 @@ import {
1199
1202
  HttpApiIntegration,
1200
1203
  OperationDetails,
1201
1204
  } from './utils.js';
1202
- import { CfnOutput } from 'aws-cdk-lib';
1205
+ import { CfnOutput, Stack } from 'aws-cdk-lib';
1203
1206
  import {
1204
1207
  HttpApi as _HttpApi,
1205
1208
  HttpApiProps as _HttpApiProps,
1206
1209
  HttpMethod,
1207
1210
  HttpStage,
1208
1211
  LogGroupLogDestination,
1212
+ ThrottleSettings,
1209
1213
  } from 'aws-cdk-lib/aws-apigatewayv2';
1210
1214
  import { LogGroup } from 'aws-cdk-lib/aws-logs';
1215
+ import { Key } from 'aws-cdk-lib/aws-kms';
1216
+ import { ServicePrincipal } from 'aws-cdk-lib/aws-iam';
1211
1217
  import { suppressRules } from '../checkov.js';
1212
1218
 
1213
1219
  /**
@@ -1232,6 +1238,12 @@ export interface HttpApiProps<
1232
1238
  * Map of operation names to their API Gateway integrations
1233
1239
  */
1234
1240
  readonly integrations: TIntegrations;
1241
+ /**
1242
+ * Default throttling limits applied to the API's default stage.
1243
+ *
1244
+ * @default { rateLimit: 10000, burstLimit: 5000 }
1245
+ */
1246
+ readonly throttle?: ThrottleSettings;
1235
1247
  }
1236
1248
 
1237
1249
  /**
@@ -1265,6 +1277,7 @@ export class HttpApi<
1265
1277
  apiName,
1266
1278
  operations,
1267
1279
  integrations,
1280
+ throttle = { rateLimit: 10000, burstLimit: 5000 },
1268
1281
  ...props
1269
1282
  }: HttpApiProps<TIntegrations, TOperation>,
1270
1283
  ) {
@@ -1277,12 +1290,18 @@ export class HttpApi<
1277
1290
  ...props,
1278
1291
  });
1279
1292
 
1280
- const accessLogGroup = new LogGroup(this, 'AccessLogs');
1281
- suppressRules(
1282
- accessLogGroup,
1283
- ['CKV_AWS_158'],
1284
- 'Using default CloudWatch log encryption',
1293
+ // Customer-managed key for access log encryption at rest
1294
+ const logsKey = new Key(this, 'AccessLogsKey', {
1295
+ enableKeyRotation: true,
1296
+ });
1297
+ const stack = Stack.of(this);
1298
+ logsKey.grantEncryptDecrypt(
1299
+ new ServicePrincipal(\`logs.\${stack.region}.amazonaws.com\`),
1285
1300
  );
1301
+
1302
+ const accessLogGroup = new LogGroup(this, 'AccessLogs', {
1303
+ encryptionKey: logsKey,
1304
+ });
1286
1305
  suppressRules(
1287
1306
  accessLogGroup,
1288
1307
  ['CKV_AWS_66', 'CKV_AWS_338'],
@@ -1292,6 +1311,7 @@ export class HttpApi<
1292
1311
  this.defaultStage = new HttpStage(this, 'DefaultStage', {
1293
1312
  httpApi: this.api,
1294
1313
  autoDeploy: true,
1314
+ throttle,
1295
1315
  accessLogSettings: {
1296
1316
  destination: new LogGroupLogDestination(accessLogGroup),
1297
1317
  },
@@ -1751,6 +1771,8 @@ export type ApiIntegrations<TOperation extends string, TBaseIntegration> =
1751
1771
  * @template TDefaultIntegrationProps - Type for default integration properties
1752
1772
  * @template TDefaultIntegration - Type for default integration implementation
1753
1773
  * @template TPattern - The integration pattern ('shared' or 'isolated')
1774
+ * @template TOverridden - Union of operation names that have been overridden
1775
+ * @template TOperationOptioned - Union of operation names with per-operation options
1754
1776
  */
1755
1777
  export class IntegrationBuilder<
1756
1778
  TOperation extends string,
@@ -1759,6 +1781,8 @@ export class IntegrationBuilder<
1759
1781
  TDefaultIntegrationProps extends object,
1760
1782
  TDefaultIntegration extends TBaseIntegration,
1761
1783
  TPattern extends 'shared' | 'isolated',
1784
+ TOverridden extends string = never,
1785
+ TOperationOptioned extends string = never,
1762
1786
  > {
1763
1787
  /** Options for the integration builder */
1764
1788
  private options: IntegrationBuilderProps<
@@ -1771,6 +1795,11 @@ export class IntegrationBuilder<
1771
1795
  /** Map of operation names to their custom integrations */
1772
1796
  private integrations: Partial<TIntegrations> = {};
1773
1797
 
1798
+ /** Map of default integration keys to per-operation default option overrides */
1799
+ private perOperationOptions: Partial<
1800
+ Record<string, Partial<TDefaultIntegrationProps>>
1801
+ > = {};
1802
+
1774
1803
  /**
1775
1804
  * Create an Integration Builder for an HTTP API with a shared pattern
1776
1805
  */
@@ -1925,11 +1954,16 @@ export class IntegrationBuilder<
1925
1954
  /**
1926
1955
  * Overrides default integrations with custom implementations for specific operations.
1927
1956
  *
1957
+ * Operations which have per-operation options set via withOperationOptions cannot be
1958
+ * overridden, since these still use the default integration.
1959
+ *
1928
1960
  * @param overrides - Map of operation names to their custom integration implementations
1929
1961
  * @returns The builder instance with updated type information reflecting the overrides
1930
1962
  */
1931
1963
  public withOverrides<
1932
- TOverrideIntegrations extends Partial<Record<TOperation, TBaseIntegration>>,
1964
+ TOverrideIntegrations extends Partial<
1965
+ Record<Exclude<TOperation, TOperationOptioned>, TBaseIntegration>
1966
+ >,
1933
1967
  >(overrides: TOverrideIntegrations) {
1934
1968
  this.integrations = { ...this.integrations, ...overrides };
1935
1969
  // Re-type to include the overridden integration types.
@@ -1945,7 +1979,9 @@ export class IntegrationBuilder<
1945
1979
  MergedIntegrations,
1946
1980
  TDefaultIntegrationProps,
1947
1981
  TDefaultIntegration,
1948
- TPattern
1982
+ TPattern,
1983
+ TOverridden | Extract<keyof TOverrideIntegrations, string>,
1984
+ TOperationOptioned
1949
1985
  >;
1950
1986
  }
1951
1987
 
@@ -1964,6 +2000,43 @@ export class IntegrationBuilder<
1964
2000
  return this;
1965
2001
  }
1966
2002
 
2003
+ /**
2004
+ * Updates the default integration options for specific operations, without
2005
+ * affecting the others. The given options are merged with the defaults (and
2006
+ * any options set via withDefaultOptions) when building each default integration.
2007
+ *
2008
+ * Operations which have been replaced via withOverrides cannot be targeted, since
2009
+ * they no longer use the default integration.
2010
+ *
2011
+ * @param options - Map of operation names to partial default integration options
2012
+ * @returns The builder instance
2013
+ */
2014
+ public withOperationOptions<
2015
+ TOptions extends Partial<
2016
+ Record<
2017
+ Exclude<DefaultIntegrationKeys<TPattern, TOperation>, TOverridden>,
2018
+ Partial<TDefaultIntegrationProps>
2019
+ >
2020
+ >,
2021
+ >(options: TOptions) {
2022
+ Object.entries(options).forEach(([op, opOptions]) => {
2023
+ this.perOperationOptions[op] = {
2024
+ ...this.perOperationOptions[op],
2025
+ ...(opOptions as Partial<TDefaultIntegrationProps>),
2026
+ };
2027
+ });
2028
+ return this as unknown as IntegrationBuilder<
2029
+ TOperation,
2030
+ TBaseIntegration,
2031
+ TIntegrations,
2032
+ TDefaultIntegrationProps,
2033
+ TDefaultIntegration,
2034
+ TPattern,
2035
+ TOverridden,
2036
+ TOperationOptioned | Extract<keyof TOptions, string>
2037
+ >;
2038
+ }
2039
+
1967
2040
  /**
1968
2041
  * Builds and returns the complete set of integrations.
1969
2042
  *
@@ -1978,6 +2051,10 @@ export class IntegrationBuilder<
1978
2051
  */
1979
2052
  public build(): TIntegrations {
1980
2053
  const options = this.options;
2054
+ const buildOptionsFor = (op: string): TDefaultIntegrationProps => ({
2055
+ ...options.defaultIntegrationOptions,
2056
+ ...this.perOperationOptions[op],
2057
+ });
1981
2058
  return {
1982
2059
  ...Object.fromEntries(
1983
2060
  options.pattern === 'shared'
@@ -1986,7 +2063,7 @@ export class IntegrationBuilder<
1986
2063
  '$router',
1987
2064
  options.buildDefaultIntegration(
1988
2065
  '$router',
1989
- options.defaultIntegrationOptions,
2066
+ buildOptionsFor('$router'),
1990
2067
  ),
1991
2068
  ],
1992
2069
  ]
@@ -1997,10 +2074,7 @@ export class IntegrationBuilder<
1997
2074
  )
1998
2075
  .map((op) => [
1999
2076
  op,
2000
- options.buildDefaultIntegration(
2001
- op,
2002
- options.defaultIntegrationOptions,
2003
- ),
2077
+ options.buildDefaultIntegration(op, buildOptionsFor(op)),
2004
2078
  ]),
2005
2079
  ),
2006
2080
  ...this.integrations,
@@ -2013,21 +2087,27 @@ export class IntegrationBuilder<
2013
2087
  exports[`trpc backend generator > should set up shared constructs for rest > rest-api.ts 1`] = `
2014
2088
  "import { Construct, IConstruct } from 'constructs';
2015
2089
  import {
2090
+ AccessLogFormat,
2016
2091
  Cors,
2092
+ LogGroupLogDestination,
2017
2093
  Resource,
2018
2094
  RestApi as _RestApi,
2019
2095
  RestApiProps as _RestApiProps,
2020
2096
  IResource,
2021
2097
  Stage,
2098
+ ThrottleSettings,
2022
2099
  } from 'aws-cdk-lib/aws-apigateway';
2023
- import { IAspect, RemovalPolicy } from 'aws-cdk-lib';
2100
+ import { IAspect, Stack } from 'aws-cdk-lib';
2024
2101
  import {
2025
2102
  CfnLoggingConfiguration,
2026
2103
  CfnWebACL,
2027
2104
  CfnWebACLAssociation,
2028
2105
  } from 'aws-cdk-lib/aws-wafv2';
2029
2106
  import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs';
2107
+ import { Key } from 'aws-cdk-lib/aws-kms';
2108
+ import { ServicePrincipal } from 'aws-cdk-lib/aws-iam';
2030
2109
  import { RuntimeConfig } from '../runtime-config.js';
2110
+ import { ApiGatewayAccount } from './api-gateway-account.js';
2031
2111
  import {
2032
2112
  ApiIntegrations,
2033
2113
  OperationDetails,
@@ -2065,6 +2145,12 @@ export interface RestApiProps<
2065
2145
  * @default true
2066
2146
  */
2067
2147
  readonly enableWaf?: boolean;
2148
+ /**
2149
+ * Default throttling limits applied to all methods on the API's default stage.
2150
+ *
2151
+ * @default { rateLimit: 10000, burstLimit: 5000 }
2152
+ */
2153
+ readonly throttle?: ThrottleSettings;
2068
2154
  }
2069
2155
 
2070
2156
  /**
@@ -2099,14 +2185,49 @@ export class RestApi<
2099
2185
  operations,
2100
2186
  integrations,
2101
2187
  enableWaf = true,
2188
+ throttle = { rateLimit: 10000, burstLimit: 5000 },
2102
2189
  ...props
2103
2190
  }: RestApiProps<TIntegrations, TOperation>,
2104
2191
  ) {
2105
2192
  super(scope, id);
2106
2193
  this.integrations = integrations;
2107
2194
 
2195
+ // Account-level CloudWatch role required for REST API access logging
2196
+ const account = ApiGatewayAccount.ensure(this);
2197
+
2198
+ // KMS key for encrypting logs at rest, usable by CloudWatch Logs
2199
+ const logsKey = new Key(this, 'LogsKey', {
2200
+ enableKeyRotation: true,
2201
+ });
2202
+ logsKey.grantEncryptDecrypt(
2203
+ new ServicePrincipal(\`logs.\${Stack.of(this).region}.amazonaws.com\`),
2204
+ );
2205
+
2206
+ const accessLogs = new LogGroup(this, 'AccessLogs', {
2207
+ retention: RetentionDays.ONE_YEAR,
2208
+ encryptionKey: logsKey,
2209
+ });
2210
+
2108
2211
  // Create the API Gateway REST API
2109
- this.api = new _RestApi(this, 'Api', props);
2212
+ this.api = new _RestApi(this, 'Api', {
2213
+ ...props,
2214
+ deployOptions: {
2215
+ accessLogDestination: new LogGroupLogDestination(accessLogs),
2216
+ accessLogFormat: AccessLogFormat.jsonWithStandardFields(),
2217
+ ...props.deployOptions,
2218
+ methodOptions: {
2219
+ ...props.deployOptions?.methodOptions,
2220
+ // Default throttling applied to all resource paths and methods
2221
+ '/*/*': {
2222
+ throttlingRateLimit: throttle.rateLimit,
2223
+ throttlingBurstLimit: throttle.burstLimit,
2224
+ ...props.deployOptions?.methodOptions?.['/*/*'],
2225
+ },
2226
+ },
2227
+ },
2228
+ });
2229
+ // Ensure the account-level role is configured before the stage is created
2230
+ this.api.deploymentStage.node.addDependency(account.resource);
2110
2231
 
2111
2232
  if (enableWaf) {
2112
2233
  this.webAcl = new CfnWebACL(this, 'WebAcl', {
@@ -2173,14 +2294,9 @@ export class RestApi<
2173
2294
  // \`aws-waf-logs-\` to satisfy the WAFv2 logging destination requirement.
2174
2295
  const wafLogGroup = new LogGroup(this, 'WebAclLogs', {
2175
2296
  logGroupName: \`aws-waf-logs-\${apiName}-\${this.node.addr.slice(-8)}\`,
2176
- retention: RetentionDays.ONE_MONTH,
2177
- removalPolicy: RemovalPolicy.DESTROY,
2297
+ retention: RetentionDays.ONE_YEAR,
2298
+ encryptionKey: logsKey,
2178
2299
  });
2179
- suppressRules(
2180
- wafLogGroup,
2181
- ['CKV_AWS_158'],
2182
- 'Using default CloudWatch log encryption for WAF logs',
2183
- );
2184
2300
 
2185
2301
  new CfnLoggingConfiguration(this, 'WebAclLoggingConfig', {
2186
2302
  resourceArn: this.webAcl.attrArn,
@@ -2194,12 +2310,6 @@ export class RestApi<
2194
2310
  'Caching not required for this use case',
2195
2311
  (c) => c instanceof Stage,
2196
2312
  );
2197
- suppressRules(
2198
- this.api,
2199
- ['CKV_AWS_76'],
2200
- 'API Gateway access logging disabled due to account-level CloudWatch Logs role ARN requirement',
2201
- (c) => c instanceof Stage,
2202
- );
2203
2313
 
2204
2314
  // Resolve the integration for a given operation.
2205
2315
  // If the operation has a dedicated integration, use it; otherwise fall back to $router.
@@ -2708,6 +2818,8 @@ export type ApiIntegrations<TOperation extends string, TBaseIntegration> =
2708
2818
  * @template TDefaultIntegrationProps - Type for default integration properties
2709
2819
  * @template TDefaultIntegration - Type for default integration implementation
2710
2820
  * @template TPattern - The integration pattern ('shared' or 'isolated')
2821
+ * @template TOverridden - Union of operation names that have been overridden
2822
+ * @template TOperationOptioned - Union of operation names with per-operation options
2711
2823
  */
2712
2824
  export class IntegrationBuilder<
2713
2825
  TOperation extends string,
@@ -2716,6 +2828,8 @@ export class IntegrationBuilder<
2716
2828
  TDefaultIntegrationProps extends object,
2717
2829
  TDefaultIntegration extends TBaseIntegration,
2718
2830
  TPattern extends 'shared' | 'isolated',
2831
+ TOverridden extends string = never,
2832
+ TOperationOptioned extends string = never,
2719
2833
  > {
2720
2834
  /** Options for the integration builder */
2721
2835
  private options: IntegrationBuilderProps<
@@ -2728,6 +2842,11 @@ export class IntegrationBuilder<
2728
2842
  /** Map of operation names to their custom integrations */
2729
2843
  private integrations: Partial<TIntegrations> = {};
2730
2844
 
2845
+ /** Map of default integration keys to per-operation default option overrides */
2846
+ private perOperationOptions: Partial<
2847
+ Record<string, Partial<TDefaultIntegrationProps>>
2848
+ > = {};
2849
+
2731
2850
  /**
2732
2851
  * Create an Integration Builder for an HTTP API with a shared pattern
2733
2852
  */
@@ -2882,11 +3001,16 @@ export class IntegrationBuilder<
2882
3001
  /**
2883
3002
  * Overrides default integrations with custom implementations for specific operations.
2884
3003
  *
3004
+ * Operations which have per-operation options set via withOperationOptions cannot be
3005
+ * overridden, since these still use the default integration.
3006
+ *
2885
3007
  * @param overrides - Map of operation names to their custom integration implementations
2886
3008
  * @returns The builder instance with updated type information reflecting the overrides
2887
3009
  */
2888
3010
  public withOverrides<
2889
- TOverrideIntegrations extends Partial<Record<TOperation, TBaseIntegration>>,
3011
+ TOverrideIntegrations extends Partial<
3012
+ Record<Exclude<TOperation, TOperationOptioned>, TBaseIntegration>
3013
+ >,
2890
3014
  >(overrides: TOverrideIntegrations) {
2891
3015
  this.integrations = { ...this.integrations, ...overrides };
2892
3016
  // Re-type to include the overridden integration types.
@@ -2902,7 +3026,9 @@ export class IntegrationBuilder<
2902
3026
  MergedIntegrations,
2903
3027
  TDefaultIntegrationProps,
2904
3028
  TDefaultIntegration,
2905
- TPattern
3029
+ TPattern,
3030
+ TOverridden | Extract<keyof TOverrideIntegrations, string>,
3031
+ TOperationOptioned
2906
3032
  >;
2907
3033
  }
2908
3034
 
@@ -2921,6 +3047,43 @@ export class IntegrationBuilder<
2921
3047
  return this;
2922
3048
  }
2923
3049
 
3050
+ /**
3051
+ * Updates the default integration options for specific operations, without
3052
+ * affecting the others. The given options are merged with the defaults (and
3053
+ * any options set via withDefaultOptions) when building each default integration.
3054
+ *
3055
+ * Operations which have been replaced via withOverrides cannot be targeted, since
3056
+ * they no longer use the default integration.
3057
+ *
3058
+ * @param options - Map of operation names to partial default integration options
3059
+ * @returns The builder instance
3060
+ */
3061
+ public withOperationOptions<
3062
+ TOptions extends Partial<
3063
+ Record<
3064
+ Exclude<DefaultIntegrationKeys<TPattern, TOperation>, TOverridden>,
3065
+ Partial<TDefaultIntegrationProps>
3066
+ >
3067
+ >,
3068
+ >(options: TOptions) {
3069
+ Object.entries(options).forEach(([op, opOptions]) => {
3070
+ this.perOperationOptions[op] = {
3071
+ ...this.perOperationOptions[op],
3072
+ ...(opOptions as Partial<TDefaultIntegrationProps>),
3073
+ };
3074
+ });
3075
+ return this as unknown as IntegrationBuilder<
3076
+ TOperation,
3077
+ TBaseIntegration,
3078
+ TIntegrations,
3079
+ TDefaultIntegrationProps,
3080
+ TDefaultIntegration,
3081
+ TPattern,
3082
+ TOverridden,
3083
+ TOperationOptioned | Extract<keyof TOptions, string>
3084
+ >;
3085
+ }
3086
+
2924
3087
  /**
2925
3088
  * Builds and returns the complete set of integrations.
2926
3089
  *
@@ -2935,6 +3098,10 @@ export class IntegrationBuilder<
2935
3098
  */
2936
3099
  public build(): TIntegrations {
2937
3100
  const options = this.options;
3101
+ const buildOptionsFor = (op: string): TDefaultIntegrationProps => ({
3102
+ ...options.defaultIntegrationOptions,
3103
+ ...this.perOperationOptions[op],
3104
+ });
2938
3105
  return {
2939
3106
  ...Object.fromEntries(
2940
3107
  options.pattern === 'shared'
@@ -2943,7 +3110,7 @@ export class IntegrationBuilder<
2943
3110
  '$router',
2944
3111
  options.buildDefaultIntegration(
2945
3112
  '$router',
2946
- options.defaultIntegrationOptions,
3113
+ buildOptionsFor('$router'),
2947
3114
  ),
2948
3115
  ],
2949
3116
  ]
@@ -2954,10 +3121,7 @@ export class IntegrationBuilder<
2954
3121
  )
2955
3122
  .map((op) => [
2956
3123
  op,
2957
- options.buildDefaultIntegration(
2958
- op,
2959
- options.defaultIntegrationOptions,
2960
- ),
3124
+ options.buildDefaultIntegration(op, buildOptionsFor(op)),
2961
3125
  ]),
2962
3126
  ),
2963
3127
  ...this.integrations,
@@ -2978,7 +3142,7 @@ terraform {
2978
3142
  required_providers {
2979
3143
  aws = {
2980
3144
  source = "hashicorp/aws"
2981
- version = "~> 6.0"
3145
+ version = "6.54.0"
2982
3146
  }
2983
3147
  }
2984
3148
  }
@@ -3225,7 +3389,7 @@ output "api_log_group_arn" {
3225
3389
  required_providers {
3226
3390
  aws = {
3227
3391
  source = "hashicorp/aws"
3228
- version = "~> 6.0"
3392
+ version = "6.54.0"
3229
3393
  }
3230
3394
  }
3231
3395
  }
@@ -3257,11 +3421,47 @@ variable "additional_iam_policy_statements" {
3257
3421
  default = []
3258
3422
  }
3259
3423
 
3424
+ variable "appconfig_application_id" {
3425
+ description = "ID of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_id\`). When set, the Lambda functions receive \`RUNTIME_CONFIG_APP_ID\` and read access to the application."
3426
+ type = string
3427
+ default = null
3428
+ }
3429
+
3430
+ variable "appconfig_application_arn" {
3431
+ description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the Lambda functions."
3432
+ type = string
3433
+ default = null
3434
+ }
3435
+
3260
3436
  variable "asset_bucket_name" {
3261
3437
  description = "Name of the shared asset S3 bucket used to stage the Lambda deployment zip. Instantiate the \`core/asset-bucket\` module once per deployment and pass its \`bucket_name\` output here."
3262
3438
  type = string
3263
3439
  }
3264
3440
 
3441
+ # VPC Configuration (optional)
3442
+ variable "enable_vpc" {
3443
+ description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
3444
+ type = bool
3445
+ default = false
3446
+ }
3447
+
3448
+ variable "vpc_id" {
3449
+ description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
3450
+ type = string
3451
+ default = null
3452
+
3453
+ validation {
3454
+ condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
3455
+ error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
3456
+ }
3457
+ }
3458
+
3459
+ variable "subnet_ids" {
3460
+ description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
3461
+ type = list(string)
3462
+ default = null
3463
+ }
3464
+
3265
3465
  # CORS Configuration (passed to core module)
3266
3466
  variable "cors_allow_credentials" {
3267
3467
  description = "Whether to allow credentials in CORS requests"
@@ -3293,12 +3493,6 @@ variable "cors_expose_headers" {
3293
3493
  default = []
3294
3494
  }
3295
3495
 
3296
- variable "cors_max_age" {
3297
- description = "Maximum age for CORS preflight requests in seconds"
3298
- type = number
3299
- default = 0
3300
- }
3301
-
3302
3496
  # Tags
3303
3497
  variable "tags" {
3304
3498
  description = "Tags to apply to all resources"
@@ -3349,16 +3543,37 @@ module "http_api" {
3349
3543
  cors_allow_methods = var.cors_allow_methods
3350
3544
  cors_allow_origins = var.cors_allow_origins
3351
3545
  cors_expose_headers = var.cors_expose_headers
3352
- cors_max_age = var.cors_max_age
3353
3546
 
3354
3547
  # Tags
3355
3548
  tags = var.tags
3356
3549
  }
3357
3550
 
3551
+ # Security group for the API Lambda function, used when deployed into a VPC
3552
+ resource "aws_security_group" "api_lambda" {
3553
+ count = var.enable_vpc ? 1 : 0
3554
+
3555
+ #checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
3556
+ name_prefix = "test-api-lambda-"
3557
+ description = "Security group for the TestApi API Lambda function"
3558
+ vpc_id = var.vpc_id
3559
+ tags = var.tags
3560
+ }
3561
+
3562
+ resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
3563
+ count = var.enable_vpc ? 1 : 0
3564
+
3565
+ security_group_id = aws_security_group.api_lambda[0].id
3566
+ cidr_ipv4 = "0.0.0.0/0"
3567
+ from_port = 443
3568
+ to_port = 443
3569
+ ip_protocol = "tcp"
3570
+ description = "Allow outbound HTTPS to AWS service endpoints"
3571
+ }
3572
+
3358
3573
  # Lambda function
3359
3574
  # This configures a single "router" lambda to serve all requests
3360
3575
  resource "aws_lambda_function" "api_lambda" {
3361
- #checkov:skip=CKV_AWS_117:Lambda function does not need to be in VPC for this use case
3576
+ #checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
3362
3577
  #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
3363
3578
  #checkov:skip=CKV_AWS_272:Code signing not required for this use case
3364
3579
  #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
@@ -3380,13 +3595,25 @@ resource "aws_lambda_function" "api_lambda" {
3380
3595
  mode = "Active"
3381
3596
  }
3382
3597
 
3598
+ dynamic "vpc_config" {
3599
+ for_each = var.enable_vpc ? [1] : []
3600
+ content {
3601
+ subnet_ids = var.subnet_ids
3602
+ security_group_ids = [aws_security_group.api_lambda[0].id]
3603
+ }
3604
+ }
3605
+
3383
3606
 
3384
3607
  environment {
3385
3608
  variables = merge({
3386
- }, var.env)
3609
+ }, var.appconfig_application_id != null ? {
3610
+ RUNTIME_CONFIG_APP_ID = var.appconfig_application_id
3611
+ } : {}, var.env)
3387
3612
  }
3388
3613
 
3389
3614
  tags = var.tags
3615
+
3616
+ depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
3390
3617
  }
3391
3618
 
3392
3619
  # IAM role for Lambda execution
@@ -3421,18 +3648,39 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
3421
3648
  role = aws_iam_role.lambda_execution_role.name
3422
3649
  }
3423
3650
 
3651
+ # Attach VPC access policy to Lambda role when deployed into a VPC
3652
+ resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
3653
+ count = var.enable_vpc ? 1 : 0
3654
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
3655
+ role = aws_iam_role.lambda_execution_role.name
3656
+ }
3657
+
3424
3658
  # Additional IAM policies for Lambda (if provided)
3425
3659
  resource "aws_iam_role_policy" "lambda_additional_policies" {
3426
- count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
3660
+ count = length(local.lambda_policy_statements) > 0 ? 1 : 0
3427
3661
  name = "TestApiHandler-additional-policies-\${random_string.suffix.result}"
3428
3662
  role = aws_iam_role.lambda_execution_role.id
3429
3663
 
3430
3664
  policy = jsonencode({
3431
3665
  Version = "2012-10-17"
3432
- Statement = var.additional_iam_policy_statements
3666
+ Statement = local.lambda_policy_statements
3433
3667
  })
3434
3668
  }
3435
3669
 
3670
+ locals {
3671
+ # Grant read access to the runtime-config AppConfig application when wired
3672
+ lambda_policy_statements = concat(var.appconfig_application_arn != null ? [
3673
+ {
3674
+ Effect = "Allow"
3675
+ Action = [
3676
+ "appconfig:StartConfigurationSession",
3677
+ "appconfig:GetLatestConfiguration"
3678
+ ]
3679
+ Resource = ["\${var.appconfig_application_arn}/*"]
3680
+ }
3681
+ ] : [], var.additional_iam_policy_statements)
3682
+ }
3683
+
3436
3684
  # CloudWatch Log Group for Lambda
3437
3685
  resource "aws_cloudwatch_log_group" "lambda_logs" {
3438
3686
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -3591,6 +3839,11 @@ output "lambda_execution_role_name" {
3591
3839
  value = aws_iam_role.lambda_execution_role.name
3592
3840
  }
3593
3841
 
3842
+ output "security_group_id" {
3843
+ description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
3844
+ value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
3845
+ }
3846
+
3594
3847
  # Integration Outputs
3595
3848
  output "integration_id" {
3596
3849
  description = "ID of the Lambda integration"
@@ -3631,7 +3884,7 @@ terraform {
3631
3884
  required_providers {
3632
3885
  aws = {
3633
3886
  source = "hashicorp/aws"
3634
- version = "~> 6.0"
3887
+ version = "6.54.0"
3635
3888
  }
3636
3889
  }
3637
3890
  }
@@ -3878,7 +4131,7 @@ output "api_log_group_arn" {
3878
4131
  required_providers {
3879
4132
  aws = {
3880
4133
  source = "hashicorp/aws"
3881
- version = "~> 6.0"
4134
+ version = "6.54.0"
3882
4135
  }
3883
4136
  }
3884
4137
  }
@@ -3900,11 +4153,47 @@ variable "additional_iam_policy_statements" {
3900
4153
  default = []
3901
4154
  }
3902
4155
 
4156
+ variable "appconfig_application_id" {
4157
+ description = "ID of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_id\`). When set, the Lambda functions receive \`RUNTIME_CONFIG_APP_ID\` and read access to the application."
4158
+ type = string
4159
+ default = null
4160
+ }
4161
+
4162
+ variable "appconfig_application_arn" {
4163
+ description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the Lambda functions."
4164
+ type = string
4165
+ default = null
4166
+ }
4167
+
3903
4168
  variable "asset_bucket_name" {
3904
4169
  description = "Name of the shared asset S3 bucket used to stage the Lambda deployment zip. Instantiate the \`core/asset-bucket\` module once per deployment and pass its \`bucket_name\` output here."
3905
4170
  type = string
3906
4171
  }
3907
4172
 
4173
+ # VPC Configuration (optional)
4174
+ variable "enable_vpc" {
4175
+ description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
4176
+ type = bool
4177
+ default = false
4178
+ }
4179
+
4180
+ variable "vpc_id" {
4181
+ description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
4182
+ type = string
4183
+ default = null
4184
+
4185
+ validation {
4186
+ condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
4187
+ error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
4188
+ }
4189
+ }
4190
+
4191
+ variable "subnet_ids" {
4192
+ description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
4193
+ type = list(string)
4194
+ default = null
4195
+ }
4196
+
3908
4197
  # CORS Configuration (passed to core module)
3909
4198
  variable "cors_allow_credentials" {
3910
4199
  description = "Whether to allow credentials in CORS requests"
@@ -3936,12 +4225,6 @@ variable "cors_expose_headers" {
3936
4225
  default = []
3937
4226
  }
3938
4227
 
3939
- variable "cors_max_age" {
3940
- description = "Maximum age for CORS preflight requests in seconds"
3941
- type = number
3942
- default = 0
3943
- }
3944
-
3945
4228
  # Tags
3946
4229
  variable "tags" {
3947
4230
  description = "Tags to apply to all resources"
@@ -3992,16 +4275,37 @@ module "http_api" {
3992
4275
  cors_allow_methods = var.cors_allow_methods
3993
4276
  cors_allow_origins = var.cors_allow_origins
3994
4277
  cors_expose_headers = var.cors_expose_headers
3995
- cors_max_age = var.cors_max_age
3996
4278
 
3997
4279
  # Tags
3998
4280
  tags = var.tags
3999
4281
  }
4000
4282
 
4283
+ # Security group for the API Lambda function, used when deployed into a VPC
4284
+ resource "aws_security_group" "api_lambda" {
4285
+ count = var.enable_vpc ? 1 : 0
4286
+
4287
+ #checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
4288
+ name_prefix = "test-api-lambda-"
4289
+ description = "Security group for the TestApi API Lambda function"
4290
+ vpc_id = var.vpc_id
4291
+ tags = var.tags
4292
+ }
4293
+
4294
+ resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
4295
+ count = var.enable_vpc ? 1 : 0
4296
+
4297
+ security_group_id = aws_security_group.api_lambda[0].id
4298
+ cidr_ipv4 = "0.0.0.0/0"
4299
+ from_port = 443
4300
+ to_port = 443
4301
+ ip_protocol = "tcp"
4302
+ description = "Allow outbound HTTPS to AWS service endpoints"
4303
+ }
4304
+
4001
4305
  # Lambda function
4002
4306
  # This configures a single "router" lambda to serve all requests
4003
4307
  resource "aws_lambda_function" "api_lambda" {
4004
- #checkov:skip=CKV_AWS_117:Lambda function does not need to be in VPC for this use case
4308
+ #checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
4005
4309
  #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
4006
4310
  #checkov:skip=CKV_AWS_272:Code signing not required for this use case
4007
4311
  #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
@@ -4023,13 +4327,25 @@ resource "aws_lambda_function" "api_lambda" {
4023
4327
  mode = "Active"
4024
4328
  }
4025
4329
 
4330
+ dynamic "vpc_config" {
4331
+ for_each = var.enable_vpc ? [1] : []
4332
+ content {
4333
+ subnet_ids = var.subnet_ids
4334
+ security_group_ids = [aws_security_group.api_lambda[0].id]
4335
+ }
4336
+ }
4337
+
4026
4338
 
4027
4339
  environment {
4028
4340
  variables = merge({
4029
- }, var.env)
4341
+ }, var.appconfig_application_id != null ? {
4342
+ RUNTIME_CONFIG_APP_ID = var.appconfig_application_id
4343
+ } : {}, var.env)
4030
4344
  }
4031
4345
 
4032
4346
  tags = var.tags
4347
+
4348
+ depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
4033
4349
  }
4034
4350
 
4035
4351
  # IAM role for Lambda execution
@@ -4064,18 +4380,39 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
4064
4380
  role = aws_iam_role.lambda_execution_role.name
4065
4381
  }
4066
4382
 
4383
+ # Attach VPC access policy to Lambda role when deployed into a VPC
4384
+ resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
4385
+ count = var.enable_vpc ? 1 : 0
4386
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
4387
+ role = aws_iam_role.lambda_execution_role.name
4388
+ }
4389
+
4067
4390
  # Additional IAM policies for Lambda (if provided)
4068
4391
  resource "aws_iam_role_policy" "lambda_additional_policies" {
4069
- count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
4392
+ count = length(local.lambda_policy_statements) > 0 ? 1 : 0
4070
4393
  name = "TestApiHandler-additional-policies-\${random_string.suffix.result}"
4071
4394
  role = aws_iam_role.lambda_execution_role.id
4072
4395
 
4073
4396
  policy = jsonencode({
4074
4397
  Version = "2012-10-17"
4075
- Statement = var.additional_iam_policy_statements
4398
+ Statement = local.lambda_policy_statements
4076
4399
  })
4077
4400
  }
4078
4401
 
4402
+ locals {
4403
+ # Grant read access to the runtime-config AppConfig application when wired
4404
+ lambda_policy_statements = concat(var.appconfig_application_arn != null ? [
4405
+ {
4406
+ Effect = "Allow"
4407
+ Action = [
4408
+ "appconfig:StartConfigurationSession",
4409
+ "appconfig:GetLatestConfiguration"
4410
+ ]
4411
+ Resource = ["\${var.appconfig_application_arn}/*"]
4412
+ }
4413
+ ] : [], var.additional_iam_policy_statements)
4414
+ }
4415
+
4079
4416
  # CloudWatch Log Group for Lambda
4080
4417
  resource "aws_cloudwatch_log_group" "lambda_logs" {
4081
4418
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -4316,6 +4653,11 @@ output "lambda_execution_role_name" {
4316
4653
  value = aws_iam_role.lambda_execution_role.name
4317
4654
  }
4318
4655
 
4656
+ output "security_group_id" {
4657
+ description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
4658
+ value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
4659
+ }
4660
+
4319
4661
  # Integration Outputs
4320
4662
  output "integration_id" {
4321
4663
  description = "ID of the Lambda integration"
@@ -4356,7 +4698,7 @@ terraform {
4356
4698
  required_providers {
4357
4699
  aws = {
4358
4700
  source = "hashicorp/aws"
4359
- version = "~> 6.0"
4701
+ version = "6.54.0"
4360
4702
  }
4361
4703
  }
4362
4704
  }
@@ -4603,7 +4945,7 @@ output "api_log_group_arn" {
4603
4945
  required_providers {
4604
4946
  aws = {
4605
4947
  source = "hashicorp/aws"
4606
- version = "~> 6.0"
4948
+ version = "6.54.0"
4607
4949
  }
4608
4950
  }
4609
4951
  }
@@ -4625,11 +4967,47 @@ variable "additional_iam_policy_statements" {
4625
4967
  default = []
4626
4968
  }
4627
4969
 
4970
+ variable "appconfig_application_id" {
4971
+ description = "ID of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_id\`). When set, the Lambda functions receive \`RUNTIME_CONFIG_APP_ID\` and read access to the application."
4972
+ type = string
4973
+ default = null
4974
+ }
4975
+
4976
+ variable "appconfig_application_arn" {
4977
+ description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the Lambda functions."
4978
+ type = string
4979
+ default = null
4980
+ }
4981
+
4628
4982
  variable "asset_bucket_name" {
4629
4983
  description = "Name of the shared asset S3 bucket used to stage the Lambda deployment zip. Instantiate the \`core/asset-bucket\` module once per deployment and pass its \`bucket_name\` output here."
4630
4984
  type = string
4631
4985
  }
4632
4986
 
4987
+ # VPC Configuration (optional)
4988
+ variable "enable_vpc" {
4989
+ description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
4990
+ type = bool
4991
+ default = false
4992
+ }
4993
+
4994
+ variable "vpc_id" {
4995
+ description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
4996
+ type = string
4997
+ default = null
4998
+
4999
+ validation {
5000
+ condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
5001
+ error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
5002
+ }
5003
+ }
5004
+
5005
+ variable "subnet_ids" {
5006
+ description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
5007
+ type = list(string)
5008
+ default = null
5009
+ }
5010
+
4633
5011
  # CORS Configuration (passed to core module)
4634
5012
  variable "cors_allow_credentials" {
4635
5013
  description = "Whether to allow credentials in CORS requests"
@@ -4661,12 +5039,6 @@ variable "cors_expose_headers" {
4661
5039
  default = []
4662
5040
  }
4663
5041
 
4664
- variable "cors_max_age" {
4665
- description = "Maximum age for CORS preflight requests in seconds"
4666
- type = number
4667
- default = 0
4668
- }
4669
-
4670
5042
  # Tags
4671
5043
  variable "tags" {
4672
5044
  description = "Tags to apply to all resources"
@@ -4717,16 +5089,37 @@ module "http_api" {
4717
5089
  cors_allow_methods = var.cors_allow_methods
4718
5090
  cors_allow_origins = var.cors_allow_origins
4719
5091
  cors_expose_headers = var.cors_expose_headers
4720
- cors_max_age = var.cors_max_age
4721
5092
 
4722
5093
  # Tags
4723
5094
  tags = var.tags
4724
5095
  }
4725
5096
 
5097
+ # Security group for the API Lambda function, used when deployed into a VPC
5098
+ resource "aws_security_group" "api_lambda" {
5099
+ count = var.enable_vpc ? 1 : 0
5100
+
5101
+ #checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
5102
+ name_prefix = "test-api-lambda-"
5103
+ description = "Security group for the TestApi API Lambda function"
5104
+ vpc_id = var.vpc_id
5105
+ tags = var.tags
5106
+ }
5107
+
5108
+ resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
5109
+ count = var.enable_vpc ? 1 : 0
5110
+
5111
+ security_group_id = aws_security_group.api_lambda[0].id
5112
+ cidr_ipv4 = "0.0.0.0/0"
5113
+ from_port = 443
5114
+ to_port = 443
5115
+ ip_protocol = "tcp"
5116
+ description = "Allow outbound HTTPS to AWS service endpoints"
5117
+ }
5118
+
4726
5119
  # Lambda function
4727
5120
  # This configures a single "router" lambda to serve all requests
4728
5121
  resource "aws_lambda_function" "api_lambda" {
4729
- #checkov:skip=CKV_AWS_117:Lambda function does not need to be in VPC for this use case
5122
+ #checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
4730
5123
  #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
4731
5124
  #checkov:skip=CKV_AWS_272:Code signing not required for this use case
4732
5125
  #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
@@ -4748,13 +5141,25 @@ resource "aws_lambda_function" "api_lambda" {
4748
5141
  mode = "Active"
4749
5142
  }
4750
5143
 
5144
+ dynamic "vpc_config" {
5145
+ for_each = var.enable_vpc ? [1] : []
5146
+ content {
5147
+ subnet_ids = var.subnet_ids
5148
+ security_group_ids = [aws_security_group.api_lambda[0].id]
5149
+ }
5150
+ }
5151
+
4751
5152
 
4752
5153
  environment {
4753
5154
  variables = merge({
4754
- }, var.env)
5155
+ }, var.appconfig_application_id != null ? {
5156
+ RUNTIME_CONFIG_APP_ID = var.appconfig_application_id
5157
+ } : {}, var.env)
4755
5158
  }
4756
5159
 
4757
5160
  tags = var.tags
5161
+
5162
+ depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
4758
5163
  }
4759
5164
 
4760
5165
  # IAM role for Lambda execution
@@ -4789,18 +5194,39 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
4789
5194
  role = aws_iam_role.lambda_execution_role.name
4790
5195
  }
4791
5196
 
5197
+ # Attach VPC access policy to Lambda role when deployed into a VPC
5198
+ resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
5199
+ count = var.enable_vpc ? 1 : 0
5200
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
5201
+ role = aws_iam_role.lambda_execution_role.name
5202
+ }
5203
+
4792
5204
  # Additional IAM policies for Lambda (if provided)
4793
5205
  resource "aws_iam_role_policy" "lambda_additional_policies" {
4794
- count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
5206
+ count = length(local.lambda_policy_statements) > 0 ? 1 : 0
4795
5207
  name = "TestApiHandler-additional-policies-\${random_string.suffix.result}"
4796
5208
  role = aws_iam_role.lambda_execution_role.id
4797
5209
 
4798
5210
  policy = jsonencode({
4799
5211
  Version = "2012-10-17"
4800
- Statement = var.additional_iam_policy_statements
5212
+ Statement = local.lambda_policy_statements
4801
5213
  })
4802
5214
  }
4803
5215
 
5216
+ locals {
5217
+ # Grant read access to the runtime-config AppConfig application when wired
5218
+ lambda_policy_statements = concat(var.appconfig_application_arn != null ? [
5219
+ {
5220
+ Effect = "Allow"
5221
+ Action = [
5222
+ "appconfig:StartConfigurationSession",
5223
+ "appconfig:GetLatestConfiguration"
5224
+ ]
5225
+ Resource = ["\${var.appconfig_application_arn}/*"]
5226
+ }
5227
+ ] : [], var.additional_iam_policy_statements)
5228
+ }
5229
+
4804
5230
  # CloudWatch Log Group for Lambda
4805
5231
  resource "aws_cloudwatch_log_group" "lambda_logs" {
4806
5232
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -4946,6 +5372,11 @@ output "lambda_execution_role_name" {
4946
5372
  value = aws_iam_role.lambda_execution_role.name
4947
5373
  }
4948
5374
 
5375
+ output "security_group_id" {
5376
+ description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
5377
+ value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
5378
+ }
5379
+
4949
5380
  # Integration Outputs
4950
5381
  output "integration_id" {
4951
5382
  description = "ID of the Lambda integration"
@@ -4986,11 +5417,11 @@ terraform {
4986
5417
  required_providers {
4987
5418
  aws = {
4988
5419
  source = "hashicorp/aws"
4989
- version = "~> 6.33"
5420
+ version = "6.54.0"
4990
5421
  }
4991
5422
  random = {
4992
5423
  source = "hashicorp/random"
4993
- version = "~> 3.1"
5424
+ version = "3.9.0"
4994
5425
  }
4995
5426
  }
4996
5427
  }
@@ -5060,8 +5491,6 @@ data "aws_caller_identity" "current" {}
5060
5491
 
5061
5492
  # Resources
5062
5493
 
5063
- # Note: CloudWatch logging removed due to account-level CloudWatch Logs role ARN requirement
5064
-
5065
5494
  # REST API Gateway
5066
5495
  resource "aws_api_gateway_rest_api" "rest_api" {
5067
5496
  name = var.api_name
@@ -5078,10 +5507,8 @@ resource "aws_api_gateway_rest_api" "rest_api" {
5078
5507
  tags = var.tags
5079
5508
  }
5080
5509
 
5081
- # Note: Deployment and stage are created in the consuming module (e.g., foo-api.tf)
5082
- # after all methods and integrations are defined
5083
-
5084
- # Note: CloudWatch Log Group removed due to account-level CloudWatch Logs role ARN requirement
5510
+ # Note: Deployment, stage and access logging are created in the consuming module
5511
+ # (e.g., foo-api.tf) after all methods and integrations are defined
5085
5512
 
5086
5513
  # Gateway Response for CORS (4XX errors)
5087
5514
  resource "aws_api_gateway_gateway_response" "cors_4xx" {
@@ -5239,16 +5666,14 @@ output "waf_web_acl_arn" {
5239
5666
  value = var.enable_waf ? aws_wafv2_web_acl.api_waf[0].arn : null
5240
5667
  }
5241
5668
 
5242
- # Note: Stage and deployment outputs are provided by the consuming module
5243
-
5244
- # Note: CloudWatch log group outputs removed due to account-level CloudWatch Logs role ARN requirement",
5669
+ # Note: Stage, deployment and access log outputs are provided by the consuming module",
5245
5670
  "test-api.tf": "terraform {
5246
5671
  required_version = ">= 1.0"
5247
5672
 
5248
5673
  required_providers {
5249
5674
  aws = {
5250
5675
  source = "hashicorp/aws"
5251
- version = "~> 6.33"
5676
+ version = "6.54.0"
5252
5677
  }
5253
5678
  }
5254
5679
  }
@@ -5280,11 +5705,47 @@ variable "additional_iam_policy_statements" {
5280
5705
  default = []
5281
5706
  }
5282
5707
 
5708
+ variable "appconfig_application_id" {
5709
+ description = "ID of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_id\`). When set, the Lambda functions receive \`RUNTIME_CONFIG_APP_ID\` and read access to the application."
5710
+ type = string
5711
+ default = null
5712
+ }
5713
+
5714
+ variable "appconfig_application_arn" {
5715
+ description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the Lambda functions."
5716
+ type = string
5717
+ default = null
5718
+ }
5719
+
5283
5720
  variable "asset_bucket_name" {
5284
5721
  description = "Name of the shared asset S3 bucket used to stage the Lambda deployment zip. Instantiate the \`core/asset-bucket\` module once per deployment and pass its \`bucket_name\` output here."
5285
5722
  type = string
5286
5723
  }
5287
5724
 
5725
+ # VPC Configuration (optional)
5726
+ variable "enable_vpc" {
5727
+ description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
5728
+ type = bool
5729
+ default = false
5730
+ }
5731
+
5732
+ variable "vpc_id" {
5733
+ description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
5734
+ type = string
5735
+ default = null
5736
+
5737
+ validation {
5738
+ condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
5739
+ error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
5740
+ }
5741
+ }
5742
+
5743
+ variable "subnet_ids" {
5744
+ description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
5745
+ type = list(string)
5746
+ default = null
5747
+ }
5748
+
5288
5749
  # CORS Configuration (passed to core module)
5289
5750
 
5290
5751
  variable "cors_allow_headers" {
@@ -5347,6 +5808,11 @@ resource "aws_s3_object" "lambda_zip" {
5347
5808
  }
5348
5809
 
5349
5810
  # Use the core REST API module
5811
+ # Account-level CloudWatch role required for REST API access logging
5812
+ module "account" {
5813
+ source = "../../../core/api/api-gateway-account"
5814
+ }
5815
+
5350
5816
  module "rest_api" {
5351
5817
  source = "../../../core/api/rest-api"
5352
5818
 
@@ -5376,9 +5842,31 @@ resource "aws_wafv2_web_acl_association" "api_waf_association" {
5376
5842
  depends_on = [aws_api_gateway_stage.api_stage]
5377
5843
  }
5378
5844
 
5845
+ # Security group for the API Lambda function, used when deployed into a VPC
5846
+ resource "aws_security_group" "api_lambda" {
5847
+ count = var.enable_vpc ? 1 : 0
5848
+
5849
+ #checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
5850
+ name_prefix = "test-api-lambda-"
5851
+ description = "Security group for the TestApi API Lambda function"
5852
+ vpc_id = var.vpc_id
5853
+ tags = var.tags
5854
+ }
5855
+
5856
+ resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
5857
+ count = var.enable_vpc ? 1 : 0
5858
+
5859
+ security_group_id = aws_security_group.api_lambda[0].id
5860
+ cidr_ipv4 = "0.0.0.0/0"
5861
+ from_port = 443
5862
+ to_port = 443
5863
+ ip_protocol = "tcp"
5864
+ description = "Allow outbound HTTPS to AWS service endpoints"
5865
+ }
5866
+
5379
5867
  # Lambda function
5380
5868
  resource "aws_lambda_function" "api_lambda" {
5381
- #checkov:skip=CKV_AWS_117:Lambda function does not need to be in VPC for this use case
5869
+ #checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
5382
5870
  #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
5383
5871
  #checkov:skip=CKV_AWS_272:Code signing not required for this use case
5384
5872
  #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
@@ -5400,13 +5888,25 @@ resource "aws_lambda_function" "api_lambda" {
5400
5888
  mode = "Active"
5401
5889
  }
5402
5890
 
5891
+ dynamic "vpc_config" {
5892
+ for_each = var.enable_vpc ? [1] : []
5893
+ content {
5894
+ subnet_ids = var.subnet_ids
5895
+ security_group_ids = [aws_security_group.api_lambda[0].id]
5896
+ }
5897
+ }
5898
+
5403
5899
 
5404
5900
  environment {
5405
5901
  variables = merge({
5406
- }, var.env)
5902
+ }, var.appconfig_application_id != null ? {
5903
+ RUNTIME_CONFIG_APP_ID = var.appconfig_application_id
5904
+ } : {}, var.env)
5407
5905
  }
5408
5906
 
5409
5907
  tags = var.tags
5908
+
5909
+ depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
5410
5910
  }
5411
5911
 
5412
5912
  # IAM role for Lambda execution
@@ -5441,18 +5941,39 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
5441
5941
  role = aws_iam_role.lambda_execution_role.name
5442
5942
  }
5443
5943
 
5944
+ # Attach VPC access policy to Lambda role when deployed into a VPC
5945
+ resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
5946
+ count = var.enable_vpc ? 1 : 0
5947
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
5948
+ role = aws_iam_role.lambda_execution_role.name
5949
+ }
5950
+
5444
5951
  # Additional IAM policies for Lambda (if provided)
5445
5952
  resource "aws_iam_role_policy" "lambda_additional_policies" {
5446
- count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
5953
+ count = length(local.lambda_policy_statements) > 0 ? 1 : 0
5447
5954
  name = "TestApiHandler-additional-policies-\${random_string.suffix.result}"
5448
5955
  role = aws_iam_role.lambda_execution_role.id
5449
5956
 
5450
5957
  policy = jsonencode({
5451
5958
  Version = "2012-10-17"
5452
- Statement = var.additional_iam_policy_statements
5959
+ Statement = local.lambda_policy_statements
5453
5960
  })
5454
5961
  }
5455
5962
 
5963
+ locals {
5964
+ # Grant read access to the runtime-config AppConfig application when wired
5965
+ lambda_policy_statements = concat(var.appconfig_application_arn != null ? [
5966
+ {
5967
+ Effect = "Allow"
5968
+ Action = [
5969
+ "appconfig:StartConfigurationSession",
5970
+ "appconfig:GetLatestConfiguration"
5971
+ ]
5972
+ Resource = ["\${var.appconfig_application_arn}/*"]
5973
+ }
5974
+ ] : [], var.additional_iam_policy_statements)
5975
+ }
5976
+
5456
5977
  # CloudWatch Log Group for Lambda
5457
5978
  resource "aws_cloudwatch_log_group" "lambda_logs" {
5458
5979
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -5502,6 +6023,9 @@ resource "aws_api_gateway_method" "proxy_method" {
5502
6023
 
5503
6024
  authorization = "COGNITO_USER_POOLS"
5504
6025
  authorizer_id = aws_api_gateway_authorizer.cognito_authorizer.id
6026
+ # Accept access tokens from both sign-in flows: 'openid' (Cognito hosted UI)
6027
+ # and 'aws.cognito.signin.user.admin' (Cognito admin/SRP auth APIs).
6028
+ authorization_scopes = ["openid", "aws.cognito.signin.user.admin"]
5505
6029
 
5506
6030
  request_parameters = {
5507
6031
  "method.request.path.proxy" = true
@@ -5588,11 +6112,63 @@ resource "aws_api_gateway_deployment" "api_deployment" {
5588
6112
  ]
5589
6113
  }
5590
6114
 
6115
+ # KMS key for encrypting access logs at rest
6116
+ resource "aws_kms_key" "access_logs" {
6117
+ description = "TestApi API access log encryption"
6118
+ deletion_window_in_days = 7
6119
+ enable_key_rotation = true
6120
+
6121
+ policy = jsonencode({
6122
+ Version = "2012-10-17"
6123
+ Statement = [
6124
+ {
6125
+ Sid = "Enable IAM User Permissions"
6126
+ Effect = "Allow"
6127
+ Principal = { AWS = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:root" }
6128
+ Action = "kms:*"
6129
+ Resource = "*"
6130
+ },
6131
+ {
6132
+ Sid = "Allow CloudWatch Logs"
6133
+ Effect = "Allow"
6134
+ Principal = { Service = "logs.\${data.aws_region.current.region}.amazonaws.com" }
6135
+ Action = [
6136
+ "kms:Encrypt",
6137
+ "kms:Decrypt",
6138
+ "kms:ReEncrypt*",
6139
+ "kms:GenerateDataKey*",
6140
+ "kms:DescribeKey"
6141
+ ]
6142
+ Resource = "*"
6143
+ Condition = {
6144
+ ArnEquals = {
6145
+ "kms:EncryptionContext:aws:logs:arn" = "arn:aws:logs:\${data.aws_region.current.region}:\${data.aws_caller_identity.current.account_id}:log-group:/aws/apigateway/test-api-\${random_string.suffix.result}/access"
6146
+ }
6147
+ }
6148
+ }
6149
+ ]
6150
+ })
6151
+
6152
+ tags = var.tags
6153
+ }
6154
+
6155
+ resource "aws_kms_alias" "access_logs" {
6156
+ name = "alias/test-api-\${random_string.suffix.result}-access-logs"
6157
+ target_key_id = aws_kms_key.access_logs.key_id
6158
+ }
6159
+
6160
+ # Access logs for the API Gateway stage
6161
+ resource "aws_cloudwatch_log_group" "access_logs" {
6162
+ name = "/aws/apigateway/test-api-\${random_string.suffix.result}/access"
6163
+ retention_in_days = 365
6164
+ kms_key_id = aws_kms_key.access_logs.arn
6165
+ tags = var.tags
6166
+ }
6167
+
5591
6168
  # API Gateway stage
5592
6169
  resource "aws_api_gateway_stage" "api_stage" {
5593
6170
  #checkov:skip=CKV_AWS_120:API Gateway caching not required for this use case
5594
- #checkov:skip=CKV_AWS_76:API Gateway access logging disabled due to account-level CloudWatch Logs role ARN requirement
5595
- #checkov:skip=CKV2_AWS_4:API Gateway logging level not applicable as access logging is disabled
6171
+ #checkov:skip=CKV2_AWS_4:Access logging is enabled below; verbose execution logging is intentionally not enabled
5596
6172
  #checkov:skip=CKV2_AWS_51:Client certificate authentication not required for this use case
5597
6173
  #checkov:skip=CKV2_AWS_77:WAFv2 Web ACL is attached via aws_wafv2_web_acl_association when var.enable_waf is true (default) and includes AWSManagedRulesKnownBadInputsRuleSet for Log4j protection; Checkov does not track the association across modules
5598
6174
  deployment_id = aws_api_gateway_deployment.api_deployment.id
@@ -5600,9 +6176,39 @@ resource "aws_api_gateway_stage" "api_stage" {
5600
6176
  stage_name = "prod"
5601
6177
  xray_tracing_enabled = true
5602
6178
 
6179
+ access_log_settings {
6180
+ destination_arn = aws_cloudwatch_log_group.access_logs.arn
6181
+ format = jsonencode({
6182
+ requestId = "$context.requestId"
6183
+ ip = "$context.identity.sourceIp"
6184
+ caller = "$context.identity.caller"
6185
+ user = "$context.identity.user"
6186
+ requestTime = "$context.requestTime"
6187
+ httpMethod = "$context.httpMethod"
6188
+ resourcePath = "$context.resourcePath"
6189
+ status = "$context.status"
6190
+ protocol = "$context.protocol"
6191
+ responseLength = "$context.responseLength"
6192
+ })
6193
+ }
6194
+
5603
6195
  tags = var.tags
5604
6196
 
5605
- depends_on = [aws_api_gateway_deployment.api_deployment]
6197
+ # Ensure the account-level role is configured before the stage is created
6198
+ depends_on = [aws_api_gateway_deployment.api_deployment, module.account]
6199
+ }
6200
+
6201
+ # Default throttling applied to all resource paths and methods
6202
+ resource "aws_api_gateway_method_settings" "throttling" {
6203
+ #checkov:skip=CKV_AWS_225:API Gateway caching not required for this use case
6204
+ rest_api_id = module.rest_api.api_id
6205
+ stage_name = aws_api_gateway_stage.api_stage.stage_name
6206
+ method_path = "*/*"
6207
+
6208
+ settings {
6209
+ throttling_rate_limit = 10000
6210
+ throttling_burst_limit = 5000
6211
+ }
5606
6212
  }
5607
6213
 
5608
6214
  # API Gateway Resource Policy
@@ -5741,6 +6347,11 @@ output "lambda_execution_role_name" {
5741
6347
  value = aws_iam_role.lambda_execution_role.name
5742
6348
  }
5743
6349
 
6350
+ output "security_group_id" {
6351
+ description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
6352
+ value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
6353
+ }
6354
+
5744
6355
  # Integration Outputs
5745
6356
  output "integration_id" {
5746
6357
  description = "ID of the Lambda integration"
@@ -5782,11 +6393,11 @@ terraform {
5782
6393
  required_providers {
5783
6394
  aws = {
5784
6395
  source = "hashicorp/aws"
5785
- version = "~> 6.33"
6396
+ version = "6.54.0"
5786
6397
  }
5787
6398
  random = {
5788
6399
  source = "hashicorp/random"
5789
- version = "~> 3.1"
6400
+ version = "3.9.0"
5790
6401
  }
5791
6402
  }
5792
6403
  }
@@ -5856,8 +6467,6 @@ data "aws_caller_identity" "current" {}
5856
6467
 
5857
6468
  # Resources
5858
6469
 
5859
- # Note: CloudWatch logging removed due to account-level CloudWatch Logs role ARN requirement
5860
-
5861
6470
  # REST API Gateway
5862
6471
  resource "aws_api_gateway_rest_api" "rest_api" {
5863
6472
  name = var.api_name
@@ -5874,10 +6483,8 @@ resource "aws_api_gateway_rest_api" "rest_api" {
5874
6483
  tags = var.tags
5875
6484
  }
5876
6485
 
5877
- # Note: Deployment and stage are created in the consuming module (e.g., foo-api.tf)
5878
- # after all methods and integrations are defined
5879
-
5880
- # Note: CloudWatch Log Group removed due to account-level CloudWatch Logs role ARN requirement
6486
+ # Note: Deployment, stage and access logging are created in the consuming module
6487
+ # (e.g., foo-api.tf) after all methods and integrations are defined
5881
6488
 
5882
6489
  # Gateway Response for CORS (4XX errors)
5883
6490
  resource "aws_api_gateway_gateway_response" "cors_4xx" {
@@ -6035,16 +6642,14 @@ output "waf_web_acl_arn" {
6035
6642
  value = var.enable_waf ? aws_wafv2_web_acl.api_waf[0].arn : null
6036
6643
  }
6037
6644
 
6038
- # Note: Stage and deployment outputs are provided by the consuming module
6039
-
6040
- # Note: CloudWatch log group outputs removed due to account-level CloudWatch Logs role ARN requirement",
6645
+ # Note: Stage, deployment and access log outputs are provided by the consuming module",
6041
6646
  "test-api.tf": "terraform {
6042
6647
  required_version = ">= 1.0"
6043
6648
 
6044
6649
  required_providers {
6045
6650
  aws = {
6046
6651
  source = "hashicorp/aws"
6047
- version = "~> 6.33"
6652
+ version = "6.54.0"
6048
6653
  }
6049
6654
  }
6050
6655
  }
@@ -6066,11 +6671,47 @@ variable "additional_iam_policy_statements" {
6066
6671
  default = []
6067
6672
  }
6068
6673
 
6674
+ variable "appconfig_application_id" {
6675
+ description = "ID of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_id\`). When set, the Lambda functions receive \`RUNTIME_CONFIG_APP_ID\` and read access to the application."
6676
+ type = string
6677
+ default = null
6678
+ }
6679
+
6680
+ variable "appconfig_application_arn" {
6681
+ description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the Lambda functions."
6682
+ type = string
6683
+ default = null
6684
+ }
6685
+
6069
6686
  variable "asset_bucket_name" {
6070
6687
  description = "Name of the shared asset S3 bucket used to stage the Lambda deployment zip. Instantiate the \`core/asset-bucket\` module once per deployment and pass its \`bucket_name\` output here."
6071
6688
  type = string
6072
6689
  }
6073
6690
 
6691
+ # VPC Configuration (optional)
6692
+ variable "enable_vpc" {
6693
+ description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
6694
+ type = bool
6695
+ default = false
6696
+ }
6697
+
6698
+ variable "vpc_id" {
6699
+ description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
6700
+ type = string
6701
+ default = null
6702
+
6703
+ validation {
6704
+ condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
6705
+ error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
6706
+ }
6707
+ }
6708
+
6709
+ variable "subnet_ids" {
6710
+ description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
6711
+ type = list(string)
6712
+ default = null
6713
+ }
6714
+
6074
6715
  # CORS Configuration (passed to core module)
6075
6716
 
6076
6717
  variable "cors_allow_headers" {
@@ -6133,6 +6774,11 @@ resource "aws_s3_object" "lambda_zip" {
6133
6774
  }
6134
6775
 
6135
6776
  # Use the core REST API module
6777
+ # Account-level CloudWatch role required for REST API access logging
6778
+ module "account" {
6779
+ source = "../../../core/api/api-gateway-account"
6780
+ }
6781
+
6136
6782
  module "rest_api" {
6137
6783
  source = "../../../core/api/rest-api"
6138
6784
 
@@ -6162,9 +6808,31 @@ resource "aws_wafv2_web_acl_association" "api_waf_association" {
6162
6808
  depends_on = [aws_api_gateway_stage.api_stage]
6163
6809
  }
6164
6810
 
6811
+ # Security group for the API Lambda function, used when deployed into a VPC
6812
+ resource "aws_security_group" "api_lambda" {
6813
+ count = var.enable_vpc ? 1 : 0
6814
+
6815
+ #checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
6816
+ name_prefix = "test-api-lambda-"
6817
+ description = "Security group for the TestApi API Lambda function"
6818
+ vpc_id = var.vpc_id
6819
+ tags = var.tags
6820
+ }
6821
+
6822
+ resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
6823
+ count = var.enable_vpc ? 1 : 0
6824
+
6825
+ security_group_id = aws_security_group.api_lambda[0].id
6826
+ cidr_ipv4 = "0.0.0.0/0"
6827
+ from_port = 443
6828
+ to_port = 443
6829
+ ip_protocol = "tcp"
6830
+ description = "Allow outbound HTTPS to AWS service endpoints"
6831
+ }
6832
+
6165
6833
  # Lambda function
6166
6834
  resource "aws_lambda_function" "api_lambda" {
6167
- #checkov:skip=CKV_AWS_117:Lambda function does not need to be in VPC for this use case
6835
+ #checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
6168
6836
  #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
6169
6837
  #checkov:skip=CKV_AWS_272:Code signing not required for this use case
6170
6838
  #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
@@ -6186,13 +6854,25 @@ resource "aws_lambda_function" "api_lambda" {
6186
6854
  mode = "Active"
6187
6855
  }
6188
6856
 
6857
+ dynamic "vpc_config" {
6858
+ for_each = var.enable_vpc ? [1] : []
6859
+ content {
6860
+ subnet_ids = var.subnet_ids
6861
+ security_group_ids = [aws_security_group.api_lambda[0].id]
6862
+ }
6863
+ }
6864
+
6189
6865
 
6190
6866
  environment {
6191
6867
  variables = merge({
6192
- }, var.env)
6868
+ }, var.appconfig_application_id != null ? {
6869
+ RUNTIME_CONFIG_APP_ID = var.appconfig_application_id
6870
+ } : {}, var.env)
6193
6871
  }
6194
6872
 
6195
6873
  tags = var.tags
6874
+
6875
+ depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
6196
6876
  }
6197
6877
 
6198
6878
  # IAM role for Lambda execution
@@ -6227,18 +6907,39 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
6227
6907
  role = aws_iam_role.lambda_execution_role.name
6228
6908
  }
6229
6909
 
6910
+ # Attach VPC access policy to Lambda role when deployed into a VPC
6911
+ resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
6912
+ count = var.enable_vpc ? 1 : 0
6913
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
6914
+ role = aws_iam_role.lambda_execution_role.name
6915
+ }
6916
+
6230
6917
  # Additional IAM policies for Lambda (if provided)
6231
6918
  resource "aws_iam_role_policy" "lambda_additional_policies" {
6232
- count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
6919
+ count = length(local.lambda_policy_statements) > 0 ? 1 : 0
6233
6920
  name = "TestApiHandler-additional-policies-\${random_string.suffix.result}"
6234
6921
  role = aws_iam_role.lambda_execution_role.id
6235
6922
 
6236
6923
  policy = jsonencode({
6237
6924
  Version = "2012-10-17"
6238
- Statement = var.additional_iam_policy_statements
6925
+ Statement = local.lambda_policy_statements
6239
6926
  })
6240
6927
  }
6241
6928
 
6929
+ locals {
6930
+ # Grant read access to the runtime-config AppConfig application when wired
6931
+ lambda_policy_statements = concat(var.appconfig_application_arn != null ? [
6932
+ {
6933
+ Effect = "Allow"
6934
+ Action = [
6935
+ "appconfig:StartConfigurationSession",
6936
+ "appconfig:GetLatestConfiguration"
6937
+ ]
6938
+ Resource = ["\${var.appconfig_application_arn}/*"]
6939
+ }
6940
+ ] : [], var.additional_iam_policy_statements)
6941
+ }
6942
+
6242
6943
  # CloudWatch Log Group for Lambda
6243
6944
  resource "aws_cloudwatch_log_group" "lambda_logs" {
6244
6945
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -6365,11 +7066,63 @@ resource "aws_api_gateway_deployment" "api_deployment" {
6365
7066
  ]
6366
7067
  }
6367
7068
 
7069
+ # KMS key for encrypting access logs at rest
7070
+ resource "aws_kms_key" "access_logs" {
7071
+ description = "TestApi API access log encryption"
7072
+ deletion_window_in_days = 7
7073
+ enable_key_rotation = true
7074
+
7075
+ policy = jsonencode({
7076
+ Version = "2012-10-17"
7077
+ Statement = [
7078
+ {
7079
+ Sid = "Enable IAM User Permissions"
7080
+ Effect = "Allow"
7081
+ Principal = { AWS = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:root" }
7082
+ Action = "kms:*"
7083
+ Resource = "*"
7084
+ },
7085
+ {
7086
+ Sid = "Allow CloudWatch Logs"
7087
+ Effect = "Allow"
7088
+ Principal = { Service = "logs.\${data.aws_region.current.region}.amazonaws.com" }
7089
+ Action = [
7090
+ "kms:Encrypt",
7091
+ "kms:Decrypt",
7092
+ "kms:ReEncrypt*",
7093
+ "kms:GenerateDataKey*",
7094
+ "kms:DescribeKey"
7095
+ ]
7096
+ Resource = "*"
7097
+ Condition = {
7098
+ ArnEquals = {
7099
+ "kms:EncryptionContext:aws:logs:arn" = "arn:aws:logs:\${data.aws_region.current.region}:\${data.aws_caller_identity.current.account_id}:log-group:/aws/apigateway/test-api-\${random_string.suffix.result}/access"
7100
+ }
7101
+ }
7102
+ }
7103
+ ]
7104
+ })
7105
+
7106
+ tags = var.tags
7107
+ }
7108
+
7109
+ resource "aws_kms_alias" "access_logs" {
7110
+ name = "alias/test-api-\${random_string.suffix.result}-access-logs"
7111
+ target_key_id = aws_kms_key.access_logs.key_id
7112
+ }
7113
+
7114
+ # Access logs for the API Gateway stage
7115
+ resource "aws_cloudwatch_log_group" "access_logs" {
7116
+ name = "/aws/apigateway/test-api-\${random_string.suffix.result}/access"
7117
+ retention_in_days = 365
7118
+ kms_key_id = aws_kms_key.access_logs.arn
7119
+ tags = var.tags
7120
+ }
7121
+
6368
7122
  # API Gateway stage
6369
7123
  resource "aws_api_gateway_stage" "api_stage" {
6370
7124
  #checkov:skip=CKV_AWS_120:API Gateway caching not required for this use case
6371
- #checkov:skip=CKV_AWS_76:API Gateway access logging disabled due to account-level CloudWatch Logs role ARN requirement
6372
- #checkov:skip=CKV2_AWS_4:API Gateway logging level not applicable as access logging is disabled
7125
+ #checkov:skip=CKV2_AWS_4:Access logging is enabled below; verbose execution logging is intentionally not enabled
6373
7126
  #checkov:skip=CKV2_AWS_51:Client certificate authentication not required for this use case
6374
7127
  #checkov:skip=CKV2_AWS_77:WAFv2 Web ACL is attached via aws_wafv2_web_acl_association when var.enable_waf is true (default) and includes AWSManagedRulesKnownBadInputsRuleSet for Log4j protection; Checkov does not track the association across modules
6375
7128
  deployment_id = aws_api_gateway_deployment.api_deployment.id
@@ -6377,9 +7130,39 @@ resource "aws_api_gateway_stage" "api_stage" {
6377
7130
  stage_name = "prod"
6378
7131
  xray_tracing_enabled = true
6379
7132
 
7133
+ access_log_settings {
7134
+ destination_arn = aws_cloudwatch_log_group.access_logs.arn
7135
+ format = jsonencode({
7136
+ requestId = "$context.requestId"
7137
+ ip = "$context.identity.sourceIp"
7138
+ caller = "$context.identity.caller"
7139
+ user = "$context.identity.user"
7140
+ requestTime = "$context.requestTime"
7141
+ httpMethod = "$context.httpMethod"
7142
+ resourcePath = "$context.resourcePath"
7143
+ status = "$context.status"
7144
+ protocol = "$context.protocol"
7145
+ responseLength = "$context.responseLength"
7146
+ })
7147
+ }
7148
+
6380
7149
  tags = var.tags
6381
7150
 
6382
- depends_on = [aws_api_gateway_deployment.api_deployment]
7151
+ # Ensure the account-level role is configured before the stage is created
7152
+ depends_on = [aws_api_gateway_deployment.api_deployment, module.account]
7153
+ }
7154
+
7155
+ # Default throttling applied to all resource paths and methods
7156
+ resource "aws_api_gateway_method_settings" "throttling" {
7157
+ #checkov:skip=CKV_AWS_225:API Gateway caching not required for this use case
7158
+ rest_api_id = module.rest_api.api_id
7159
+ stage_name = aws_api_gateway_stage.api_stage.stage_name
7160
+ method_path = "*/*"
7161
+
7162
+ settings {
7163
+ throttling_rate_limit = 10000
7164
+ throttling_burst_limit = 5000
7165
+ }
6383
7166
  }
6384
7167
 
6385
7168
  # API Gateway Resource Policy
@@ -6529,6 +7312,11 @@ output "lambda_execution_role_name" {
6529
7312
  value = aws_iam_role.lambda_execution_role.name
6530
7313
  }
6531
7314
 
7315
+ output "security_group_id" {
7316
+ description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
7317
+ value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
7318
+ }
7319
+
6532
7320
  # Integration Outputs
6533
7321
  output "integration_id" {
6534
7322
  description = "ID of the Lambda integration"
@@ -6570,11 +7358,11 @@ terraform {
6570
7358
  required_providers {
6571
7359
  aws = {
6572
7360
  source = "hashicorp/aws"
6573
- version = "~> 6.33"
7361
+ version = "6.54.0"
6574
7362
  }
6575
7363
  random = {
6576
7364
  source = "hashicorp/random"
6577
- version = "~> 3.1"
7365
+ version = "3.9.0"
6578
7366
  }
6579
7367
  }
6580
7368
  }
@@ -6644,8 +7432,6 @@ data "aws_caller_identity" "current" {}
6644
7432
 
6645
7433
  # Resources
6646
7434
 
6647
- # Note: CloudWatch logging removed due to account-level CloudWatch Logs role ARN requirement
6648
-
6649
7435
  # REST API Gateway
6650
7436
  resource "aws_api_gateway_rest_api" "rest_api" {
6651
7437
  name = var.api_name
@@ -6662,10 +7448,8 @@ resource "aws_api_gateway_rest_api" "rest_api" {
6662
7448
  tags = var.tags
6663
7449
  }
6664
7450
 
6665
- # Note: Deployment and stage are created in the consuming module (e.g., foo-api.tf)
6666
- # after all methods and integrations are defined
6667
-
6668
- # Note: CloudWatch Log Group removed due to account-level CloudWatch Logs role ARN requirement
7451
+ # Note: Deployment, stage and access logging are created in the consuming module
7452
+ # (e.g., foo-api.tf) after all methods and integrations are defined
6669
7453
 
6670
7454
  # Gateway Response for CORS (4XX errors)
6671
7455
  resource "aws_api_gateway_gateway_response" "cors_4xx" {
@@ -6823,16 +7607,14 @@ output "waf_web_acl_arn" {
6823
7607
  value = var.enable_waf ? aws_wafv2_web_acl.api_waf[0].arn : null
6824
7608
  }
6825
7609
 
6826
- # Note: Stage and deployment outputs are provided by the consuming module
6827
-
6828
- # Note: CloudWatch log group outputs removed due to account-level CloudWatch Logs role ARN requirement",
7610
+ # Note: Stage, deployment and access log outputs are provided by the consuming module",
6829
7611
  "test-api.tf": "terraform {
6830
7612
  required_version = ">= 1.0"
6831
7613
 
6832
7614
  required_providers {
6833
7615
  aws = {
6834
7616
  source = "hashicorp/aws"
6835
- version = "~> 6.33"
7617
+ version = "6.54.0"
6836
7618
  }
6837
7619
  }
6838
7620
  }
@@ -6854,11 +7636,47 @@ variable "additional_iam_policy_statements" {
6854
7636
  default = []
6855
7637
  }
6856
7638
 
7639
+ variable "appconfig_application_id" {
7640
+ description = "ID of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_id\`). When set, the Lambda functions receive \`RUNTIME_CONFIG_APP_ID\` and read access to the application."
7641
+ type = string
7642
+ default = null
7643
+ }
7644
+
7645
+ variable "appconfig_application_arn" {
7646
+ description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the Lambda functions."
7647
+ type = string
7648
+ default = null
7649
+ }
7650
+
6857
7651
  variable "asset_bucket_name" {
6858
7652
  description = "Name of the shared asset S3 bucket used to stage the Lambda deployment zip. Instantiate the \`core/asset-bucket\` module once per deployment and pass its \`bucket_name\` output here."
6859
7653
  type = string
6860
7654
  }
6861
7655
 
7656
+ # VPC Configuration (optional)
7657
+ variable "enable_vpc" {
7658
+ description = "Deploy the Lambda function into a VPC. Set alongside vpc_id/subnet_ids."
7659
+ type = bool
7660
+ default = false
7661
+ }
7662
+
7663
+ variable "vpc_id" {
7664
+ description = "VPC ID to deploy the Lambda function into. Required when enable_vpc is true."
7665
+ type = string
7666
+ default = null
7667
+
7668
+ validation {
7669
+ condition = !var.enable_vpc || (var.vpc_id != null && var.subnet_ids != null)
7670
+ error_message = "vpc_id and subnet_ids must be set when enable_vpc is true."
7671
+ }
7672
+ }
7673
+
7674
+ variable "subnet_ids" {
7675
+ description = "Subnet IDs to deploy the Lambda function into. Required when enable_vpc is true."
7676
+ type = list(string)
7677
+ default = null
7678
+ }
7679
+
6862
7680
  # CORS Configuration (passed to core module)
6863
7681
 
6864
7682
  variable "cors_allow_headers" {
@@ -6921,6 +7739,11 @@ resource "aws_s3_object" "lambda_zip" {
6921
7739
  }
6922
7740
 
6923
7741
  # Use the core REST API module
7742
+ # Account-level CloudWatch role required for REST API access logging
7743
+ module "account" {
7744
+ source = "../../../core/api/api-gateway-account"
7745
+ }
7746
+
6924
7747
  module "rest_api" {
6925
7748
  source = "../../../core/api/rest-api"
6926
7749
 
@@ -6950,9 +7773,31 @@ resource "aws_wafv2_web_acl_association" "api_waf_association" {
6950
7773
  depends_on = [aws_api_gateway_stage.api_stage]
6951
7774
  }
6952
7775
 
7776
+ # Security group for the API Lambda function, used when deployed into a VPC
7777
+ resource "aws_security_group" "api_lambda" {
7778
+ count = var.enable_vpc ? 1 : 0
7779
+
7780
+ #checkov:skip=CKV2_AWS_5:Attached to api_lambda via vpc_config block; Checkov cannot resolve this reference
7781
+ name_prefix = "test-api-lambda-"
7782
+ description = "Security group for the TestApi API Lambda function"
7783
+ vpc_id = var.vpc_id
7784
+ tags = var.tags
7785
+ }
7786
+
7787
+ resource "aws_vpc_security_group_egress_rule" "api_lambda_https" {
7788
+ count = var.enable_vpc ? 1 : 0
7789
+
7790
+ security_group_id = aws_security_group.api_lambda[0].id
7791
+ cidr_ipv4 = "0.0.0.0/0"
7792
+ from_port = 443
7793
+ to_port = 443
7794
+ ip_protocol = "tcp"
7795
+ description = "Allow outbound HTTPS to AWS service endpoints"
7796
+ }
7797
+
6953
7798
  # Lambda function
6954
7799
  resource "aws_lambda_function" "api_lambda" {
6955
- #checkov:skip=CKV_AWS_117:Lambda function does not need to be in VPC for this use case
7800
+ #checkov:skip=CKV_AWS_117:Lambda function is optionally deployed into a VPC via vpc_id/subnet_ids; not required for this use case
6956
7801
  #checkov:skip=CKV_AWS_116:Dead Letter Queue not required for this simple API use case
6957
7802
  #checkov:skip=CKV_AWS_272:Code signing not required for this use case
6958
7803
  #checkov:skip=CKV_AWS_115:Concurrent execution limit not required for this use case
@@ -6974,13 +7819,25 @@ resource "aws_lambda_function" "api_lambda" {
6974
7819
  mode = "Active"
6975
7820
  }
6976
7821
 
7822
+ dynamic "vpc_config" {
7823
+ for_each = var.enable_vpc ? [1] : []
7824
+ content {
7825
+ subnet_ids = var.subnet_ids
7826
+ security_group_ids = [aws_security_group.api_lambda[0].id]
7827
+ }
7828
+ }
7829
+
6977
7830
 
6978
7831
  environment {
6979
7832
  variables = merge({
6980
- }, var.env)
7833
+ }, var.appconfig_application_id != null ? {
7834
+ RUNTIME_CONFIG_APP_ID = var.appconfig_application_id
7835
+ } : {}, var.env)
6981
7836
  }
6982
7837
 
6983
7838
  tags = var.tags
7839
+
7840
+ depends_on = [aws_iam_role_policy_attachment.lambda_vpc_access]
6984
7841
  }
6985
7842
 
6986
7843
  # IAM role for Lambda execution
@@ -7015,18 +7872,39 @@ resource "aws_iam_role_policy_attachment" "lambda_xray_execution" {
7015
7872
  role = aws_iam_role.lambda_execution_role.name
7016
7873
  }
7017
7874
 
7875
+ # Attach VPC access policy to Lambda role when deployed into a VPC
7876
+ resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
7877
+ count = var.enable_vpc ? 1 : 0
7878
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
7879
+ role = aws_iam_role.lambda_execution_role.name
7880
+ }
7881
+
7018
7882
  # Additional IAM policies for Lambda (if provided)
7019
7883
  resource "aws_iam_role_policy" "lambda_additional_policies" {
7020
- count = length(var.additional_iam_policy_statements) > 0 ? 1 : 0
7884
+ count = length(local.lambda_policy_statements) > 0 ? 1 : 0
7021
7885
  name = "TestApiHandler-additional-policies-\${random_string.suffix.result}"
7022
7886
  role = aws_iam_role.lambda_execution_role.id
7023
7887
 
7024
7888
  policy = jsonencode({
7025
7889
  Version = "2012-10-17"
7026
- Statement = var.additional_iam_policy_statements
7890
+ Statement = local.lambda_policy_statements
7027
7891
  })
7028
7892
  }
7029
7893
 
7894
+ locals {
7895
+ # Grant read access to the runtime-config AppConfig application when wired
7896
+ lambda_policy_statements = concat(var.appconfig_application_arn != null ? [
7897
+ {
7898
+ Effect = "Allow"
7899
+ Action = [
7900
+ "appconfig:StartConfigurationSession",
7901
+ "appconfig:GetLatestConfiguration"
7902
+ ]
7903
+ Resource = ["\${var.appconfig_application_arn}/*"]
7904
+ }
7905
+ ] : [], var.additional_iam_policy_statements)
7906
+ }
7907
+
7030
7908
  # CloudWatch Log Group for Lambda
7031
7909
  resource "aws_cloudwatch_log_group" "lambda_logs" {
7032
7910
  #checkov:skip=CKV_AWS_158:Using default CloudWatch log encryption
@@ -7247,11 +8125,63 @@ resource "aws_api_gateway_deployment" "api_deployment" {
7247
8125
  ]
7248
8126
  }
7249
8127
 
8128
+ # KMS key for encrypting access logs at rest
8129
+ resource "aws_kms_key" "access_logs" {
8130
+ description = "TestApi API access log encryption"
8131
+ deletion_window_in_days = 7
8132
+ enable_key_rotation = true
8133
+
8134
+ policy = jsonencode({
8135
+ Version = "2012-10-17"
8136
+ Statement = [
8137
+ {
8138
+ Sid = "Enable IAM User Permissions"
8139
+ Effect = "Allow"
8140
+ Principal = { AWS = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:root" }
8141
+ Action = "kms:*"
8142
+ Resource = "*"
8143
+ },
8144
+ {
8145
+ Sid = "Allow CloudWatch Logs"
8146
+ Effect = "Allow"
8147
+ Principal = { Service = "logs.\${data.aws_region.current.region}.amazonaws.com" }
8148
+ Action = [
8149
+ "kms:Encrypt",
8150
+ "kms:Decrypt",
8151
+ "kms:ReEncrypt*",
8152
+ "kms:GenerateDataKey*",
8153
+ "kms:DescribeKey"
8154
+ ]
8155
+ Resource = "*"
8156
+ Condition = {
8157
+ ArnEquals = {
8158
+ "kms:EncryptionContext:aws:logs:arn" = "arn:aws:logs:\${data.aws_region.current.region}:\${data.aws_caller_identity.current.account_id}:log-group:/aws/apigateway/test-api-\${random_string.suffix.result}/access"
8159
+ }
8160
+ }
8161
+ }
8162
+ ]
8163
+ })
8164
+
8165
+ tags = var.tags
8166
+ }
8167
+
8168
+ resource "aws_kms_alias" "access_logs" {
8169
+ name = "alias/test-api-\${random_string.suffix.result}-access-logs"
8170
+ target_key_id = aws_kms_key.access_logs.key_id
8171
+ }
8172
+
8173
+ # Access logs for the API Gateway stage
8174
+ resource "aws_cloudwatch_log_group" "access_logs" {
8175
+ name = "/aws/apigateway/test-api-\${random_string.suffix.result}/access"
8176
+ retention_in_days = 365
8177
+ kms_key_id = aws_kms_key.access_logs.arn
8178
+ tags = var.tags
8179
+ }
8180
+
7250
8181
  # API Gateway stage
7251
8182
  resource "aws_api_gateway_stage" "api_stage" {
7252
8183
  #checkov:skip=CKV_AWS_120:API Gateway caching not required for this use case
7253
- #checkov:skip=CKV_AWS_76:API Gateway access logging disabled due to account-level CloudWatch Logs role ARN requirement
7254
- #checkov:skip=CKV2_AWS_4:API Gateway logging level not applicable as access logging is disabled
8184
+ #checkov:skip=CKV2_AWS_4:Access logging is enabled below; verbose execution logging is intentionally not enabled
7255
8185
  #checkov:skip=CKV2_AWS_51:Client certificate authentication not required for this use case
7256
8186
  #checkov:skip=CKV2_AWS_77:WAFv2 Web ACL is attached via aws_wafv2_web_acl_association when var.enable_waf is true (default) and includes AWSManagedRulesKnownBadInputsRuleSet for Log4j protection; Checkov does not track the association across modules
7257
8187
  deployment_id = aws_api_gateway_deployment.api_deployment.id
@@ -7259,9 +8189,39 @@ resource "aws_api_gateway_stage" "api_stage" {
7259
8189
  stage_name = "prod"
7260
8190
  xray_tracing_enabled = true
7261
8191
 
8192
+ access_log_settings {
8193
+ destination_arn = aws_cloudwatch_log_group.access_logs.arn
8194
+ format = jsonencode({
8195
+ requestId = "$context.requestId"
8196
+ ip = "$context.identity.sourceIp"
8197
+ caller = "$context.identity.caller"
8198
+ user = "$context.identity.user"
8199
+ requestTime = "$context.requestTime"
8200
+ httpMethod = "$context.httpMethod"
8201
+ resourcePath = "$context.resourcePath"
8202
+ status = "$context.status"
8203
+ protocol = "$context.protocol"
8204
+ responseLength = "$context.responseLength"
8205
+ })
8206
+ }
8207
+
7262
8208
  tags = var.tags
7263
8209
 
7264
- depends_on = [aws_api_gateway_deployment.api_deployment]
8210
+ # Ensure the account-level role is configured before the stage is created
8211
+ depends_on = [aws_api_gateway_deployment.api_deployment, module.account]
8212
+ }
8213
+
8214
+ # Default throttling applied to all resource paths and methods
8215
+ resource "aws_api_gateway_method_settings" "throttling" {
8216
+ #checkov:skip=CKV_AWS_225:API Gateway caching not required for this use case
8217
+ rest_api_id = module.rest_api.api_id
8218
+ stage_name = aws_api_gateway_stage.api_stage.stage_name
8219
+ method_path = "*/*"
8220
+
8221
+ settings {
8222
+ throttling_rate_limit = 10000
8223
+ throttling_burst_limit = 5000
8224
+ }
7265
8225
  }
7266
8226
 
7267
8227
  # API Gateway Resource Policy
@@ -7400,6 +8360,11 @@ output "lambda_execution_role_name" {
7400
8360
  value = aws_iam_role.lambda_execution_role.name
7401
8361
  }
7402
8362
 
8363
+ output "security_group_id" {
8364
+ description = "Security group ID of the API Lambda function, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
8365
+ value = var.enable_vpc ? aws_security_group.api_lambda[0].id : null
8366
+ }
8367
+
7403
8368
  # Integration Outputs
7404
8369
  output "integration_id" {
7405
8370
  description = "ID of the Lambda integration"