@swovohq/fuel 0.2.2-alpha.9 → 0.2.2-alpha.91

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 (232) hide show
  1. package/README.md +173 -69
  2. package/dist/bin/fuel.js +77 -31
  3. package/dist/bin/fuel.js.map +1 -1
  4. package/dist/cleanup/finalize.d.ts.map +1 -1
  5. package/dist/cleanup/finalize.js +11 -3
  6. package/dist/cleanup/finalize.js.map +1 -1
  7. package/dist/commands/config-verify.d.ts.map +1 -1
  8. package/dist/commands/config-verify.js +14 -6
  9. package/dist/commands/config-verify.js.map +1 -1
  10. package/dist/commands/create-app.d.ts.map +1 -1
  11. package/dist/commands/create-app.js +41 -7
  12. package/dist/commands/create-app.js.map +1 -1
  13. package/dist/commands/infra-deploy.d.ts +15 -1
  14. package/dist/commands/infra-deploy.d.ts.map +1 -1
  15. package/dist/commands/infra-deploy.js +164 -18
  16. package/dist/commands/infra-deploy.js.map +1 -1
  17. package/dist/commands/infra-destroy.d.ts.map +1 -1
  18. package/dist/commands/infra-destroy.js +3 -3
  19. package/dist/commands/infra-destroy.js.map +1 -1
  20. package/dist/commands/infra-init.d.ts +91 -0
  21. package/dist/commands/infra-init.d.ts.map +1 -1
  22. package/dist/commands/infra-init.js +644 -113
  23. package/dist/commands/infra-init.js.map +1 -1
  24. package/dist/commands/infra-pull.d.ts +8 -0
  25. package/dist/commands/infra-pull.d.ts.map +1 -0
  26. package/dist/commands/infra-pull.js +81 -0
  27. package/dist/commands/infra-pull.js.map +1 -0
  28. package/dist/commands/list-modules.d.ts.map +1 -1
  29. package/dist/commands/list-modules.js +10 -3
  30. package/dist/commands/list-modules.js.map +1 -1
  31. package/dist/engines/convention.d.ts +2 -2
  32. package/dist/engines/convention.d.ts.map +1 -1
  33. package/dist/engines/convention.js +8 -6
  34. package/dist/engines/convention.js.map +1 -1
  35. package/dist/engines/dependencies.d.ts +2 -0
  36. package/dist/engines/dependencies.d.ts.map +1 -1
  37. package/dist/engines/dependencies.js.map +1 -1
  38. package/dist/engines/monorepo.d.ts.map +1 -1
  39. package/dist/engines/monorepo.js.map +1 -1
  40. package/dist/engines/template-source.d.ts.map +1 -1
  41. package/dist/engines/template-source.js +3 -1
  42. package/dist/engines/template-source.js.map +1 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js.map +1 -1
  45. package/dist/infra/azure-defaults.d.ts +49 -0
  46. package/dist/infra/azure-defaults.d.ts.map +1 -0
  47. package/dist/infra/azure-defaults.js +52 -0
  48. package/dist/infra/azure-defaults.js.map +1 -0
  49. package/dist/infra/azure-keyvault-client.d.ts +4 -0
  50. package/dist/infra/azure-keyvault-client.d.ts.map +1 -0
  51. package/dist/infra/azure-keyvault-client.js +57 -0
  52. package/dist/infra/azure-keyvault-client.js.map +1 -0
  53. package/dist/infra/azure-rbac.d.ts +11 -0
  54. package/dist/infra/azure-rbac.d.ts.map +1 -0
  55. package/dist/infra/azure-rbac.js +49 -0
  56. package/dist/infra/azure-rbac.js.map +1 -0
  57. package/dist/infra/azure-state-storage.d.ts +20 -0
  58. package/dist/infra/azure-state-storage.d.ts.map +1 -0
  59. package/dist/infra/azure-state-storage.js +229 -0
  60. package/dist/infra/azure-state-storage.js.map +1 -0
  61. package/dist/infra/config-loader.d.ts.map +1 -1
  62. package/dist/infra/config-loader.js.map +1 -1
  63. package/dist/infra/config-writer.js +1 -1
  64. package/dist/infra/credentials.d.ts +2 -2
  65. package/dist/infra/credentials.d.ts.map +1 -1
  66. package/dist/infra/credentials.js +8 -4
  67. package/dist/infra/credentials.js.map +1 -1
  68. package/dist/infra/dependency-checker.d.ts.map +1 -1
  69. package/dist/infra/dependency-checker.js.map +1 -1
  70. package/dist/infra/deployment-detect.d.ts +9 -0
  71. package/dist/infra/deployment-detect.d.ts.map +1 -0
  72. package/dist/infra/deployment-detect.js +53 -0
  73. package/dist/infra/deployment-detect.js.map +1 -0
  74. package/dist/infra/git-client.d.ts.map +1 -1
  75. package/dist/infra/git-client.js +6 -10
  76. package/dist/infra/git-client.js.map +1 -1
  77. package/dist/infra/github-client.d.ts +7 -0
  78. package/dist/infra/github-client.d.ts.map +1 -1
  79. package/dist/infra/github-client.js +47 -7
  80. package/dist/infra/github-client.js.map +1 -1
  81. package/dist/infra/github-secrets-client.d.ts.map +1 -1
  82. package/dist/infra/github-secrets-client.js +2 -2
  83. package/dist/infra/github-secrets-client.js.map +1 -1
  84. package/dist/infra/github-token-link.d.ts +4 -0
  85. package/dist/infra/github-token-link.d.ts.map +1 -0
  86. package/dist/infra/github-token-link.js +32 -0
  87. package/dist/infra/github-token-link.js.map +1 -0
  88. package/dist/infra/orchestrator.d.ts +4 -1
  89. package/dist/infra/orchestrator.d.ts.map +1 -1
  90. package/dist/infra/orchestrator.js +218 -63
  91. package/dist/infra/orchestrator.js.map +1 -1
  92. package/dist/infra/port-utils.d.ts.map +1 -1
  93. package/dist/infra/port-utils.js.map +1 -1
  94. package/dist/infra/preflight.d.ts.map +1 -1
  95. package/dist/infra/preflight.js +25 -11
  96. package/dist/infra/preflight.js.map +1 -1
  97. package/dist/infra/remote-secret.d.ts +14 -0
  98. package/dist/infra/remote-secret.d.ts.map +1 -0
  99. package/dist/infra/remote-secret.js +42 -0
  100. package/dist/infra/remote-secret.js.map +1 -0
  101. package/dist/infra/s3-state-bucket.d.ts.map +1 -1
  102. package/dist/infra/s3-state-bucket.js +8 -4
  103. package/dist/infra/s3-state-bucket.js.map +1 -1
  104. package/dist/infra/secrets-manager-client.d.ts.map +1 -1
  105. package/dist/infra/secrets-manager-client.js +8 -5
  106. package/dist/infra/secrets-manager-client.js.map +1 -1
  107. package/dist/infra/subprocess.js +1 -1
  108. package/dist/infra/template-engine.d.ts +14 -5
  109. package/dist/infra/template-engine.d.ts.map +1 -1
  110. package/dist/infra/template-engine.js +157 -39
  111. package/dist/infra/template-engine.js.map +1 -1
  112. package/dist/infra/tofu-runner.d.ts +4 -3
  113. package/dist/infra/tofu-runner.d.ts.map +1 -1
  114. package/dist/infra/tofu-runner.js +40 -34
  115. package/dist/infra/tofu-runner.js.map +1 -1
  116. package/dist/infra/types.d.ts +241 -17
  117. package/dist/infra/types.d.ts.map +1 -1
  118. package/dist/infra/types.js +419 -22
  119. package/dist/infra/types.js.map +1 -1
  120. package/dist/infra-templates/TODO-azure-prod.md +127 -0
  121. package/dist/infra-templates/modules/azure-container-app/main.tf +124 -0
  122. package/dist/infra-templates/modules/azure-container-app/outputs.tf +24 -0
  123. package/dist/infra-templates/modules/azure-container-app/variables.tf +80 -0
  124. package/dist/infra-templates/modules/azure-container-apps-environment/main.tf +18 -0
  125. package/dist/infra-templates/modules/azure-container-apps-environment/outputs.tf +14 -0
  126. package/dist/infra-templates/modules/azure-container-apps-environment/variables.tf +24 -0
  127. package/dist/infra-templates/modules/azure-container-registry/main.tf +10 -0
  128. package/dist/infra-templates/modules/azure-container-registry/outputs.tf +14 -0
  129. package/dist/infra-templates/modules/azure-container-registry/variables.tf +20 -0
  130. package/dist/infra-templates/modules/azure-front-door/main.tf +80 -0
  131. package/dist/infra-templates/modules/azure-front-door/outputs.tf +20 -0
  132. package/dist/infra-templates/modules/azure-front-door/variables.tf +26 -0
  133. package/dist/infra-templates/modules/azure-github-oidc/main.tf +48 -0
  134. package/dist/infra-templates/modules/azure-github-oidc/outputs.tf +9 -0
  135. package/dist/infra-templates/modules/azure-github-oidc/variables.tf +69 -0
  136. package/dist/infra-templates/modules/azure-key-vault/main.tf +21 -0
  137. package/dist/infra-templates/modules/azure-key-vault/outputs.tf +11 -0
  138. package/dist/infra-templates/modules/azure-key-vault/variables.tf +43 -0
  139. package/dist/infra-templates/modules/azure-monitor/main.tf +29 -0
  140. package/dist/infra-templates/modules/azure-monitor/outputs.tf +17 -0
  141. package/dist/infra-templates/modules/azure-monitor/variables.tf +32 -0
  142. package/dist/infra-templates/modules/azure-network/main.tf +134 -0
  143. package/dist/infra-templates/modules/azure-network/outputs.tf +44 -0
  144. package/dist/infra-templates/modules/azure-network/variables.tf +56 -0
  145. package/dist/infra-templates/modules/azure-postgresql-flexible/main.tf +34 -0
  146. package/dist/infra-templates/modules/azure-postgresql-flexible/outputs.tf +20 -0
  147. package/dist/infra-templates/modules/azure-postgresql-flexible/variables.tf +54 -0
  148. package/dist/infra-templates/modules/azure-redis-cache/main.tf +32 -0
  149. package/dist/infra-templates/modules/azure-redis-cache/outputs.tf +15 -0
  150. package/dist/infra-templates/modules/azure-redis-cache/variables.tf +30 -0
  151. package/dist/infra-templates/modules/azure-resource-group/main.tf +5 -0
  152. package/dist/infra-templates/modules/azure-resource-group/outputs.tf +11 -0
  153. package/dist/infra-templates/modules/azure-resource-group/variables.tf +16 -0
  154. package/dist/infra-templates/modules/azure-sql-database/main.tf +63 -0
  155. package/dist/infra-templates/modules/azure-sql-database/outputs.tf +20 -0
  156. package/dist/infra-templates/modules/azure-sql-database/variables.tf +78 -0
  157. package/dist/infra-templates/modules/azure-storage-account/main.tf +13 -0
  158. package/dist/infra-templates/modules/azure-storage-account/outputs.tf +16 -0
  159. package/dist/infra-templates/modules/azure-storage-account/variables.tf +38 -0
  160. package/dist/infra-templates/modules/cloud-watch/event-bridge.tf +15 -0
  161. package/dist/infra-templates/modules/cloud-watch/lambda.tf +84 -0
  162. package/dist/infra-templates/modules/cloud-watch/lambda_function.zip +0 -0
  163. package/dist/infra-templates/modules/cloud-watch/lambda_function_deploy.zip +0 -0
  164. package/dist/infra-templates/modules/cloud-watch/main.tf +156 -0
  165. package/dist/infra-templates/modules/cloud-watch/sns.tf +3 -0
  166. package/dist/infra-templates/modules/cloud-watch/variables.tf +38 -0
  167. package/dist/infra-templates/modules/ecs-core/alb.tf +126 -0
  168. package/dist/infra-templates/modules/ecs-core/cloudwatch.tf +48 -0
  169. package/dist/infra-templates/modules/ecs-core/iam.tf +95 -0
  170. package/dist/infra-templates/modules/ecs-core/main.tf +12 -0
  171. package/dist/infra-templates/modules/ecs-core/outputs.tf +44 -0
  172. package/dist/infra-templates/modules/ecs-core/secrets.tf +9 -0
  173. package/dist/infra-templates/modules/ecs-core/security_groups.tf +73 -0
  174. package/dist/infra-templates/modules/ecs-core/variables.tf +96 -0
  175. package/dist/infra-templates/modules/ecs-service/ecs_autoscaling.tf +51 -0
  176. package/dist/infra-templates/modules/ecs-service/ecs_service.tf +39 -0
  177. package/dist/infra-templates/modules/ecs-service/ecs_task_definition.tf +56 -0
  178. package/dist/infra-templates/modules/ecs-service/variables.tf +170 -0
  179. package/dist/infra-templates/modules/elastic-container-registry/main.tf +32 -0
  180. package/dist/infra-templates/modules/elastic-container-registry/outputs.tf +9 -0
  181. package/dist/infra-templates/modules/elastic-container-registry/variables.tf +25 -0
  182. package/dist/infra-templates/modules/github-oidc-role/main.tf +46 -0
  183. package/dist/infra-templates/modules/github-oidc-role/outputs.tf +4 -0
  184. package/dist/infra-templates/modules/github-oidc-role/variables.tf +11 -0
  185. package/dist/infra-templates/modules/guardduty/main.tf +8 -0
  186. package/dist/infra-templates/modules/iam/main.tf +205 -0
  187. package/dist/infra-templates/modules/iam/outputs.tf +3 -0
  188. package/dist/infra-templates/modules/iam/variables.tf +4 -0
  189. package/dist/infra-templates/modules/random-key/main.tf +11 -0
  190. package/dist/infra-templates/modules/random-key/outputs.tf +4 -0
  191. package/dist/infra-templates/modules/random-key/variables.tf +10 -0
  192. package/dist/infra-templates/modules/redis/main.tf +47 -0
  193. package/dist/infra-templates/modules/redis/outputs.tf +8 -0
  194. package/dist/infra-templates/modules/redis/variables.tf +20 -0
  195. package/dist/infra-templates/modules/relational-database-service/main.tf +44 -0
  196. package/dist/infra-templates/modules/relational-database-service/outputs.tf +13 -0
  197. package/dist/infra-templates/modules/relational-database-service/security-group.tf +15 -0
  198. package/dist/infra-templates/modules/relational-database-service/variables.tf +50 -0
  199. package/dist/infra-templates/modules/secret/main.tf +14 -0
  200. package/dist/infra-templates/modules/secret/outputs.tf +3 -0
  201. package/dist/infra-templates/modules/secret/variables.tf +8 -0
  202. package/dist/infra-templates/modules/simple-storage-service/main.tf +28 -0
  203. package/dist/infra-templates/modules/simple-storage-service/variables.tf +4 -0
  204. package/dist/infra-templates/modules/vpc/data.tf +2 -0
  205. package/dist/infra-templates/modules/vpc/main.tf +76 -0
  206. package/dist/infra-templates/modules/vpc/outputs.tf +23 -0
  207. package/dist/infra-templates/modules/vpc/variables.tf +5 -0
  208. package/dist/infra-templates/package.json +6 -0
  209. package/dist/infra-templates/templates/azure/MANUAL_DEPLOY.md +168 -0
  210. package/dist/infra-templates/templates/azure/backend.tf +8 -0
  211. package/dist/infra-templates/templates/azure/data.tf +21 -0
  212. package/dist/infra-templates/templates/azure/default.tfvars +0 -0
  213. package/dist/infra-templates/templates/azure/locals.tf +116 -0
  214. package/dist/infra-templates/templates/azure/main.tf +421 -0
  215. package/dist/infra-templates/templates/azure/outputs.tf +40 -0
  216. package/dist/infra-templates/templates/azure/providers.tf +65 -0
  217. package/dist/infra-templates/templates/azure/variables.tf +69 -0
  218. package/dist/infra-templates/templates/azure/workflows/build_and_deploy.yml +155 -0
  219. package/dist/infra-templates/templates/azure/workflows/tests.yml +63 -0
  220. package/dist/infra-templates/templates/ecs/README.md +235 -0
  221. package/dist/infra-templates/templates/ecs/backend.tf +7 -0
  222. package/dist/infra-templates/templates/ecs/data.tf +6 -0
  223. package/dist/infra-templates/templates/ecs/default.tfvars +1 -0
  224. package/dist/infra-templates/templates/ecs/locals.tf +97 -0
  225. package/dist/infra-templates/templates/ecs/main.tf +185 -0
  226. package/dist/infra-templates/templates/ecs/outputs.tf +42 -0
  227. package/dist/infra-templates/templates/ecs/providers.tf +21 -0
  228. package/dist/infra-templates/templates/ecs/variables.tf +105 -0
  229. package/dist/infra-templates/templates/ecs/workflows/build_and_deploy.yml +188 -0
  230. package/dist/infra-templates/templates/ecs/workflows/tests.yml +65 -0
  231. package/package.json +10 -2
  232. package/schema/fuel.schema.json +570 -91
@@ -1,44 +1,441 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REQUIRED_CREDENTIAL_KEYS = exports.WorkerSchema = exports.InfraConfigSchema = exports.AppSchema = void 0;
3
+ exports.REQUIRED_CREDENTIAL_KEYS = exports.AZURE_REQUIRED_CREDENTIAL_KEYS = exports.AWS_REQUIRED_CREDENTIAL_KEYS = exports.WorkerSchema = exports.InfraConfigSchema = exports.AzureInfraConfigSchema = exports.AzureAppSchema = exports.EcsInfraConfigSchema = exports.AppSchema = void 0;
4
+ exports.requiredCredentialKeysFor = requiredCredentialKeysFor;
4
5
  const zod_1 = require("zod");
5
- const WorkerSchema = zod_1.z.object({
6
- name: zod_1.z.string().min(1),
7
- dockerfile: zod_1.z.string().min(1),
8
- });
6
+ const azure_defaults_1 = require("./azure-defaults");
7
+ // AWS resource naming: lowercase letters, numbers, and hyphens only; must start and
8
+ // end with an alphanumeric character. This is the strictest common denominator among
9
+ // the AWS resources these names flow into (S3 bucket names, ALB/target group names).
10
+ const AWS_NAME_PATTERN = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
11
+ const AWS_NAME_MESSAGE = 'must contain only lowercase letters, numbers, and hyphens, and cannot start or end with a hyphen';
12
+ // "<name>-TargetGroup" must fit AWS's 32-character ALB target group name limit.
13
+ const PROJECT_NAME_MAX_LENGTH = 20;
14
+ // Per-app ALB target group names use the app name literally, with no suffix — also capped at 32 by AWS.
15
+ const APP_NAME_MAX_LENGTH = 32;
16
+ // Azure Container App naming: 2-32 characters, must start with a letter, contain only
17
+ // lowercase letters, numbers, and hyphens, end with an alphanumeric character, and never
18
+ // contain consecutive hyphens.
19
+ const AZURE_APP_NAME_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
20
+ const AZURE_APP_NAME_MESSAGE = 'must start with a letter, contain only lowercase letters, numbers, and hyphens, end with an alphanumeric character, and not contain consecutive hyphens';
21
+ const AZURE_APP_NAME_MIN_LENGTH = 2;
22
+ const AZURE_APP_NAME_MAX_LENGTH = 32;
23
+ const WorkerSchema = zod_1.z
24
+ .object({
25
+ name: zod_1.z
26
+ .string()
27
+ .min(1)
28
+ .max(APP_NAME_MAX_LENGTH, `worker name must be ${APP_NAME_MAX_LENGTH} characters or fewer (AWS resource naming limit)`)
29
+ .regex(AWS_NAME_PATTERN, `worker name ${AWS_NAME_MESSAGE}`)
30
+ .describe('Worker name. Used as the ECS service name.'),
31
+ dockerfile: zod_1.z
32
+ .string()
33
+ .min(1)
34
+ .describe("Path to the worker's Dockerfile relative to the project root.")
35
+ })
36
+ .passthrough()
37
+ .meta({ id: 'worker' });
9
38
  exports.WorkerSchema = WorkerSchema;
10
- exports.AppSchema = zod_1.z.object({
11
- name: zod_1.z.string().min(1),
12
- technology: zod_1.z.enum(['nest', 'react']),
39
+ exports.AppSchema = zod_1.z
40
+ .object({
41
+ name: zod_1.z
42
+ .string()
43
+ .min(1)
44
+ .max(APP_NAME_MAX_LENGTH, `app name must be ${APP_NAME_MAX_LENGTH} characters or fewer (AWS ALB target group name limit)`)
45
+ .regex(AWS_NAME_PATTERN, `app name ${AWS_NAME_MESSAGE}`),
46
+ technology: zod_1.z
47
+ .string()
48
+ .min(1)
49
+ .describe("Application role/framework. 'nest' and 'react' get framework-specific env var injection (see docs); any other value deploys as a plain container with no extra env vars — pass everything explicitly via variables/build_env."),
13
50
  dockerfile: zod_1.z.string().min(1),
14
51
  health_check_path: zod_1.z.string().min(1),
15
52
  domain: zod_1.z.string().min(1),
16
53
  port: zod_1.z.number().int().positive(),
17
54
  branch: zod_1.z.string().default('main'),
18
55
  template_repo_branch: zod_1.z.string().default('main'),
19
- postgres: zod_1.z.boolean().optional().default(false),
20
- redis: zod_1.z.boolean().optional().default(false),
56
+ postgres: zod_1.z
57
+ .boolean()
58
+ .optional()
59
+ .default(false)
60
+ .describe('Provision an RDS PostgreSQL instance for this app.'),
61
+ redis: zod_1.z
62
+ .boolean()
63
+ .optional()
64
+ .default(false)
65
+ .describe('Provision an ElastiCache Redis instance for this app.'),
21
66
  variables: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional().default({}),
22
67
  build_env: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional().default({}),
23
68
  workers: zod_1.z.array(WorkerSchema).optional().default([]),
24
- cpu_units: zod_1.z.number().int().positive().optional().default(1024),
25
- memory_units: zod_1.z.number().int().positive().optional().default(2048),
26
- db_instance_type: zod_1.z.string().optional(),
27
- db_allocated_storage: zod_1.z.number().int().positive().optional(),
28
- redis_instance_type: zod_1.z.string().optional(),
29
- });
30
- exports.InfraConfigSchema = zod_1.z.object({
31
- name: zod_1.z.string().min(1),
69
+ cpu_units: zod_1.z
70
+ .number()
71
+ .int()
72
+ .positive()
73
+ .optional()
74
+ .default(1024)
75
+ .describe('ECS task CPU units (1024 = 1 vCPU).'),
76
+ memory_units: zod_1.z
77
+ .number()
78
+ .int()
79
+ .positive()
80
+ .optional()
81
+ .default(2048)
82
+ .describe('ECS task memory in MB.'),
83
+ db_instance_type: zod_1.z
84
+ .string()
85
+ .optional()
86
+ .describe('RDS instance type, e.g. db.t3.small. Only used when postgres is true.'),
87
+ db_allocated_storage: zod_1.z
88
+ .number()
89
+ .int()
90
+ .positive()
91
+ .optional()
92
+ .describe('RDS allocated storage in GB. Only used when postgres is true.'),
93
+ redis_instance_type: zod_1.z
94
+ .string()
95
+ .optional()
96
+ .describe('ElastiCache node type, e.g. cache.t3.small. Only used when redis is true.')
97
+ })
98
+ .passthrough()
99
+ .meta({ id: 'ecsApp' });
100
+ exports.EcsInfraConfigSchema = zod_1.z
101
+ .object({
102
+ name: zod_1.z
103
+ .string()
104
+ .min(1)
105
+ .max(PROJECT_NAME_MAX_LENGTH, `name must be ${PROJECT_NAME_MAX_LENGTH} characters or fewer — AWS caps the "<name>-TargetGroup" load balancer resource name at 32 characters`)
106
+ .regex(AWS_NAME_PATTERN, `name ${AWS_NAME_MESSAGE}`),
107
+ slack_webhook_url: zod_1.z.string().optional(),
108
+ github_repo_name: zod_1.z
109
+ .string()
110
+ .optional()
111
+ .describe('Name of the GitHub repository to create/use. Defaults to "${name}-monorepo". Set this ' +
112
+ 'explicitly when this fuel.yml should target a repo already used by another environment ' +
113
+ '(e.g. a separate prod fuel.yml with its own `name` pointing at the same repo as dev).'),
32
114
  deployment: zod_1.z.literal('ecs'),
33
- ssl: zod_1.z.string().min(1),
34
- apps: zod_1.z.array(exports.AppSchema).min(1),
115
+ ssl: zod_1.z
116
+ .string()
117
+ .min(1)
118
+ .describe('ACM certificate ARN attached to the ALB HTTPS listener, e.g. arn:aws:acm:us-east-1:ACCOUNT_ID:certificate/CERTIFICATE_ID.'),
119
+ apps: zod_1.z.array(exports.AppSchema).min(1)
120
+ })
121
+ .passthrough()
122
+ .meta({ id: 'ecsConfig' })
123
+ .superRefine((config, ctx) => {
124
+ const names = config.apps.map((app) => app.name);
125
+ const duplicates = [
126
+ ...new Set(names.filter((name, i) => names.indexOf(name) !== i))
127
+ ];
128
+ if (duplicates.length > 0) {
129
+ ctx.addIssue({
130
+ code: 'custom',
131
+ message: `app.name must be unique — duplicate: ${duplicates.join(', ')}`,
132
+ path: ['apps']
133
+ });
134
+ }
35
135
  });
36
- exports.REQUIRED_CREDENTIAL_KEYS = [
136
+ // --- Azure ---
137
+ const AzureDatabaseSchema = zod_1.z
138
+ .object({
139
+ enabled: zod_1.z.boolean().optional().default(false),
140
+ engine: zod_1.z
141
+ .enum(['mssql', 'postgres'])
142
+ .optional()
143
+ .default(azure_defaults_1.AZURE_DEFAULTS.database.engine)
144
+ .describe("Database engine: 'mssql' provisions Azure SQL Database, 'postgres' provisions Azure Database for PostgreSQL Flexible Server."),
145
+ sku_name: zod_1.z
146
+ .string()
147
+ .optional()
148
+ .describe('SKU name — e.g. GP_S_Gen5_4 for mssql, GP_Standard_D4s_v3 for postgres.'),
149
+ storage_account_type: zod_1.z
150
+ .enum(['Local', 'Zone', 'Geo', 'GeoZone'])
151
+ .optional()
152
+ .default(azure_defaults_1.AZURE_DEFAULTS.database.storageAccountType)
153
+ .describe('Backup storage redundancy (mssql only).'),
154
+ pitr_retention_days: zod_1.z
155
+ .number()
156
+ .int()
157
+ .min(1)
158
+ .max(35)
159
+ .optional()
160
+ .default(azure_defaults_1.AZURE_DEFAULTS.database.pitrRetentionDays)
161
+ .describe('Point-in-time restore retention in days (mssql only).'),
162
+ ltr_weekly_retention: zod_1.z
163
+ .string()
164
+ .optional()
165
+ .default(azure_defaults_1.AZURE_DEFAULTS.database.ltrWeeklyRetention)
166
+ .describe('Long-term retention ISO 8601 duration, e.g. P21W (mssql only).'),
167
+ allocated_storage_mb: zod_1.z
168
+ .number()
169
+ .int()
170
+ .positive()
171
+ .optional()
172
+ .describe('Allocated storage in MB (postgres only).')
173
+ })
174
+ .passthrough();
175
+ const AzureRedisSchema = zod_1.z
176
+ .object({
177
+ enabled: zod_1.z.boolean().optional().default(false),
178
+ sku_name: zod_1.z
179
+ .string()
180
+ .optional()
181
+ .default(azure_defaults_1.AZURE_DEFAULTS.redis.skuName)
182
+ .describe("Azure Managed Redis 'Balanced' tier SKU, e.g. Balanced_B0, Balanced_B1, Balanced_B5.")
183
+ })
184
+ .passthrough();
185
+ const AzureContainerAppSchema = zod_1.z
186
+ .object({
187
+ cpu: zod_1.z
188
+ .number()
189
+ .positive()
190
+ .optional()
191
+ .default(azure_defaults_1.AZURE_DEFAULTS.containerApp.cpu),
192
+ memory: zod_1.z
193
+ .string()
194
+ .optional()
195
+ .default(azure_defaults_1.AZURE_DEFAULTS.containerApp.memory)
196
+ .describe('CPU:memory ratio is fixed at 1:2 by the platform.'),
197
+ concurrent_requests: zod_1.z
198
+ .number()
199
+ .int()
200
+ .positive()
201
+ .optional()
202
+ .default(azure_defaults_1.AZURE_DEFAULTS.containerApp.concurrentRequests)
203
+ .describe('HTTP concurrency threshold that triggers scale-out.'),
204
+ min_replicas: zod_1.z
205
+ .number()
206
+ .int()
207
+ .nonnegative()
208
+ .optional()
209
+ .default(azure_defaults_1.AZURE_DEFAULTS.containerApp.minReplicas),
210
+ max_replicas: zod_1.z
211
+ .number()
212
+ .int()
213
+ .positive()
214
+ .optional()
215
+ .default(azure_defaults_1.AZURE_DEFAULTS.containerApp.maxReplicas)
216
+ })
217
+ .passthrough();
218
+ const AzureWorkerSchema = zod_1.z
219
+ .object({
220
+ name: zod_1.z
221
+ .string()
222
+ .min(AZURE_APP_NAME_MIN_LENGTH, `worker name must be at least ${AZURE_APP_NAME_MIN_LENGTH} characters (Azure Container App naming requirement)`)
223
+ .max(AZURE_APP_NAME_MAX_LENGTH, `worker name must be ${AZURE_APP_NAME_MAX_LENGTH} characters or fewer (Azure Container App naming limit)`)
224
+ .regex(AZURE_APP_NAME_PATTERN, `worker name ${AZURE_APP_NAME_MESSAGE}`)
225
+ .describe('Worker name. Used as the Container App name.'),
226
+ dockerfile: zod_1.z
227
+ .string()
228
+ .min(1)
229
+ .describe("Path to the worker's Dockerfile relative to the project root.")
230
+ })
231
+ .passthrough()
232
+ .meta({ id: 'azureWorker' });
233
+ exports.AzureAppSchema = zod_1.z
234
+ .object({
235
+ name: zod_1.z
236
+ .string()
237
+ .min(AZURE_APP_NAME_MIN_LENGTH, `app name must be at least ${AZURE_APP_NAME_MIN_LENGTH} characters (Azure Container App naming requirement)`)
238
+ .max(AZURE_APP_NAME_MAX_LENGTH, `app name must be ${AZURE_APP_NAME_MAX_LENGTH} characters or fewer (Azure Container App naming limit)`)
239
+ .regex(AZURE_APP_NAME_PATTERN, `app name ${AZURE_APP_NAME_MESSAGE}`),
240
+ technology: zod_1.z
241
+ .string()
242
+ .min(1)
243
+ .describe("Application role/framework. 'nest' and 'react' get framework-specific env var injection (see docs); any other value deploys as a plain Container App with no extra env vars — pass everything explicitly via variables/build_env."),
244
+ dockerfile: zod_1.z.string().min(1),
245
+ health_check_path: zod_1.z.string().min(1),
246
+ domain: zod_1.z
247
+ .string()
248
+ .min(1)
249
+ .describe('Custom domain for this app. A managed TLS certificate is issued automatically via Front Door once DNS validation completes (see the custom_domain_validation deploy output).'),
250
+ port: zod_1.z.number().int().positive(),
251
+ branch: zod_1.z.string().default('main'),
252
+ template_repo_branch: zod_1.z.string().default('main'),
253
+ variables: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional().default({}),
254
+ build_env: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional().default({}),
255
+ workers: zod_1.z.array(AzureWorkerSchema).optional().default([]),
256
+ database: AzureDatabaseSchema.default({
257
+ enabled: false,
258
+ engine: azure_defaults_1.AZURE_DEFAULTS.database.engine,
259
+ storage_account_type: azure_defaults_1.AZURE_DEFAULTS.database.storageAccountType,
260
+ pitr_retention_days: azure_defaults_1.AZURE_DEFAULTS.database.pitrRetentionDays,
261
+ ltr_weekly_retention: azure_defaults_1.AZURE_DEFAULTS.database.ltrWeeklyRetention
262
+ }).describe('Azure SQL Database or PostgreSQL Flexible Server for this app.'),
263
+ redis: AzureRedisSchema.default({
264
+ enabled: false,
265
+ sku_name: azure_defaults_1.AZURE_DEFAULTS.redis.skuName
266
+ }).describe('Azure Managed Redis for this app.'),
267
+ container_app: AzureContainerAppSchema.default({
268
+ cpu: azure_defaults_1.AZURE_DEFAULTS.containerApp.cpu,
269
+ memory: azure_defaults_1.AZURE_DEFAULTS.containerApp.memory,
270
+ concurrent_requests: azure_defaults_1.AZURE_DEFAULTS.containerApp.concurrentRequests,
271
+ min_replicas: azure_defaults_1.AZURE_DEFAULTS.containerApp.minReplicas,
272
+ max_replicas: azure_defaults_1.AZURE_DEFAULTS.containerApp.maxReplicas
273
+ }).describe('Azure Container Apps (Consumption plan) sizing. Every app runs as a Container App.')
274
+ })
275
+ .passthrough()
276
+ .meta({ id: 'azureApp' });
277
+ exports.AzureInfraConfigSchema = zod_1.z
278
+ .object({
279
+ name: zod_1.z.string().min(1),
280
+ slack_webhook_url: zod_1.z.string().optional(),
281
+ github_repo_name: zod_1.z
282
+ .string()
283
+ .optional()
284
+ .describe('Name of the GitHub repository to create/use. Defaults to "${name}-monorepo". Set this ' +
285
+ 'explicitly when this fuel.yml should target a repo already used by another environment ' +
286
+ '(e.g. a separate prod fuel.yml with its own `name` pointing at the same repo as dev).'),
287
+ deployment: zod_1.z.literal('azure'),
288
+ location: zod_1.z
289
+ .string()
290
+ .optional()
291
+ .default(azure_defaults_1.AZURE_DEFAULTS.location)
292
+ .describe('Azure region for all resources.'),
293
+ monitor: zod_1.z
294
+ .object({
295
+ daily_data_cap_gb: zod_1.z
296
+ .number()
297
+ .positive()
298
+ .optional()
299
+ .default(azure_defaults_1.AZURE_DEFAULTS.monitor.dailyDataCapGb),
300
+ retention_days: zod_1.z
301
+ .number()
302
+ .int()
303
+ .positive()
304
+ .optional()
305
+ .default(azure_defaults_1.AZURE_DEFAULTS.monitor.retentionDays),
306
+ dashboard_count: zod_1.z
307
+ .number()
308
+ .int()
309
+ .nonnegative()
310
+ .optional()
311
+ .default(azure_defaults_1.AZURE_DEFAULTS.monitor.dashboardCount)
312
+ })
313
+ .passthrough()
314
+ .default({
315
+ daily_data_cap_gb: azure_defaults_1.AZURE_DEFAULTS.monitor.dailyDataCapGb,
316
+ retention_days: azure_defaults_1.AZURE_DEFAULTS.monitor.retentionDays,
317
+ dashboard_count: azure_defaults_1.AZURE_DEFAULTS.monitor.dashboardCount
318
+ })
319
+ .describe('Application Insights / Log Analytics settings shared across all apps.'),
320
+ front_door: zod_1.z
321
+ .object({
322
+ sku_name: zod_1.z
323
+ .literal('Standard_AzureFrontDoor')
324
+ .optional()
325
+ .default(azure_defaults_1.AZURE_DEFAULTS.frontDoor.skuName)
326
+ })
327
+ .passthrough()
328
+ .default({ sku_name: azure_defaults_1.AZURE_DEFAULTS.frontDoor.skuName }),
329
+ storage_account: zod_1.z
330
+ .object({
331
+ account_kind: zod_1.z
332
+ .literal('BlockBlobStorage')
333
+ .optional()
334
+ .default(azure_defaults_1.AZURE_DEFAULTS.storageAccount.accountKind),
335
+ account_tier: zod_1.z
336
+ .literal('Premium')
337
+ .optional()
338
+ .default(azure_defaults_1.AZURE_DEFAULTS.storageAccount.accountTier),
339
+ account_replication_type: zod_1.z
340
+ .literal('LRS')
341
+ .optional()
342
+ .default(azure_defaults_1.AZURE_DEFAULTS.storageAccount.accountReplicationType),
343
+ access_tier: zod_1.z
344
+ .literal('Hot')
345
+ .optional()
346
+ .default(azure_defaults_1.AZURE_DEFAULTS.storageAccount.accessTier)
347
+ })
348
+ .passthrough()
349
+ .default({
350
+ account_kind: azure_defaults_1.AZURE_DEFAULTS.storageAccount.accountKind,
351
+ account_tier: azure_defaults_1.AZURE_DEFAULTS.storageAccount.accountTier,
352
+ account_replication_type: azure_defaults_1.AZURE_DEFAULTS.storageAccount.accountReplicationType,
353
+ access_tier: azure_defaults_1.AZURE_DEFAULTS.storageAccount.accessTier
354
+ })
355
+ .describe('Shared app storage account, used for app file uploads (not the Terraform state storage account).'),
356
+ key_vault: zod_1.z
357
+ .object({
358
+ sku_name: zod_1.z
359
+ .literal('standard')
360
+ .optional()
361
+ .default(azure_defaults_1.AZURE_DEFAULTS.keyVault.skuName)
362
+ })
363
+ .passthrough()
364
+ .default({ sku_name: azure_defaults_1.AZURE_DEFAULTS.keyVault.skuName }),
365
+ github_oidc: zod_1.z
366
+ .object({
367
+ enabled: zod_1.z
368
+ .boolean()
369
+ .optional()
370
+ .default(true)
371
+ .describe('Set to false to skip GitHub Actions OIDC entirely — no app registration, no role assignment ' +
372
+ 'for CI. Use this to unblock testing the rest of the stack while waiting on a tenant admin.'),
373
+ existing_client_id: zod_1.z
374
+ .string()
375
+ .optional()
376
+ .describe('Client ID of an app registration + service principal + federated identity credential(s) already ' +
377
+ 'created out-of-band by a tenant admin. Set this when the deploying SP lacks the Entra ID ' +
378
+ '"Application Administrator" role (creating an app registration requires it, regardless of ' +
379
+ 'subscription-level RBAC) — the module then reuses that identity instead of creating a new one. ' +
380
+ 'The Contributor role assignment is still managed by Terraform either way, since that only needs ' +
381
+ '"User Access Administrator" on the subscription.'),
382
+ existing_principal_id: zod_1.z
383
+ .string()
384
+ .optional()
385
+ .describe('Object ID (principal ID) of the service principal identified by existing_client_id, when ' +
386
+ 'already known. Strongly recommended whenever existing_client_id is set: without it, ' +
387
+ 'Terraform looks the object ID up via Microsoft Graph, which needs Directory.Read.All or ' +
388
+ "Application.Read.All on the deploying SP — permissions many tenant admins won't grant just " +
389
+ 'to resolve one known object. Whoever created the app out-of-band can get this by running ' +
390
+ '`az ad sp show --id <existing_client_id> --query id -o tsv`.'),
391
+ manage_role_assignment: zod_1.z
392
+ .boolean()
393
+ .optional()
394
+ .default(true)
395
+ .describe('Whether Terraform should create/manage the Contributor role assignment for this identity. ' +
396
+ 'Set to false when it was already granted out-of-band alongside existing_client_id (e.g. a ' +
397
+ "tenant admin's onboarding runbook already ran the role assignment) — otherwise Terraform " +
398
+ 'tries to create it again on every apply and fails with RoleAssignmentExists.')
399
+ })
400
+ .passthrough()
401
+ .optional()
402
+ .default({ enabled: true, manage_role_assignment: true })
403
+ .describe('GitHub Actions OIDC identity used to push images and redeploy Container Apps.'),
404
+ apps: zod_1.z.array(exports.AzureAppSchema).min(1)
405
+ })
406
+ .passthrough()
407
+ .meta({ id: 'azureConfig' });
408
+ exports.InfraConfigSchema = zod_1.z.discriminatedUnion('deployment', [
409
+ exports.EcsInfraConfigSchema,
410
+ exports.AzureInfraConfigSchema
411
+ ]);
412
+ exports.AWS_REQUIRED_CREDENTIAL_KEYS = [
37
413
  'AWS_ACCESS_KEY_ID',
38
414
  'AWS_SECRET_ACCESS_KEY',
39
415
  'AWS_REGION',
40
416
  'GITHUB_TOKEN',
41
417
  'GITHUB_USERNAME',
42
- 'GITHUB_ORGANIZATION',
418
+ 'GITHUB_ORGANIZATION'
419
+ ];
420
+ exports.AZURE_REQUIRED_CREDENTIAL_KEYS = [
421
+ 'AZURE_SUBSCRIPTION_ID',
422
+ 'AZURE_TENANT_ID',
423
+ 'AZURE_CLIENT_ID',
424
+ 'AZURE_CLIENT_SECRET',
425
+ 'GITHUB_TOKEN',
426
+ 'GITHUB_USERNAME',
427
+ 'GITHUB_ORGANIZATION'
428
+ ];
429
+ // Union of every credential key across providers — `resolveCredentials` only
430
+ // requires the subset matching the target deployment, but the type covers both
431
+ // so a single Credentials object can be read/written regardless of provider.
432
+ exports.REQUIRED_CREDENTIAL_KEYS = [
433
+ ...exports.AWS_REQUIRED_CREDENTIAL_KEYS,
434
+ ...exports.AZURE_REQUIRED_CREDENTIAL_KEYS
43
435
  ];
436
+ function requiredCredentialKeysFor(deployment) {
437
+ return deployment === 'azure'
438
+ ? exports.AZURE_REQUIRED_CREDENTIAL_KEYS
439
+ : exports.AWS_REQUIRED_CREDENTIAL_KEYS;
440
+ }
44
441
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/infra/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/infra/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ # Azure prod isolation — pending points
2
+
3
+ Context: expanding to a fully isolated `infra-prod` (separate RG, separate
4
+ tfstate, separate Key Vault/OIDC identity from dev/stg) with heavier prod
5
+ specs (SQL 6 vCore GP zone-redundant, Front Door Premium+WAF, Container
6
+ Apps Dedicated D4x2, Defender for Cloud, etc).
7
+
8
+ ## Done — Key Vault per-app secrets pre-populated (closed on feature/azure-provider-support)
9
+
10
+ Each app's vault now gets an `azurerm_key_vault_secret` named `app-variables`
11
+ holding `jsonencode(local.app_variables[app])` — one JSON blob per app,
12
+ mirroring ECS's `modules/secret` (which also stores all of an app's
13
+ `variables:` as one JSON blob, not one secret per key).
14
+
15
+ Two blockers closed:
16
+
17
+ - **RBAC** (data-plane `Key Vault Secrets Officer`, which `Contributor` doesn't
18
+ cover): resolved _without_ the Graph-lookup problem the github_oidc
19
+ `existing_principal_id` escape hatch needed — `data.azurerm_client_config.current.object_id`
20
+ resolves the _running_ SP's own object_id purely via ARM, no
21
+ `Application.Read.All` required.
22
+ - **Network** (found while implementing, wasn't in this doc before): the vault
23
+ defaults to `public_network_access_enabled = false`, so `network_acls` never
24
+ even applies — writing a secret from a local machine (not a VNet-joined
25
+ identity) 403s regardless of RBAC. Fixed via `modules/azure-key-vault`'s new
26
+ `ip_rules` var: `data.http.tofu_operator_ip` auto-detects the operator's
27
+ current public IP (`api.ipify.org`) each apply and allowlists just that /32,
28
+ flipping `public_network_access_enabled` on only when `ip_rules` is non-empty.
29
+ A `time_sleep` (30s) sits between the role assignment and the secret write —
30
+ Azure RBAC propagation isn't instant, so writing in the same apply that
31
+ grants the role can otherwise 403 intermittently.
32
+
33
+ Not addressed: this doesn't give the _app itself_ read access over the network
34
+ at runtime (Container Apps egress via the NAT Gateway's public IP, which isn't
35
+ on the allowlist and isn't covered by `bypass = "AzureServices"`). Today no app
36
+ code actually reads from Key Vault via SDK — `KEY_VAULT_URI` is informational
37
+ and env vars are still delivered as plaintext Container App `env_vars`/`secrets`
38
+ (see "Decided, not implemented yet" below for that separate gap). If an app
39
+ ever needs to read its vault directly, this'll need a private endpoint or a
40
+ broader firewall rule for the Container Apps subnet's egress IP.
41
+
42
+ ## Already fixed (committed on feature/azure-provider-support)
43
+
44
+ - `github_oidc.enabled` sensitivity leak (`for_each`/output error) — fixed via
45
+ `nonsensitive()` in `templates/azure/locals.tf` (`local.github_oidc_enabled`).
46
+ - Orphan private DNS zones in `modules/azure-network` (e.g. postgres zone
47
+ created even when only mssql is used) — gated behind `postgres_needed`/
48
+ `mssql_needed`/`redis_needed` flags computed from `local.app_list`.
49
+ - Container App `secret` block used the raw (unsanitized) secret key as the
50
+ Azure secret name — fixed to reuse `local.secret_names`.
51
+ - SQL LTR + auto-pause both enabled by default, which Azure rejects on a
52
+ serverless database — LTR now only applies when `auto_pause_delay_in_minutes
53
+ == -1` (i.e. provisioned/prod databases).
54
+ - `packages/infra` was left behind in every scaffolded project (only
55
+ `packages/cli` was cleaned up) — now removed the same way. `templates/azure`
56
+ had no `.gitignore` (unlike `templates/ecs`) — added one.
57
+ - `fuel infra:deploy --regenerate` never resolved a template source (no
58
+ `--source`, no GitHub-token download) — wired through `resolveSourceRoot()`.
59
+ - Subscription missing required resource provider registrations (`Microsoft.App`
60
+ 409 mid-apply) — `providers.tf` now explicitly registers everything this
61
+ template set needs via `resource_providers_to_register` (azurerm >= 4.0).
62
+ - Container Apps referenced `${acr}/${app}:latest` from creation, but that tag
63
+ never exists yet (CI depends on this same apply having run first) — seeded
64
+ with a public placeholder image + `ignore_changes` so CI's first real push
65
+ takes over permanently.
66
+ - Container Apps subnet had no NAT Gateway/route table — Azure's "default
67
+ outbound access" retirement means no reliable egress for image pulls
68
+ without one. Added a Standard NAT Gateway to the subnet.
69
+ - `azurerm_container_app` always declared a `registry` block pointing at the
70
+ ACR, but the AcrPull role assignment for that identity is necessarily
71
+ created _after_ the container app — Azure hung validating an unauthorized
72
+ credential on first create regardless of which image was pulled. Dropped
73
+ the `registry` block; CI now configures it via `az containerapp registry
74
+ set` once the role assignment already exists.
75
+ - Every Front Door route also set `link_to_default_domain = true`, so the
76
+ second app's route collided with the first on the shared `*.azurefd.net`
77
+ hostname/path. Now only links the default domain when an app has no custom
78
+ domain (which, since `domain` is required, is never in practice).
79
+ - `github_repo_name` as explicit field — done, see below.
80
+
81
+ ## Decided, not implemented yet
82
+
83
+ 1. **Multi-environment pipelines.** `templates/azure/workflows/build_and_deploy.yml`
84
+ uses repo-wide secrets (`AZURE_CLIENT_ID`/`TENANT_ID`/`SUBSCRIPTION_ID`/
85
+ `ACR_LOGIN_SERVER`, no `environment:` on the job) and bakes
86
+ `RESOURCE_GROUP`/`ACR_NAME`/`CONTAINER_APP_NAME` as literal strings at
87
+ generation time (`copyAzureWorkflows` in `template-engine.ts`). Need to
88
+ move to GitHub Environments (per-env secrets/vars + protection rules for
89
+ prod) before generating a prod workflow in the same repo as dev — same
90
+ app name today would silently overwrite the dev workflow file.
91
+ 2. **Front Door Premium + WAF** (OWASP 3.2 + bot protection). Schema
92
+ (`fuel.schema.json` → `azureConfig.front_door.sku_name`) hardcodes
93
+ `Standard_AzureFrontDoor` as a `const`. Module
94
+ `modules/azure-front-door` has no `azurerm_cdn_frontdoor_security_policy`/
95
+ WAF policy resource at all. Since prod gets its own Terraform state this
96
+ no longer conflicts with dev/stg — just needs the schema const relaxed
97
+ and the WAF resource added.
98
+ 3. **Container Apps Dedicated plan** (D4 x2). `modules/azure-container-apps-environment`
99
+ is Consumption-only _by design_ (explicit comment in `main.tf`). Needs a
100
+ `workload_profile` block + a way to select Dedicated per-app/per-env.
101
+
102
+ ## No Terraform module exists (infra gap, not config gap)
103
+
104
+ - Microsoft Defender for Cloud (Containers/SQL/Storage/Key Vault plans)
105
+ - Static Web Apps
106
+ - Azure DevOps pipelines (stack uses GitHub Actions instead — confirm this
107
+ is acceptable for prod or if Azure DevOps is a hard requirement)
108
+ - Support plan (subscription-level purchase, not a Terraform resource —
109
+ won't ever be a fuel.yml field)
110
+
111
+ ## Still need to verify
112
+
113
+ - Count actual `azurerm_private_endpoint`-equivalent resources created
114
+ today (SQL, Redis) vs. the prod spec line "5 private endpoints x 730h,
115
+ 100GB in/out" — only confirmed the network _structure_ (subnets/DNS
116
+ zones) exists, not an exact endpoint count against spec.
117
+
118
+ ## Action not yet taken
119
+
120
+ - No one has actually scaffolded `infra-prod` yet (new `fuel.yml` + running
121
+ the CLI generation into a separate target dir). Isolation is designed but
122
+ not yet real until that runs.
123
+
124
+ ## Suggested next pick (unresolved — pick one to start)
125
+
126
+ - GitHub Environments wiring (workflow template + docs)
127
+ - Front Door WAF (schema + module)