@msn-control/liftoff 0.10.3 → 0.11.1

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 (656) hide show
  1. package/DEVELOPER.md +364 -20
  2. package/README.md +29 -29
  3. package/assets/governance/single-maintainer-gitflow/assessment-controls.json +39 -0
  4. package/assets/supported-stack.json +7 -138
  5. package/dist/adapters/azure/governance-assessment.d.ts +2 -0
  6. package/dist/adapters/azure/governance-assessment.js +21 -0
  7. package/dist/adapters/azure/governance-assessment.js.map +1 -0
  8. package/dist/adapters/filesystem/atomic-write.d.ts +2 -0
  9. package/dist/adapters/filesystem/atomic-write.js +74 -0
  10. package/dist/adapters/filesystem/atomic-write.js.map +1 -0
  11. package/dist/adapters/filesystem/errors.d.ts +2 -0
  12. package/dist/adapters/filesystem/errors.js +8 -0
  13. package/dist/adapters/filesystem/errors.js.map +1 -0
  14. package/dist/adapters/filesystem/manifest-file.d.ts +1 -0
  15. package/dist/adapters/filesystem/manifest-file.js +21 -0
  16. package/dist/adapters/filesystem/manifest-file.js.map +1 -0
  17. package/dist/adapters/filesystem/project-config.d.ts +4 -0
  18. package/dist/adapters/filesystem/project-config.js +157 -0
  19. package/dist/adapters/filesystem/project-config.js.map +1 -0
  20. package/dist/adapters/filesystem/project-discovery.d.ts +2 -0
  21. package/dist/adapters/filesystem/project-discovery.js +30 -0
  22. package/dist/adapters/filesystem/project-discovery.js.map +1 -0
  23. package/dist/adapters/filesystem/project-files.d.ts +6 -0
  24. package/dist/adapters/filesystem/project-files.js +68 -0
  25. package/dist/adapters/filesystem/project-files.js.map +1 -0
  26. package/dist/adapters/filesystem/project-lock.d.ts +8 -0
  27. package/dist/adapters/filesystem/project-lock.js +164 -0
  28. package/dist/adapters/filesystem/project-lock.js.map +1 -0
  29. package/dist/adapters/filesystem/project-paths.d.ts +2 -0
  30. package/dist/adapters/filesystem/project-paths.js +60 -0
  31. package/dist/adapters/filesystem/project-paths.js.map +1 -0
  32. package/dist/adapters/filesystem/project-transaction.d.ts +23 -0
  33. package/dist/adapters/filesystem/project-transaction.js +158 -0
  34. package/dist/adapters/filesystem/project-transaction.js.map +1 -0
  35. package/dist/adapters/git/governance-assessment.d.ts +22 -0
  36. package/dist/adapters/git/governance-assessment.js +161 -0
  37. package/dist/adapters/git/governance-assessment.js.map +1 -0
  38. package/dist/adapters/github/governance-assessment.d.ts +2 -0
  39. package/dist/adapters/github/governance-assessment.js +18 -0
  40. package/dist/adapters/github/governance-assessment.js.map +1 -0
  41. package/dist/adapters/packaged-assets/package-root.d.ts +3 -0
  42. package/dist/adapters/packaged-assets/package-root.js +21 -0
  43. package/dist/adapters/packaged-assets/package-root.js.map +1 -0
  44. package/dist/adapters/packaged-assets/supported-stack.d.ts +4 -0
  45. package/dist/adapters/packaged-assets/supported-stack.js +18 -0
  46. package/dist/adapters/packaged-assets/supported-stack.js.map +1 -0
  47. package/dist/adapters/packaged-assets/template-assets.d.ts +23 -0
  48. package/dist/adapters/packaged-assets/template-assets.js +36 -0
  49. package/dist/adapters/packaged-assets/template-assets.js.map +1 -0
  50. package/dist/adapters/process/shell-command.d.ts +5 -0
  51. package/dist/adapters/process/shell-command.js +21 -0
  52. package/dist/adapters/process/shell-command.js.map +1 -0
  53. package/dist/application/context.d.ts +20 -0
  54. package/dist/application/context.js +2 -0
  55. package/dist/application/context.js.map +1 -0
  56. package/dist/application/diagnose/doctor.d.ts +21 -0
  57. package/dist/application/diagnose/doctor.js +586 -0
  58. package/dist/application/diagnose/doctor.js.map +1 -0
  59. package/dist/application/diagnose/generated-project.d.ts +1 -0
  60. package/dist/application/diagnose/generated-project.js +105 -0
  61. package/dist/application/diagnose/generated-project.js.map +1 -0
  62. package/dist/application/diagnose/validate.d.ts +6 -0
  63. package/dist/application/diagnose/validate.js +27 -0
  64. package/dist/application/diagnose/validate.js.map +1 -0
  65. package/dist/application/initialize/fixture.d.ts +2 -0
  66. package/dist/application/initialize/fixture.js +39 -0
  67. package/dist/application/initialize/fixture.js.map +1 -0
  68. package/dist/application/initialize/inputs.d.ts +3 -0
  69. package/dist/application/initialize/inputs.js +35 -0
  70. package/dist/application/initialize/inputs.js.map +1 -0
  71. package/dist/application/initialize/use-case.d.ts +23 -0
  72. package/dist/application/initialize/use-case.js +360 -0
  73. package/dist/application/initialize/use-case.js.map +1 -0
  74. package/dist/application/migrate/use-case.d.ts +7 -0
  75. package/dist/application/migrate/use-case.js +378 -0
  76. package/dist/application/migrate/use-case.js.map +1 -0
  77. package/dist/application/project/catalog.d.ts +46 -0
  78. package/dist/application/project/catalog.js +12 -0
  79. package/dist/application/project/catalog.js.map +1 -0
  80. package/dist/application/project/manifest.d.ts +2 -0
  81. package/dist/application/project/manifest.js +29 -0
  82. package/dist/application/project/manifest.js.map +1 -0
  83. package/dist/application/project/planning.d.ts +6 -0
  84. package/dist/application/project/planning.js +12 -0
  85. package/dist/application/project/planning.js.map +1 -0
  86. package/dist/application/update/planning.d.ts +40 -0
  87. package/dist/application/update/planning.js +293 -0
  88. package/dist/application/update/planning.js.map +1 -0
  89. package/dist/application/update/reporting.d.ts +42 -0
  90. package/dist/application/update/reporting.js +325 -0
  91. package/dist/application/update/reporting.js.map +1 -0
  92. package/dist/application/update/use-case.d.ts +8 -0
  93. package/dist/application/update/use-case.js +600 -0
  94. package/dist/application/update/use-case.js.map +1 -0
  95. package/dist/application/upgrade/use-case.d.ts +6 -0
  96. package/dist/application/upgrade/use-case.js +82 -0
  97. package/dist/application/upgrade/use-case.js.map +1 -0
  98. package/dist/args.d.ts +5 -65
  99. package/dist/args.js +4 -441
  100. package/dist/args.js.map +1 -1
  101. package/dist/artifact-lifecycle.d.ts +1 -21
  102. package/dist/artifact-lifecycle.js +1 -73
  103. package/dist/artifact-lifecycle.js.map +1 -1
  104. package/dist/catalogs.d.ts +1 -50
  105. package/dist/catalogs.js +1 -472
  106. package/dist/catalogs.js.map +1 -1
  107. package/dist/cli/args/contracts.d.ts +51 -0
  108. package/dist/cli/args/contracts.js +2 -0
  109. package/dist/cli/args/contracts.js.map +1 -0
  110. package/dist/cli/args/definitions.d.ts +6 -0
  111. package/dist/cli/args/definitions.js +187 -0
  112. package/dist/cli/args/definitions.js.map +1 -0
  113. package/dist/cli/args/help.d.ts +5 -0
  114. package/dist/cli/args/help.js +130 -0
  115. package/dist/cli/args/help.js.map +1 -0
  116. package/dist/cli/args/parser.d.ts +5 -0
  117. package/dist/cli/args/parser.js +145 -0
  118. package/dist/cli/args/parser.js.map +1 -0
  119. package/dist/cli/args/readers.d.ts +4 -0
  120. package/dist/cli/args/readers.js +19 -0
  121. package/dist/cli/args/readers.js.map +1 -0
  122. package/dist/cli/commands/diagnose.d.ts +4 -0
  123. package/dist/cli/commands/diagnose.js +12 -0
  124. package/dist/cli/commands/diagnose.js.map +1 -0
  125. package/dist/cli/commands/dispatch.d.ts +3 -0
  126. package/dist/cli/commands/dispatch.js +94 -0
  127. package/dist/cli/commands/dispatch.js.map +1 -0
  128. package/dist/cli/commands/help.d.ts +3 -0
  129. package/dist/cli/commands/help.js +32 -0
  130. package/dist/cli/commands/help.js.map +1 -0
  131. package/dist/cli/commands/helpers.d.ts +8 -0
  132. package/dist/cli/commands/helpers.js +97 -0
  133. package/dist/cli/commands/helpers.js.map +1 -0
  134. package/dist/cli/commands/initialize.d.ts +3 -0
  135. package/dist/cli/commands/initialize.js +7 -0
  136. package/dist/cli/commands/initialize.js.map +1 -0
  137. package/dist/cli/commands/migrate.d.ts +3 -0
  138. package/dist/cli/commands/migrate.js +8 -0
  139. package/dist/cli/commands/migrate.js.map +1 -0
  140. package/dist/cli/commands/plan.d.ts +3 -0
  141. package/dist/cli/commands/plan.js +34 -0
  142. package/dist/cli/commands/plan.js.map +1 -0
  143. package/dist/cli/commands/reference.d.ts +5 -0
  144. package/dist/cli/commands/reference.js +43 -0
  145. package/dist/cli/commands/reference.js.map +1 -0
  146. package/dist/cli/commands/update.d.ts +3 -0
  147. package/dist/cli/commands/update.js +9 -0
  148. package/dist/cli/commands/update.js.map +1 -0
  149. package/dist/cli/commands/upgrade.d.ts +3 -0
  150. package/dist/cli/commands/upgrade.js +7 -0
  151. package/dist/cli/commands/upgrade.js.map +1 -0
  152. package/dist/cli/context.d.ts +1 -0
  153. package/dist/cli/context.js +2 -0
  154. package/dist/cli/context.js.map +1 -0
  155. package/dist/cli/project-options.d.ts +3 -0
  156. package/dist/cli/project-options.js +41 -0
  157. package/dist/cli/project-options.js.map +1 -0
  158. package/dist/cli.d.ts +3 -3
  159. package/dist/cli.js +4 -3
  160. package/dist/cli.js.map +1 -1
  161. package/dist/commands.d.ts +4 -35
  162. package/dist/commands.js +3 -2812
  163. package/dist/commands.js.map +1 -1
  164. package/dist/container-validation.d.ts +1 -1
  165. package/dist/domain/governance/activation/approvals.d.ts +351 -0
  166. package/dist/domain/governance/activation/approvals.js +528 -0
  167. package/dist/domain/governance/activation/approvals.js.map +1 -0
  168. package/dist/domain/governance/activation/canonical-json.d.ts +4 -0
  169. package/dist/domain/governance/activation/canonical-json.js +39 -0
  170. package/dist/domain/governance/activation/canonical-json.js.map +1 -0
  171. package/dist/domain/governance/activation/capabilities.d.ts +7 -0
  172. package/dist/domain/governance/activation/capabilities.js +33 -0
  173. package/dist/domain/governance/activation/capabilities.js.map +1 -0
  174. package/dist/domain/governance/activation/evidence.d.ts +63 -0
  175. package/dist/domain/governance/activation/evidence.js +444 -0
  176. package/dist/domain/governance/activation/evidence.js.map +1 -0
  177. package/dist/domain/governance/activation/graph.d.ts +397 -0
  178. package/dist/domain/governance/activation/graph.js +441 -0
  179. package/dist/domain/governance/activation/graph.js.map +1 -0
  180. package/dist/domain/governance/activation/inputs.d.ts +25 -0
  181. package/dist/domain/governance/activation/inputs.js +63 -0
  182. package/dist/domain/governance/activation/inputs.js.map +1 -0
  183. package/dist/domain/governance/activation/operations.d.ts +19 -0
  184. package/dist/domain/governance/activation/operations.js +181 -0
  185. package/dist/domain/governance/activation/operations.js.map +1 -0
  186. package/dist/domain/governance/activation/readiness.d.ts +27 -0
  187. package/dist/domain/governance/activation/readiness.js +269 -0
  188. package/dist/domain/governance/activation/readiness.js.map +1 -0
  189. package/dist/domain/governance/activation/types.d.ts +399 -0
  190. package/dist/domain/governance/activation/types.js +109 -0
  191. package/dist/domain/governance/activation/types.js.map +1 -0
  192. package/dist/domain/governance/activation/validators.d.ts +22 -0
  193. package/dist/domain/governance/activation/validators.js +1347 -0
  194. package/dist/domain/governance/activation/validators.js.map +1 -0
  195. package/dist/domain/governance/assessment/catalog.d.ts +14 -0
  196. package/dist/domain/governance/assessment/catalog.js +105 -0
  197. package/dist/domain/governance/assessment/catalog.js.map +1 -0
  198. package/dist/domain/governance/assessment/errors.d.ts +10 -0
  199. package/dist/domain/governance/assessment/errors.js +22 -0
  200. package/dist/domain/governance/assessment/errors.js.map +1 -0
  201. package/dist/domain/governance/assessment/index.d.ts +8 -0
  202. package/dist/domain/governance/assessment/index.js +9 -0
  203. package/dist/domain/governance/assessment/index.js.map +1 -0
  204. package/dist/domain/governance/assessment/live-normalize.d.ts +19 -0
  205. package/dist/domain/governance/assessment/live-normalize.js +403 -0
  206. package/dist/domain/governance/assessment/live-normalize.js.map +1 -0
  207. package/dist/domain/governance/assessment/predicates.d.ts +36 -0
  208. package/dist/domain/governance/assessment/predicates.js +545 -0
  209. package/dist/domain/governance/assessment/predicates.js.map +1 -0
  210. package/dist/domain/governance/assessment/report.d.ts +23 -0
  211. package/dist/domain/governance/assessment/report.js +266 -0
  212. package/dist/domain/governance/assessment/report.js.map +1 -0
  213. package/dist/domain/governance/assessment/sanitize.d.ts +8 -0
  214. package/dist/domain/governance/assessment/sanitize.js +60 -0
  215. package/dist/domain/governance/assessment/sanitize.js.map +1 -0
  216. package/dist/domain/governance/assessment/types.d.ts +174 -0
  217. package/dist/domain/governance/assessment/types.js +13 -0
  218. package/dist/domain/governance/assessment/types.js.map +1 -0
  219. package/dist/domain/governance/assessment/yaml.d.ts +6 -0
  220. package/dist/domain/governance/assessment/yaml.js +30 -0
  221. package/dist/domain/governance/assessment/yaml.js.map +1 -0
  222. package/dist/domain/governance/policy/identity.d.ts +64 -0
  223. package/dist/domain/governance/policy/identity.js +112 -0
  224. package/dist/domain/governance/policy/identity.js.map +1 -0
  225. package/dist/domain/migration/dependencies.d.ts +7 -0
  226. package/dist/domain/migration/dependencies.js +221 -0
  227. package/dist/domain/migration/dependencies.js.map +1 -0
  228. package/dist/domain/migration/inventory.d.ts +3 -0
  229. package/dist/domain/migration/inventory.js +15 -0
  230. package/dist/domain/migration/inventory.js.map +1 -0
  231. package/dist/domain/project/artifact-lifecycle.d.ts +69 -0
  232. package/dist/domain/project/artifact-lifecycle.js +137 -0
  233. package/dist/domain/project/artifact-lifecycle.js.map +1 -0
  234. package/dist/domain/project/catalog.d.ts +48 -0
  235. package/dist/domain/project/catalog.js +507 -0
  236. package/dist/domain/project/catalog.js.map +1 -0
  237. package/dist/domain/project/contracts.d.ts +247 -0
  238. package/dist/domain/project/contracts.js +2 -0
  239. package/dist/domain/project/contracts.js.map +1 -0
  240. package/dist/domain/project/errors.d.ts +3 -0
  241. package/dist/domain/project/errors.js +7 -0
  242. package/dist/domain/project/errors.js.map +1 -0
  243. package/dist/domain/project/infrastructure-layout.d.ts +26 -0
  244. package/dist/domain/project/infrastructure-layout.js +124 -0
  245. package/dist/domain/project/infrastructure-layout.js.map +1 -0
  246. package/dist/domain/project/inputs.d.ts +21 -0
  247. package/dist/domain/project/inputs.js +41 -0
  248. package/dist/domain/project/inputs.js.map +1 -0
  249. package/dist/domain/project/manifest/artifacts.d.ts +8 -0
  250. package/dist/domain/project/manifest/artifacts.js +150 -0
  251. package/dist/domain/project/manifest/artifacts.js.map +1 -0
  252. package/dist/domain/project/manifest/context.d.ts +13 -0
  253. package/dist/domain/project/manifest/context.js +2 -0
  254. package/dist/domain/project/manifest/context.js.map +1 -0
  255. package/dist/domain/project/manifest/fields.d.ts +6 -0
  256. package/dist/domain/project/manifest/fields.js +36 -0
  257. package/dist/domain/project/manifest/fields.js.map +1 -0
  258. package/dist/domain/project/manifest/governance.d.ts +8 -0
  259. package/dist/domain/project/manifest/governance.js +161 -0
  260. package/dist/domain/project/manifest/governance.js.map +1 -0
  261. package/dist/domain/project/manifest/project-identity.d.ts +6 -0
  262. package/dist/domain/project/manifest/project-identity.js +273 -0
  263. package/dist/domain/project/manifest/project-identity.js.map +1 -0
  264. package/dist/domain/project/manifest/reader.d.ts +9 -0
  265. package/dist/domain/project/manifest/reader.js +141 -0
  266. package/dist/domain/project/manifest/reader.js.map +1 -0
  267. package/dist/domain/project/paths.d.ts +2 -0
  268. package/dist/domain/project/paths.js +29 -0
  269. package/dist/domain/project/paths.js.map +1 -0
  270. package/dist/domain/project/planning.d.ts +19 -0
  271. package/dist/domain/project/planning.js +329 -0
  272. package/dist/domain/project/planning.js.map +1 -0
  273. package/dist/domain/project/retired-workload.d.ts +4 -0
  274. package/dist/domain/project/retired-workload.js +18 -0
  275. package/dist/domain/project/retired-workload.js.map +1 -0
  276. package/dist/domain/project/supported-stack.d.ts +113 -0
  277. package/dist/domain/project/supported-stack.js +426 -0
  278. package/dist/domain/project/supported-stack.js.map +1 -0
  279. package/dist/domain/workstation/constraints.d.ts +6 -0
  280. package/dist/domain/workstation/constraints.js +8 -0
  281. package/dist/domain/workstation/constraints.js.map +1 -0
  282. package/dist/file-system.d.ts +10 -41
  283. package/dist/file-system.js +9 -1204
  284. package/dist/file-system.js.map +1 -1
  285. package/dist/framework-adapters.d.ts +1 -1
  286. package/dist/framework-validation.d.ts +1 -1
  287. package/dist/framework-validation.js +1 -1
  288. package/dist/framework-validation.js.map +1 -1
  289. package/dist/genai-templates.d.ts +2 -9
  290. package/dist/genai-templates.js +4 -5
  291. package/dist/genai-templates.js.map +1 -1
  292. package/dist/generators/common/artifacts.d.ts +6 -0
  293. package/dist/generators/common/artifacts.js +30 -0
  294. package/dist/generators/common/artifacts.js.map +1 -0
  295. package/dist/generators/common/base.d.ts +17 -0
  296. package/dist/generators/common/base.js +421 -0
  297. package/dist/generators/common/base.js.map +1 -0
  298. package/dist/generators/common/dotenv-validation.d.ts +2 -0
  299. package/dist/generators/common/dotenv-validation.js +80 -0
  300. package/dist/generators/common/dotenv-validation.js.map +1 -0
  301. package/dist/generators/common/environments.d.ts +3 -0
  302. package/dist/generators/common/environments.js +15 -0
  303. package/dist/generators/common/environments.js.map +1 -0
  304. package/dist/generators/common/frontend.d.ts +15 -0
  305. package/dist/generators/common/frontend.js +166 -0
  306. package/dist/generators/common/frontend.js.map +1 -0
  307. package/dist/generators/common/python-settings.d.ts +2 -0
  308. package/dist/generators/common/python-settings.js +70 -0
  309. package/dist/generators/common/python-settings.js.map +1 -0
  310. package/dist/generators/common/spec-workflow.d.ts +28 -0
  311. package/dist/generators/common/spec-workflow.js +567 -0
  312. package/dist/generators/common/spec-workflow.js.map +1 -0
  313. package/dist/generators/common/values.d.ts +13 -0
  314. package/dist/generators/common/values.js +16 -0
  315. package/dist/generators/common/values.js.map +1 -0
  316. package/dist/generators/containers/compose.d.ts +7 -0
  317. package/dist/generators/containers/compose.js +196 -0
  318. package/dist/generators/containers/compose.js.map +1 -0
  319. package/dist/generators/containers/context.d.ts +1 -0
  320. package/dist/generators/containers/context.js +43 -0
  321. package/dist/generators/containers/context.js.map +1 -0
  322. package/dist/generators/containers/images.d.ts +7 -0
  323. package/dist/generators/containers/images.js +119 -0
  324. package/dist/generators/containers/images.js.map +1 -0
  325. package/dist/generators/context.d.ts +42 -0
  326. package/dist/generators/context.js +38 -0
  327. package/dist/generators/context.js.map +1 -0
  328. package/dist/generators/genai/backend.d.ts +20 -0
  329. package/dist/generators/genai/backend.js +667 -0
  330. package/dist/generators/genai/backend.js.map +1 -0
  331. package/dist/generators/genai/configuration.d.ts +3 -0
  332. package/dist/generators/genai/configuration.js +43 -0
  333. package/dist/generators/genai/configuration.js.map +1 -0
  334. package/dist/generators/genai/database.d.ts +7 -0
  335. package/dist/generators/genai/database.js +71 -0
  336. package/dist/generators/genai/database.js.map +1 -0
  337. package/dist/generators/genai/functions.d.ts +15 -0
  338. package/dist/generators/genai/functions.js +156 -0
  339. package/dist/generators/genai/functions.js.map +1 -0
  340. package/dist/generators/genai/index.d.ts +8 -0
  341. package/dist/generators/genai/index.js +11 -0
  342. package/dist/generators/genai/index.js.map +1 -0
  343. package/dist/generators/genai/patterns.d.ts +9 -0
  344. package/dist/generators/genai/patterns.js +309 -0
  345. package/dist/generators/genai/patterns.js.map +1 -0
  346. package/dist/generators/infrastructure/azure.d.ts +18 -0
  347. package/dist/generators/infrastructure/azure.js +655 -0
  348. package/dist/generators/infrastructure/azure.js.map +1 -0
  349. package/dist/generators/infrastructure/names.d.ts +23 -0
  350. package/dist/generators/infrastructure/names.js +51 -0
  351. package/dist/generators/infrastructure/names.js.map +1 -0
  352. package/dist/generators/standard/configuration.d.ts +3 -0
  353. package/dist/generators/standard/configuration.js +26 -0
  354. package/dist/generators/standard/configuration.js.map +1 -0
  355. package/dist/generators/standard/go.d.ts +17 -0
  356. package/dist/generators/standard/go.js +338 -0
  357. package/dist/generators/standard/go.js.map +1 -0
  358. package/dist/generators/standard/index.d.ts +12 -0
  359. package/dist/generators/standard/index.js +12 -0
  360. package/dist/generators/standard/index.js.map +1 -0
  361. package/dist/generators/standard/node.d.ts +20 -0
  362. package/dist/generators/standard/node.js +314 -0
  363. package/dist/generators/standard/node.js.map +1 -0
  364. package/dist/generators/standard/python.d.ts +18 -0
  365. package/dist/generators/standard/python.js +191 -0
  366. package/dist/generators/standard/python.js.map +1 -0
  367. package/dist/go-template-assets.js +3 -3
  368. package/dist/go-template-assets.js.map +1 -1
  369. package/dist/governance-activation/activation-state.d.ts +1 -1
  370. package/dist/governance-activation/activation-state.js +46 -9
  371. package/dist/governance-activation/activation-state.js.map +1 -1
  372. package/dist/governance-activation/approvals.d.ts +1 -188
  373. package/dist/governance-activation/approvals.js +1 -507
  374. package/dist/governance-activation/approvals.js.map +1 -1
  375. package/dist/governance-activation/canonical-json.d.ts +1 -3
  376. package/dist/governance-activation/canonical-json.js +1 -35
  377. package/dist/governance-activation/canonical-json.js.map +1 -1
  378. package/dist/governance-activation/commands.d.ts +1 -1
  379. package/dist/governance-activation/commands.js +107 -103
  380. package/dist/governance-activation/commands.js.map +1 -1
  381. package/dist/governance-activation/compatibility.d.ts +11 -3
  382. package/dist/governance-activation/compatibility.js +31 -4
  383. package/dist/governance-activation/compatibility.js.map +1 -1
  384. package/dist/governance-activation/credentials.d.ts +3 -3
  385. package/dist/governance-activation/credentials.js +5 -5
  386. package/dist/governance-activation/credentials.js.map +1 -1
  387. package/dist/governance-activation/doctor.d.ts +1 -1
  388. package/dist/governance-activation/doctor.js +28 -96
  389. package/dist/governance-activation/doctor.js.map +1 -1
  390. package/dist/governance-activation/evidence.d.ts +1 -49
  391. package/dist/governance-activation/evidence.js +1 -245
  392. package/dist/governance-activation/evidence.js.map +1 -1
  393. package/dist/governance-activation/git-ignore.d.ts +9 -0
  394. package/dist/governance-activation/git-ignore.js +76 -0
  395. package/dist/governance-activation/git-ignore.js.map +1 -0
  396. package/dist/governance-activation/graph.d.ts +1 -397
  397. package/dist/governance-activation/graph.js +1 -440
  398. package/dist/governance-activation/graph.js.map +1 -1
  399. package/dist/governance-activation/identity.d.ts +1 -35
  400. package/dist/governance-activation/identity.js +1 -88
  401. package/dist/governance-activation/identity.js.map +1 -1
  402. package/dist/governance-activation/index.d.ts +3 -0
  403. package/dist/governance-activation/index.js +3 -0
  404. package/dist/governance-activation/index.js.map +1 -1
  405. package/dist/governance-activation/inputs.d.ts +8 -0
  406. package/dist/governance-activation/inputs.js +146 -0
  407. package/dist/governance-activation/inputs.js.map +1 -0
  408. package/dist/governance-activation/migration.d.ts +4 -3
  409. package/dist/governance-activation/migration.js +14 -6
  410. package/dist/governance-activation/migration.js.map +1 -1
  411. package/dist/governance-activation/phase-bootstrap-state.d.ts +3 -0
  412. package/dist/governance-activation/phase-bootstrap-state.js +128 -0
  413. package/dist/governance-activation/phase-bootstrap-state.js.map +1 -0
  414. package/dist/governance-activation/phase-discovery.d.ts +2 -0
  415. package/dist/governance-activation/phase-discovery.js +88 -0
  416. package/dist/governance-activation/phase-discovery.js.map +1 -0
  417. package/dist/governance-activation/phase-governance.d.ts +4 -0
  418. package/dist/governance-activation/phase-governance.js +141 -0
  419. package/dist/governance-activation/phase-governance.js.map +1 -0
  420. package/dist/governance-activation/phase-publication.d.ts +8 -0
  421. package/dist/governance-activation/phase-publication.js +318 -0
  422. package/dist/governance-activation/phase-publication.js.map +1 -0
  423. package/dist/governance-activation/read-only.d.ts +30 -0
  424. package/dist/governance-activation/read-only.js +93 -0
  425. package/dist/governance-activation/read-only.js.map +1 -0
  426. package/dist/governance-activation/readiness.d.ts +1 -24
  427. package/dist/governance-activation/readiness.js +1 -220
  428. package/dist/governance-activation/readiness.js.map +1 -1
  429. package/dist/governance-activation/reconciliation.d.ts +1 -1
  430. package/dist/governance-activation/reconciliation.js +3 -3
  431. package/dist/governance-activation/reconciliation.js.map +1 -1
  432. package/dist/governance-activation/release-integrity.d.ts +1 -1
  433. package/dist/governance-activation/release-integrity.js +2 -2
  434. package/dist/governance-activation/release-integrity.js.map +1 -1
  435. package/dist/governance-activation/seed-lifecycle.d.ts +10 -2
  436. package/dist/governance-activation/seed-lifecycle.js +244 -66
  437. package/dist/governance-activation/seed-lifecycle.js.map +1 -1
  438. package/dist/governance-activation/source-of-truth.d.ts +5 -3
  439. package/dist/governance-activation/source-of-truth.js +32 -52
  440. package/dist/governance-activation/source-of-truth.js.map +1 -1
  441. package/dist/governance-activation/spec-kit-seed.d.ts +9 -0
  442. package/dist/governance-activation/spec-kit-seed.js +43 -0
  443. package/dist/governance-activation/spec-kit-seed.js.map +1 -0
  444. package/dist/governance-activation/task-projection.d.ts +1 -1
  445. package/dist/governance-activation/transition-planning.d.ts +15 -0
  446. package/dist/governance-activation/transition-planning.js +250 -0
  447. package/dist/governance-activation/transition-planning.js.map +1 -0
  448. package/dist/governance-activation/transition-ports.d.ts +150 -0
  449. package/dist/governance-activation/transition-ports.js +2 -0
  450. package/dist/governance-activation/transition-ports.js.map +1 -0
  451. package/dist/governance-activation/transition-process.d.ts +7 -0
  452. package/dist/governance-activation/transition-process.js +21 -0
  453. package/dist/governance-activation/transition-process.js.map +1 -0
  454. package/dist/governance-activation/transition-records.d.ts +56 -0
  455. package/dist/governance-activation/transition-records.js +208 -0
  456. package/dist/governance-activation/transition-records.js.map +1 -0
  457. package/dist/governance-activation/transitions.d.ts +6 -157
  458. package/dist/governance-activation/transitions.js +143 -2045
  459. package/dist/governance-activation/transitions.js.map +1 -1
  460. package/dist/governance-activation/types.d.ts +1 -390
  461. package/dist/governance-activation/types.js +1 -107
  462. package/dist/governance-activation/types.js.map +1 -1
  463. package/dist/governance-activation/validators.d.ts +1 -17
  464. package/dist/governance-activation/validators.js +1 -1304
  465. package/dist/governance-activation/validators.js.map +1 -1
  466. package/dist/governance-assessment/catalog.d.ts +7 -0
  467. package/dist/governance-assessment/catalog.js +31 -0
  468. package/dist/governance-assessment/catalog.js.map +1 -0
  469. package/dist/governance-assessment/command.d.ts +10 -0
  470. package/dist/governance-assessment/command.js +77 -0
  471. package/dist/governance-assessment/command.js.map +1 -0
  472. package/dist/governance-assessment/engine.d.ts +14 -0
  473. package/dist/governance-assessment/engine.js +935 -0
  474. package/dist/governance-assessment/engine.js.map +1 -0
  475. package/dist/governance-assessment/index.d.ts +5 -0
  476. package/dist/governance-assessment/index.js +6 -0
  477. package/dist/governance-assessment/index.js.map +1 -0
  478. package/dist/governance-assessment/live-normalize.d.ts +1 -0
  479. package/dist/governance-assessment/live-normalize.js +2 -0
  480. package/dist/governance-assessment/live-normalize.js.map +1 -0
  481. package/dist/governance-assessment/live-transport.d.ts +34 -0
  482. package/dist/governance-assessment/live-transport.js +455 -0
  483. package/dist/governance-assessment/live-transport.js.map +1 -0
  484. package/dist/governance-assessment/live.d.ts +2 -0
  485. package/dist/governance-assessment/live.js +689 -0
  486. package/dist/governance-assessment/live.js.map +1 -0
  487. package/dist/governance-assessment/predicates.d.ts +1 -0
  488. package/dist/governance-assessment/predicates.js +2 -0
  489. package/dist/governance-assessment/predicates.js.map +1 -0
  490. package/dist/governance-assessment/project.d.ts +33 -0
  491. package/dist/governance-assessment/project.js +178 -0
  492. package/dist/governance-assessment/project.js.map +1 -0
  493. package/dist/governance-assessment/readers.d.ts +14 -0
  494. package/dist/governance-assessment/readers.js +122 -0
  495. package/dist/governance-assessment/readers.js.map +1 -0
  496. package/dist/governance-assessment/report.d.ts +1 -0
  497. package/dist/governance-assessment/report.js +2 -0
  498. package/dist/governance-assessment/report.js.map +1 -0
  499. package/dist/governance-assessment/sanitize.d.ts +1 -0
  500. package/dist/governance-assessment/sanitize.js +2 -0
  501. package/dist/governance-assessment/sanitize.js.map +1 -0
  502. package/dist/governance-assessment/types.d.ts +6 -0
  503. package/dist/governance-assessment/types.js +2 -0
  504. package/dist/governance-assessment/types.js.map +1 -0
  505. package/dist/governance-assessment/yaml.d.ts +1 -0
  506. package/dist/governance-assessment/yaml.js +2 -0
  507. package/dist/governance-assessment/yaml.js.map +1 -0
  508. package/dist/init-filesystem.d.ts +1 -1
  509. package/dist/init-filesystem.js +126 -174
  510. package/dist/init-filesystem.js.map +1 -1
  511. package/dist/interactive.d.ts +2 -2
  512. package/dist/interactive.js +42 -41
  513. package/dist/interactive.js.map +1 -1
  514. package/dist/migrate-plan.d.ts +5 -1
  515. package/dist/migrate-plan.js +87 -10
  516. package/dist/migrate-plan.js.map +1 -1
  517. package/dist/npm-template-assets.js +5 -4
  518. package/dist/npm-template-assets.js.map +1 -1
  519. package/dist/openspec-profile.d.ts +1 -1
  520. package/dist/opentofu-template-assets.js +3 -3
  521. package/dist/opentofu-template-assets.js.map +1 -1
  522. package/dist/package-identity.d.ts +3 -0
  523. package/dist/package-identity.js +13 -2
  524. package/dist/package-identity.js.map +1 -1
  525. package/dist/planner.d.ts +1 -19
  526. package/dist/planner.js +1 -565
  527. package/dist/planner.js.map +1 -1
  528. package/dist/process-runner.d.ts +5 -1
  529. package/dist/process-runner.js +164 -8
  530. package/dist/process-runner.js.map +1 -1
  531. package/dist/project-dependencies.d.ts +5 -3
  532. package/dist/project-dependencies.js +74 -63
  533. package/dist/project-dependencies.js.map +1 -1
  534. package/dist/published-verifier.js +67 -30
  535. package/dist/published-verifier.js.map +1 -1
  536. package/dist/python-template-assets.js +6 -9
  537. package/dist/python-template-assets.js.map +1 -1
  538. package/dist/reconcile.d.ts +1 -1
  539. package/dist/reconcile.js +2 -2
  540. package/dist/reconcile.js.map +1 -1
  541. package/dist/release-identity.js +19 -0
  542. package/dist/release-identity.js.map +1 -1
  543. package/dist/repository-governance.d.ts +10 -2
  544. package/dist/repository-governance.js +240 -99
  545. package/dist/repository-governance.js.map +1 -1
  546. package/dist/runtime.js +1 -1
  547. package/dist/runtime.js.map +1 -1
  548. package/dist/scan.d.ts +6 -2
  549. package/dist/scan.js +78 -30
  550. package/dist/scan.js.map +1 -1
  551. package/dist/self-upgrade.d.ts +1 -1
  552. package/dist/self-upgrade.js +20 -7
  553. package/dist/self-upgrade.js.map +1 -1
  554. package/dist/stable-release.js +7 -1
  555. package/dist/stable-release.js.map +1 -1
  556. package/dist/standard-templates.d.ts +2 -2
  557. package/dist/standard-templates.js +6 -841
  558. package/dist/standard-templates.js.map +1 -1
  559. package/dist/supported-stack.d.ts +3 -115
  560. package/dist/supported-stack.js +4 -438
  561. package/dist/supported-stack.js.map +1 -1
  562. package/dist/telemetry/contract.d.ts +2 -0
  563. package/dist/telemetry/contract.js +7 -0
  564. package/dist/telemetry/contract.js.map +1 -1
  565. package/dist/telemetry/index.d.ts +1 -1
  566. package/dist/templates.d.ts +10 -20
  567. package/dist/templates.js +52 -3238
  568. package/dist/templates.js.map +1 -1
  569. package/dist/types.d.ts +1 -263
  570. package/dist/types.js +1 -1
  571. package/dist/types.js.map +1 -1
  572. package/dist/version.js +2 -6
  573. package/dist/version.js.map +1 -1
  574. package/dist/workstation-catalog.d.ts +5 -2
  575. package/dist/workstation-catalog.js +33 -2
  576. package/dist/workstation-catalog.js.map +1 -1
  577. package/dist/workstation.d.ts +4 -3
  578. package/dist/workstation.js +86 -32
  579. package/dist/workstation.js.map +1 -1
  580. package/docs/assets/liftoff-terminal.svg +3 -3
  581. package/docs/azure-deployment.md +107 -10
  582. package/docs/cli-reference.md +127 -11
  583. package/docs/configuration-and-manifests.md +150 -35
  584. package/docs/existing-repositories.md +33 -6
  585. package/docs/getting-started.md +44 -31
  586. package/docs/prerequisites.md +34 -35
  587. package/docs/project-structure.md +45 -47
  588. package/docs/repository-governance.md +207 -24
  589. package/docs/safety-and-consent.md +65 -12
  590. package/docs/spec-workflows-and-agents.md +31 -28
  591. package/docs/supported-stack.md +11 -9
  592. package/docs/telemetry.md +9 -3
  593. package/docs/troubleshooting.md +107 -49
  594. package/docs/workloads.md +53 -62
  595. package/package.json +6 -8
  596. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/UPSTREAM_LICENSE.txt +0 -21
  597. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/catalog.json +0 -520
  598. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/packaged/gitignore +0 -27
  599. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/README.md +0 -25
  600. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/components.json +0 -22
  601. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/eslint.config.js +0 -23
  602. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/index.html +0 -13
  603. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package-lock.json +0 -6156
  604. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package.json +0 -60
  605. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/public/power-apps.svg +0 -55
  606. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/App.tsx +0 -17
  607. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/assets/react.svg +0 -1
  608. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/mode-toggle.tsx +0 -37
  609. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/badge.tsx +0 -46
  610. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/button.tsx +0 -60
  611. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/calendar.tsx +0 -211
  612. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/card.tsx +0 -92
  613. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/chart.tsx +0 -355
  614. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/checkbox.tsx +0 -32
  615. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/command.tsx +0 -184
  616. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dialog.tsx +0 -141
  617. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dropdown-menu.tsx +0 -257
  618. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/input.tsx +0 -21
  619. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/label.tsx +0 -22
  620. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/popover.tsx +0 -46
  621. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/progress.tsx +0 -29
  622. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/select.tsx +0 -185
  623. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/separator.tsx +0 -26
  624. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/skeleton.tsx +0 -13
  625. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/table.tsx +0 -114
  626. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tabs.tsx +0 -66
  627. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/textarea.tsx +0 -18
  628. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tooltip.tsx +0 -61
  629. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/hooks/use-theme.ts +0 -11
  630. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/index.css +0 -131
  631. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/lib/utils.ts +0 -6
  632. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/main.tsx +0 -10
  633. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/_layout.tsx +0 -31
  634. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/home.tsx +0 -59
  635. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/not-found.tsx +0 -14
  636. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/query-provider.tsx +0 -26
  637. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/sonner-provider.tsx +0 -23
  638. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/theme-provider.tsx +0 -64
  639. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/router.tsx +0 -24
  640. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.app.json +0 -34
  641. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.json +0 -13
  642. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.node.json +0 -26
  643. package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/vite.config.ts +0 -19
  644. package/assets/power-apps-code-app/README.md +0 -27
  645. package/dist/code-apps-plugin.d.ts +0 -13
  646. package/dist/code-apps-plugin.js +0 -69
  647. package/dist/code-apps-plugin.js.map +0 -1
  648. package/dist/power-apps-assets.d.ts +0 -30
  649. package/dist/power-apps-assets.js +0 -131
  650. package/dist/power-apps-assets.js.map +0 -1
  651. package/dist/power-apps-templates.d.ts +0 -3
  652. package/dist/power-apps-templates.js +0 -173
  653. package/dist/power-apps-templates.js.map +0 -1
  654. package/dist/power-apps-validation.d.ts +0 -1
  655. package/dist/power-apps-validation.js +0 -79
  656. package/dist/power-apps-validation.js.map +0 -1
@@ -0,0 +1,18 @@
1
+ import type { GeneratorContext as ResolvedGeneratorContext } from '../context.js';
2
+ type GeneratorContext = Pick<ResolvedGeneratorContext, 'opentofu' | 'stack'>;
3
+ import type { AddArtifact } from '../../template-types.js';
4
+ import type { ApiProjectPlan } from '../../domain/project/contracts.js';
5
+ import type { GeneratedArtifact } from '../../domain/project/contracts.js';
6
+ export declare function addInfrastructureArtifacts(add: AddArtifact, artifacts: GeneratedArtifact[], plan: ApiProjectPlan, context: GeneratorContext): void;
7
+ export declare function renderTofuRootVariables(plan: ApiProjectPlan, environment: string, context: GeneratorContext): string;
8
+ export declare function renderTofuRootMain(plan: ApiProjectPlan): string;
9
+ export declare function renderTofuRootOutputs(plan: ApiProjectPlan): string;
10
+ export declare function renderTofuProviders(): string;
11
+ export declare function renderTofuVariables(plan: ApiProjectPlan, context: GeneratorContext): string;
12
+ export declare function renderTofuMain(plan: ApiProjectPlan): string;
13
+ export declare function renderTofuOutputs(plan: ApiProjectPlan): string;
14
+ export declare function renderTofuLocalState(environment: string): string;
15
+ export declare function renderTofuRemoteStateExample(plan: ApiProjectPlan, environment: string): string;
16
+ export declare function renderTofuReadme(plan: ApiProjectPlan): string;
17
+ export declare function renderTofuTfvars(plan: ApiProjectPlan, environment: string, context: GeneratorContext): string;
18
+ export {};
@@ -0,0 +1,655 @@
1
+ import { buildAzureResourceNames } from './names.js';
2
+ import { createArtifactAdder } from '../common/artifacts.js';
3
+ import { DEFAULT_FUNCTION_WORKER_QUEUE_NAME } from '../common/values.js';
4
+ import { formatContainerImage } from '../../domain/project/supported-stack.js';
5
+ import { functionWorkerName } from '../common/values.js';
6
+ import { genAiPattern } from '../common/values.js';
7
+ import { hasFunctionWorker } from '../common/values.js';
8
+ import { selectedEnvironmentId } from '../common/values.js';
9
+ import { projectIdentityDigest, stableResourceSuffix } from './names.js';
10
+ export function addInfrastructureArtifacts(add, artifacts, plan, context) {
11
+ const base = ['infrastructure', 'opentofu', 'azure'];
12
+ const application = [...base, 'modules', 'application'];
13
+ add('opentofu-application-versions', 'infrastructure', [...application, 'versions.tf'], context.opentofu.versions);
14
+ add('opentofu-application-variables', 'infrastructure', [...application, 'variables.tf'], renderTofuVariables(plan, context));
15
+ add('opentofu-application-main', 'infrastructure', [...application, 'main.tf'], renderTofuMain(plan));
16
+ add('opentofu-application-outputs', 'infrastructure', [...application, 'outputs.tf'], renderTofuOutputs(plan));
17
+ add('opentofu-readme', 'infrastructure', [...base, 'README.md'], renderTofuReadme(plan));
18
+ for (const environment of plan.environments) {
19
+ const addEnvironment = createArtifactAdder(artifacts, 'project', `environment:${environment.id}`);
20
+ const root = [...base, 'environments', environment.id];
21
+ const rootArtifacts = [
22
+ ['versions', 'versions.tf', context.opentofu.versions],
23
+ ['provider-lock', '.terraform.lock.hcl', context.opentofu.providerLock],
24
+ ['providers', 'providers.tf', renderTofuProviders()],
25
+ ['variables', 'variables.tf', renderTofuRootVariables(plan, environment.id, context)],
26
+ ['main', 'main.tf', renderTofuRootMain(plan)],
27
+ ['outputs', 'outputs.tf', renderTofuRootOutputs(plan)],
28
+ ['local-state', 'backend.local.tf', renderTofuLocalState(environment.id)],
29
+ ['remote-state-example', 'backend.remote.example.tf', renderTofuRemoteStateExample(plan, environment.id)],
30
+ ['tfvars', `${environment.id}.tfvars`, renderTofuTfvars(plan, environment.id, context)]
31
+ ];
32
+ for (const [identity, file, content] of rootArtifacts) {
33
+ addEnvironment(`opentofu-${environment.id}-${identity}`, 'infrastructure', [...root, file], content);
34
+ }
35
+ }
36
+ }
37
+ export function renderTofuRootVariables(plan, environment, context) {
38
+ return renderTofuVariables(plan, context).replace(' description = "Deployment environment name."', ` description = "Deployment environment name."
39
+ default = "${environment}"
40
+
41
+ validation {
42
+ condition = var.environment == "${environment}"
43
+ error_message = "This root only deploys ${environment}; select another environment root instead."
44
+ }`);
45
+ }
46
+ export function renderTofuRootMain(plan) {
47
+ const variables = [
48
+ 'environment', 'location', 'resource_suffix', 'backend_image', 'backend_target_port',
49
+ 'postgres_admin_password', 'enable_private_networking',
50
+ ...(plan.includeFrontend ? ['frontend_image'] : []),
51
+ ...(hasFunctionWorker(plan) ? ['function_worker_queue_name', 'functions_python_version'] : [])
52
+ ];
53
+ const width = Math.max(...variables.map((name) => name.length), 'source'.length);
54
+ return `module "application" {
55
+ ${'source'.padEnd(width)} = "../../modules/application"
56
+ ${variables.map((name) => ` ${name.padEnd(width)} = var.${name}`).join('\n')}
57
+ }
58
+ `;
59
+ }
60
+ export function renderTofuRootOutputs(plan) {
61
+ const outputs = [
62
+ 'backend_url', ...(plan.includeFrontend ? ['frontend_url'] : []),
63
+ ...(hasFunctionWorker(plan) ? ['function_app_name', 'function_worker_queue_name'] : []),
64
+ 'container_registry', 'container_registry_name',
65
+ ...(plan.workload === 'genai' && plan.pattern.id === 'rag'
66
+ ? ['service_bus_fully_qualified_namespace', 'service_bus_queue_name', 'backend_azure_client_id']
67
+ : [])
68
+ ];
69
+ return outputs.map((name) => `output "${name}" {
70
+ value = module.application.${name}
71
+ }
72
+ `).join('\n');
73
+ }
74
+ export function renderTofuProviders() {
75
+ return `provider "azurerm" {
76
+ features {}
77
+ }
78
+ `;
79
+ }
80
+ export function renderTofuVariables(plan, context) {
81
+ const frontendVariables = plan.includeFrontend ? `
82
+ variable "frontend_image" {
83
+ type = string
84
+ default = "${formatContainerImage(context.stack.containers['container-apps-bootstrap'])}"
85
+ description = "Frontend image. Replace the bootstrap image with the generated frontend image after pushing it to ACR."
86
+ }
87
+ ` : '';
88
+ const functionVariables = hasFunctionWorker(plan) ? `
89
+ variable "function_worker_queue_name" {
90
+ type = string
91
+ default = "events"
92
+ description = "Service Bus queue consumed by the generated Azure Functions worker."
93
+ }
94
+
95
+ variable "functions_python_version" {
96
+ type = string
97
+ default = "${context.stack.runtimes.python.releaseLine}"
98
+ description = "Python runtime version for the generated Azure Functions worker."
99
+ }
100
+ ` : '';
101
+ return `variable "environment" {
102
+ type = string
103
+ description = "Deployment environment name."
104
+ }
105
+
106
+ variable "location" {
107
+ type = string
108
+ description = "Azure region slug."
109
+ default = "${plan.region.slug}"
110
+ }
111
+
112
+ variable "resource_suffix" {
113
+ type = string
114
+ description = "Twelve-character lowercase alphanumeric suffix for globally scoped Azure resource names."
115
+
116
+ validation {
117
+ condition = can(regex("^[a-z0-9]{12}$", var.resource_suffix))
118
+ error_message = "resource_suffix must contain exactly 12 lowercase letters or numbers."
119
+ }
120
+ }
121
+
122
+ variable "backend_image" {
123
+ type = string
124
+ default = "${formatContainerImage(context.stack.containers['container-apps-bootstrap'])}"
125
+ description = "Backend image. Replace the bootstrap image with the generated backend image after pushing it to ACR."
126
+ }
127
+
128
+ variable "backend_target_port" {
129
+ type = number
130
+ default = 80
131
+ description = "Backend ingress port. Set to 8000 when switching from the bootstrap image to the generated backend."
132
+ }
133
+ ${frontendVariables}
134
+ variable "postgres_admin_password" {
135
+ type = string
136
+ sensitive = true
137
+ description = "PostgreSQL administrator password supplied at apply time."
138
+ }
139
+
140
+ variable "enable_private_networking" {
141
+ type = bool
142
+ default = false
143
+ description = "Enable production-oriented private-networking-ready settings."
144
+ }
145
+ ${functionVariables}
146
+ `;
147
+ }
148
+ export function renderTofuMain(plan) {
149
+ const functionPattern = plan.workload === 'genai' && hasFunctionWorker(plan)
150
+ ? genAiPattern(plan)
151
+ : undefined;
152
+ const names = buildAzureResourceNames(plan, '${var.environment}', '${var.resource_suffix}');
153
+ const queueName = hasFunctionWorker(plan)
154
+ ? 'var.function_worker_queue_name'
155
+ : JSON.stringify(DEFAULT_FUNCTION_WORKER_QUEUE_NAME);
156
+ const ragPublisher = plan.workload === 'genai' && plan.pattern.id === 'rag';
157
+ const publisherEnvironment = ragPublisher ? `
158
+ env {
159
+ name = "SERVICE_BUS_FULLY_QUALIFIED_NAMESPACE"
160
+ value = "\${azurerm_servicebus_namespace.main.name}.servicebus.windows.net"
161
+ }
162
+
163
+ env {
164
+ name = "SERVICE_BUS_QUEUE_NAME"
165
+ value = azurerm_servicebus_queue.events.name
166
+ }
167
+
168
+ env {
169
+ name = "SERVICE_BUS_AUTH_MODE"
170
+ value = "managed-identity"
171
+ }
172
+
173
+ env {
174
+ name = "AZURE_CLIENT_ID"
175
+ value = azurerm_user_assigned_identity.app.client_id
176
+ }
177
+ ` : '';
178
+ const senderRole = ragPublisher ? `
179
+ resource "azurerm_role_assignment" "backend_servicebus_sender" {
180
+ scope = azurerm_servicebus_queue.events.id
181
+ role_definition_name = "Azure Service Bus Data Sender"
182
+ principal_id = azurerm_user_assigned_identity.app.principal_id
183
+ }
184
+ ` : '';
185
+ const projectIdentityEnv = plan.workload === 'genai' ? `
186
+ env {
187
+ name = "GENAI_PATTERN"
188
+ value = "${genAiPattern(plan).id}"
189
+ }
190
+ ` : `
191
+ env {
192
+ name = "API_STACK"
193
+ value = "${plan.apiStack.id}"
194
+ }
195
+ `;
196
+ const frontendCorsEnvironment = plan.includeFrontend ? `
197
+ env {
198
+ name = "CORS_ALLOWED_ORIGINS"
199
+ value = "https://\${azurerm_container_app.frontend.ingress[0].fqdn}"
200
+ }
201
+ ` : '';
202
+ const frontendContainer = plan.includeFrontend ? `
203
+ resource "azurerm_container_app" "frontend" {
204
+ name = "${names.frontendContainerApp}"
205
+ container_app_environment_id = azurerm_container_app_environment.main.id
206
+ resource_group_name = azurerm_resource_group.main.name
207
+ revision_mode = "Single"
208
+
209
+ identity {
210
+ type = "UserAssigned"
211
+ identity_ids = [azurerm_user_assigned_identity.app.id]
212
+ }
213
+
214
+ registry {
215
+ server = azurerm_container_registry.main.login_server
216
+ identity = azurerm_user_assigned_identity.app.id
217
+ }
218
+
219
+ template {
220
+ container {
221
+ name = "frontend"
222
+ image = var.frontend_image
223
+ cpu = 0.25
224
+ memory = "0.5Gi"
225
+ }
226
+ }
227
+
228
+ ingress {
229
+ external_enabled = true
230
+ target_port = 80
231
+ traffic_weight {
232
+ percentage = 100
233
+ latest_revision = true
234
+ }
235
+ }
236
+
237
+ depends_on = [azurerm_role_assignment.acr_pull]
238
+ }
239
+ ` : '';
240
+ const functionWorker = hasFunctionWorker(plan) ? `
241
+ resource "azurerm_user_assigned_identity" "worker" {
242
+ name = "${names.functionIdentity}"
243
+ resource_group_name = azurerm_resource_group.main.name
244
+ location = azurerm_resource_group.main.location
245
+ }
246
+
247
+ resource "azurerm_service_plan" "functions" {
248
+ name = "${names.functionServicePlan}"
249
+ resource_group_name = azurerm_resource_group.main.name
250
+ location = azurerm_resource_group.main.location
251
+ os_type = "Linux"
252
+ sku_name = "Y1"
253
+ }
254
+
255
+ resource "azurerm_linux_function_app" "worker" {
256
+ name = "${names.functionApp}"
257
+ resource_group_name = azurerm_resource_group.main.name
258
+ location = azurerm_resource_group.main.location
259
+ service_plan_id = azurerm_service_plan.functions.id
260
+ storage_account_name = azurerm_storage_account.main.name
261
+ storage_account_access_key = azurerm_storage_account.main.primary_access_key
262
+
263
+ identity {
264
+ type = "UserAssigned"
265
+ identity_ids = [azurerm_user_assigned_identity.worker.id]
266
+ }
267
+
268
+ site_config {
269
+ application_stack {
270
+ python_version = var.functions_python_version
271
+ }
272
+ }
273
+
274
+ app_settings = {
275
+ APP_ENV = var.environment
276
+ APP_NAME = "${plan.safeProjectName}"
277
+ GENAI_PATTERN = "${functionPattern?.id}"
278
+ FUNCTIONS_WORKER_RUNTIME = "python"
279
+ SERVICEBUS_QUEUE_NAME = var.function_worker_queue_name
280
+ ServiceBusConnection__clientId = azurerm_user_assigned_identity.worker.client_id
281
+ ServiceBusConnection__fullyQualifiedNamespace = "\${azurerm_servicebus_namespace.main.name}.servicebus.windows.net"
282
+ SHARED_ORCHESTRATION_ROOT = "../../backend"
283
+ }
284
+ }
285
+
286
+ resource "azurerm_role_assignment" "function_servicebus_receiver" {
287
+ scope = azurerm_servicebus_queue.events.id
288
+ role_definition_name = "Azure Service Bus Data Receiver"
289
+ principal_id = azurerm_user_assigned_identity.worker.principal_id
290
+ }
291
+
292
+ resource "azurerm_role_assignment" "function_storage_blob_contributor" {
293
+ scope = azurerm_storage_account.main.id
294
+ role_definition_name = "Storage Blob Data Contributor"
295
+ principal_id = azurerm_user_assigned_identity.worker.principal_id
296
+ }
297
+ ` : '';
298
+ return `resource "azurerm_resource_group" "main" {
299
+ name = "${names.resourceGroup}"
300
+ location = var.location
301
+ }
302
+
303
+ resource "azurerm_container_registry" "main" {
304
+ name = "${names.containerRegistry}"
305
+ resource_group_name = azurerm_resource_group.main.name
306
+ location = azurerm_resource_group.main.location
307
+ sku = "Basic"
308
+ admin_enabled = false
309
+ }
310
+
311
+ resource "azurerm_user_assigned_identity" "app" {
312
+ name = "${names.identity}"
313
+ resource_group_name = azurerm_resource_group.main.name
314
+ location = azurerm_resource_group.main.location
315
+ }
316
+
317
+ resource "azurerm_role_assignment" "acr_pull" {
318
+ scope = azurerm_container_registry.main.id
319
+ role_definition_name = "AcrPull"
320
+ principal_id = azurerm_user_assigned_identity.app.principal_id
321
+ }
322
+
323
+ resource "azurerm_container_app_environment" "main" {
324
+ name = "${names.containerAppEnvironment}"
325
+ resource_group_name = azurerm_resource_group.main.name
326
+ location = azurerm_resource_group.main.location
327
+ }
328
+
329
+ resource "azurerm_container_app" "backend" {
330
+ name = "${names.backendContainerApp}"
331
+ container_app_environment_id = azurerm_container_app_environment.main.id
332
+ resource_group_name = azurerm_resource_group.main.name
333
+ revision_mode = "Single"
334
+
335
+ identity {
336
+ type = "UserAssigned"
337
+ identity_ids = [azurerm_user_assigned_identity.app.id]
338
+ }
339
+
340
+ registry {
341
+ server = azurerm_container_registry.main.login_server
342
+ identity = azurerm_user_assigned_identity.app.id
343
+ }
344
+
345
+ secret {
346
+ name = "database-url"
347
+ value = "postgresql://liftoffadmin:\${urlencode(var.postgres_admin_password)}@\${azurerm_postgresql_flexible_server.main.fqdn}:5432/postgres?sslmode=require"
348
+ }
349
+
350
+ secret {
351
+ name = "redis-url"
352
+ value = "rediss://:\${urlencode(azurerm_redis_cache.main.primary_access_key)}@\${azurerm_redis_cache.main.hostname}:\${azurerm_redis_cache.main.ssl_port}/0"
353
+ }
354
+
355
+ template {
356
+ container {
357
+ name = "backend"
358
+ image = var.backend_image
359
+ cpu = 0.5
360
+ memory = "1Gi"
361
+
362
+ env {
363
+ name = "APP_ENV"
364
+ value = var.environment
365
+ }
366
+
367
+ env {
368
+ name = "APP_NAME"
369
+ value = "${plan.safeProjectName}"
370
+ }
371
+
372
+ env {
373
+ name = "PROJECT_TYPE"
374
+ value = "${plan.projectType.id}"
375
+ }
376
+ ${projectIdentityEnv}
377
+ env {
378
+ name = "CLOUD_PROVIDER"
379
+ value = "azure"
380
+ }
381
+
382
+ env {
383
+ name = "AZURE_REGION"
384
+ value = var.location
385
+ }
386
+ ${frontendCorsEnvironment}
387
+
388
+ env {
389
+ name = "DATABASE_URL"
390
+ secret_name = "database-url"
391
+ }
392
+
393
+ env {
394
+ name = "REDIS_URL"
395
+ secret_name = "redis-url"
396
+ }
397
+
398
+ env {
399
+ name = "MESSAGING_TRANSPORT"
400
+ value = "azure-service-bus"
401
+ }
402
+ ${publisherEnvironment}
403
+ env {
404
+ name = "BLOB_ENDPOINT"
405
+ value = azurerm_storage_account.main.primary_blob_endpoint
406
+ }
407
+ }
408
+ }
409
+
410
+ ingress {
411
+ external_enabled = true
412
+ target_port = var.backend_target_port
413
+ traffic_weight {
414
+ percentage = 100
415
+ latest_revision = true
416
+ }
417
+ }
418
+
419
+ depends_on = [azurerm_role_assignment.acr_pull${ragPublisher ? ', azurerm_role_assignment.backend_servicebus_sender' : ''}]
420
+ }
421
+ ${frontendContainer}
422
+ resource "azurerm_postgresql_flexible_server" "main" {
423
+ name = "${names.postgres}"
424
+ resource_group_name = azurerm_resource_group.main.name
425
+ location = azurerm_resource_group.main.location
426
+ version = "16"
427
+ administrator_login = "liftoffadmin"
428
+ administrator_password = var.postgres_admin_password
429
+ storage_mb = 32768
430
+ sku_name = "B_Standard_B1ms"
431
+ }
432
+
433
+ resource "azurerm_postgresql_flexible_server_firewall_rule" "azure_services" {
434
+ count = var.enable_private_networking ? 0 : 1
435
+ name = "AllowAzureServices"
436
+ server_id = azurerm_postgresql_flexible_server.main.id
437
+ start_ip_address = "0.0.0.0"
438
+ end_ip_address = "0.0.0.0"
439
+ }
440
+
441
+ resource "azurerm_redis_cache" "main" {
442
+ name = "${names.redis}"
443
+ location = azurerm_resource_group.main.location
444
+ resource_group_name = azurerm_resource_group.main.name
445
+ capacity = 0
446
+ family = "C"
447
+ sku_name = "Basic"
448
+ }
449
+
450
+ resource "azurerm_storage_account" "main" {
451
+ name = "${names.storage}"
452
+ resource_group_name = azurerm_resource_group.main.name
453
+ location = azurerm_resource_group.main.location
454
+ account_tier = "Standard"
455
+ account_replication_type = "LRS"
456
+ }
457
+
458
+ resource "azurerm_storage_container" "documents" {
459
+ name = "documents"
460
+ storage_account_id = azurerm_storage_account.main.id
461
+ container_access_type = "private"
462
+ }
463
+
464
+ resource "azurerm_servicebus_namespace" "main" {
465
+ name = "${names.serviceBus}"
466
+ location = azurerm_resource_group.main.location
467
+ resource_group_name = azurerm_resource_group.main.name
468
+ sku = "Standard"
469
+ }
470
+
471
+ resource "azurerm_servicebus_queue" "events" {
472
+ name = ${queueName}
473
+ namespace_id = azurerm_servicebus_namespace.main.id
474
+ }
475
+ ${senderRole}${functionWorker}
476
+
477
+ resource "azurerm_communication_service" "main" {
478
+ name = "${names.communication}"
479
+ resource_group_name = azurerm_resource_group.main.name
480
+ data_location = "United States"
481
+ }
482
+
483
+ resource "azurerm_key_vault" "main" {
484
+ name = "${names.keyVault}"
485
+ location = azurerm_resource_group.main.location
486
+ resource_group_name = azurerm_resource_group.main.name
487
+ tenant_id = data.azurerm_client_config.current.tenant_id
488
+ sku_name = "standard"
489
+ rbac_authorization_enabled = true
490
+ }
491
+
492
+ data "azurerm_client_config" "current" {}
493
+ `;
494
+ }
495
+ export function renderTofuOutputs(plan) {
496
+ const functionOutputs = hasFunctionWorker(plan) ? `
497
+ output "function_app_name" {
498
+ value = azurerm_linux_function_app.worker.name
499
+ }
500
+
501
+ output "function_worker_queue_name" {
502
+ value = azurerm_servicebus_queue.events.name
503
+ }
504
+ ` : '';
505
+ const publisherOutputs = plan.workload === 'genai' && plan.pattern.id === 'rag' ? `
506
+ output "service_bus_fully_qualified_namespace" {
507
+ value = "\${azurerm_servicebus_namespace.main.name}.servicebus.windows.net"
508
+ }
509
+
510
+ output "service_bus_queue_name" {
511
+ value = azurerm_servicebus_queue.events.name
512
+ }
513
+
514
+ output "backend_azure_client_id" {
515
+ value = azurerm_user_assigned_identity.app.client_id
516
+ }
517
+ ` : '';
518
+ return `output "backend_url" {
519
+ value = azurerm_container_app.backend.ingress[0].fqdn
520
+ }
521
+
522
+ ${plan.includeFrontend ? `output "frontend_url" {
523
+ value = azurerm_container_app.frontend.ingress[0].fqdn
524
+ }
525
+ ` : ''}${functionOutputs}output "container_registry" {
526
+ value = azurerm_container_registry.main.login_server
527
+ }
528
+
529
+ output "container_registry_name" {
530
+ value = azurerm_container_registry.main.name
531
+ }
532
+ ${publisherOutputs}
533
+ `;
534
+ }
535
+ export function renderTofuLocalState(environment) {
536
+ return `terraform {
537
+ backend "local" {
538
+ path = "state/${environment}.tfstate"
539
+ }
540
+ }
541
+ `;
542
+ }
543
+ export function renderTofuRemoteStateExample(plan, environment) {
544
+ return `# Replace backend.local.tf with a reviewed backend.tf using this example.
545
+ # Use approved private, encrypted ZRS state storage; blob leases provide locking.
546
+ # State may contain secrets. Do not commit it or place credentials in this file.
547
+ # terraform {
548
+ # backend "azurerm" {
549
+ # resource_group_name = "rg-opentofu-state"
550
+ # storage_account_name = "stliftoffstate"
551
+ # container_name = "tfstate"
552
+ # key = "${plan.safeProjectName}-${projectIdentityDigest(plan)}/${environment}/terraform.tfstate"
553
+ # use_azuread_auth = true
554
+ # }
555
+ # }
556
+ `;
557
+ }
558
+ export function renderTofuReadme(plan) {
559
+ const env = selectedEnvironmentId(plan);
560
+ const governanceGate = plan.governanceProfile.id === 'none' ? '' : `
561
+ ## Governance Gate
562
+
563
+ The commands below are reference material, not authorization to mutate Azure.
564
+ Do not run the plan/apply, ACR build, or image-replacement sequence until the
565
+ separately approved \`application-foundation\` governance phase authorizes the
566
+ exact operation. \`/liftoff-setup\` can evaluate and resume managed phases, but it
567
+ does not imply that every managed phase has an executable production adapter.
568
+ An unavailable production adapter remains a blocker; do not bypass it by running
569
+ these commands directly.
570
+ `;
571
+ const functionSection = plan.workload === 'genai' && hasFunctionWorker(plan) ? `
572
+ ## Azure Functions Worker
573
+
574
+ This project includes an Azure Functions worker under \`functions/${functionWorkerName(plan)}\`. The worker has a separate user-assigned identity with Azure Service Bus Data Receiver on the generated queue only, selected through \`ServiceBusConnection__clientId\` plus \`ServiceBusConnection__fullyQualifiedNamespace\`. \`function_worker_queue_name\` provisions the queue, configures \`SERVICEBUS_QUEUE_NAME\`, and drives the worker queue output. Function host storage uses the complete key-backed \`AzureWebJobsStorage\` connection setting.
575
+ ${plan.workload === 'genai' && plan.pattern.id === 'rag' ? '\nThe RAG backend identity has only Azure Service Bus Data Sender on that queue, not receiver authority. Its namespace, queue, managed-identity authentication mode, and client ID are injected by the application module. The worker trigger is a handoff foundation; retrieval and indexing are not implemented.\n' : ''}
576
+ ` : '';
577
+ return `# Azure OpenTofu
578
+
579
+ Azure is the supported infrastructure starter. Generated files are not production-readiness evidence.
580
+ ${governanceGate}
581
+
582
+ ## Bootstrap Infrastructure
583
+
584
+ The first apply uses a public bootstrap image so Azure Container Apps can start before the new ACR contains application images.
585
+
586
+ \`\`\`bash
587
+ cd infrastructure/opentofu/azure/environments/${env}
588
+ tofu init
589
+ tofu plan -var-file=${env}.tfvars
590
+ tofu apply -var-file=${env}.tfvars
591
+ \`\`\`
592
+
593
+ Build the generated backend in ACR, then replace the bootstrap image:
594
+
595
+ \`\`\`bash
596
+ ACR_NAME="$(tofu output -raw container_registry_name)"
597
+ SOURCE_SHA="$(git rev-parse HEAD)"
598
+ az acr build --registry "$ACR_NAME" --image ${plan.safeProjectName}-backend:"$SOURCE_SHA" ../../../../..
599
+ ${plan.includeFrontend ? `BACKEND_URL="https://$(tofu output -raw backend_url)"
600
+ az acr build --registry "$ACR_NAME" --image ${plan.safeProjectName}-frontend:"$SOURCE_SHA" --build-arg VITE_API_BASE_URL="$BACKEND_URL" ../../../../../frontend
601
+ ` : ''}\`\`\`
602
+
603
+ Persist the deployed images in this root's \`${env}.tfvars\` so future applies do not restore the bootstrap image:
604
+
605
+ \`\`\`hcl
606
+ backend_image = "<login-server>/${plan.safeProjectName}-backend@sha256:<manifest-digest>"
607
+ backend_target_port = 8000
608
+ ${plan.includeFrontend ? `frontend_image = "<login-server>/${plan.safeProjectName}-frontend@sha256:<manifest-digest>"
609
+ ` : ''}\`\`\`
610
+
611
+ \`\`\`bash
612
+ tofu apply -var-file=${env}.tfvars
613
+ \`\`\`
614
+
615
+ Each selected environment (${plan.environments.map(({ id }) => id).join(', ')}) has its own root,
616
+ provider lock, named tfvars, and \`state/<environment>.tfstate\`. Shared resource definitions
617
+ live under \`modules/application\`; do not run plan/apply from that module or the Azure parent directory.
618
+ Switch environment by selecting its root, never by passing another environment's tfvars.
619
+
620
+ Operational \`tofu init\` initializes the root's configured backend. Only local baseline checks
621
+ use \`tofu init -backend=false\` followed by \`tofu validate\` in each selected root.
622
+ For reviewed remote-state adoption, replace \`backend.local.tf\` using that root's
623
+ \`backend.remote.example.tf\`. Each example has a distinct project-and-environment blob key.
624
+ State is secret-sensitive: require private access, encryption, ZRS redundancy, and blob-lease locking;
625
+ do not commit state or credentials. Existing flat-root projects need a separate reviewed migration;
626
+ Liftoff update and force do not move infrastructure or state.
627
+ The default PostgreSQL firewall permits Azure-hosted services. Replace it with private networking before production; set \`enable_private_networking=true\` only when the required VNet, delegated subnet, and private DNS resources are added.
628
+
629
+ ## Azure Name Suffixes
630
+
631
+ Every bounded Azure name includes a stable digest of the full project identity, not only its truncated display prefix.
632
+ Each environment tfvars also supplies a deterministic 12-character \`resource_suffix\` for global names.
633
+ If Azure reports that a name is already taken, replace that environment's suffix with another unique value matching \`^[a-z0-9]{12}$\`; \`tofu validate\` rejects invalid overrides before deployment.
634
+ ${functionSection}
635
+ `;
636
+ }
637
+ export function renderTofuTfvars(plan, environment, context) {
638
+ const values = [
639
+ ['environment', JSON.stringify(environment)],
640
+ ['location', JSON.stringify(plan.region.slug)],
641
+ ['resource_suffix', JSON.stringify(stableResourceSuffix(plan, environment))],
642
+ ['backend_image', JSON.stringify(formatContainerImage(context.stack.containers['container-apps-bootstrap']))],
643
+ ['backend_target_port', '80'],
644
+ ['enable_private_networking', 'false']
645
+ ];
646
+ if (plan.includeFrontend) {
647
+ values.push(['frontend_image', JSON.stringify(formatContainerImage(context.stack.containers['container-apps-bootstrap']))]);
648
+ }
649
+ if (hasFunctionWorker(plan)) {
650
+ values.push(['function_worker_queue_name', JSON.stringify(DEFAULT_FUNCTION_WORKER_QUEUE_NAME)], ['functions_python_version', JSON.stringify(context.stack.runtimes.python.releaseLine)]);
651
+ }
652
+ const width = Math.max(...values.map(([key]) => key.length));
653
+ return values.map(([key, value]) => `${key.padEnd(width)} = ${value}`).join('\n');
654
+ }
655
+ //# sourceMappingURL=azure.js.map