dojo.md 0.2.2 → 0.2.4

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 (196) hide show
  1. package/courses/GENERATION_LOG.md +29 -0
  2. package/courses/api-documentation-writing/course.yaml +12 -0
  3. package/courses/api-documentation-writing/scenarios/level-1/authentication-basics.yaml +46 -0
  4. package/courses/api-documentation-writing/scenarios/level-1/data-types-formats.yaml +45 -0
  5. package/courses/api-documentation-writing/scenarios/level-1/endpoint-description.yaml +45 -0
  6. package/courses/api-documentation-writing/scenarios/level-1/error-documentation.yaml +45 -0
  7. package/courses/api-documentation-writing/scenarios/level-1/first-documentation-shift.yaml +47 -0
  8. package/courses/api-documentation-writing/scenarios/level-1/getting-started-guide.yaml +42 -0
  9. package/courses/api-documentation-writing/scenarios/level-1/pagination-docs.yaml +51 -0
  10. package/courses/api-documentation-writing/scenarios/level-1/request-parameters.yaml +46 -0
  11. package/courses/api-documentation-writing/scenarios/level-1/request-response-examples.yaml +48 -0
  12. package/courses/api-documentation-writing/scenarios/level-1/status-codes.yaml +45 -0
  13. package/courses/api-documentation-writing/scenarios/level-2/error-patterns.yaml +48 -0
  14. package/courses/api-documentation-writing/scenarios/level-2/intermediate-documentation-shift.yaml +48 -0
  15. package/courses/api-documentation-writing/scenarios/level-2/oauth-documentation.yaml +47 -0
  16. package/courses/api-documentation-writing/scenarios/level-2/openapi-specification.yaml +46 -0
  17. package/courses/api-documentation-writing/scenarios/level-2/rate-limiting-docs.yaml +45 -0
  18. package/courses/api-documentation-writing/scenarios/level-2/request-body-schemas.yaml +46 -0
  19. package/courses/api-documentation-writing/scenarios/level-2/schema-definitions.yaml +41 -0
  20. package/courses/api-documentation-writing/scenarios/level-2/swagger-redoc-rendering.yaml +43 -0
  21. package/courses/api-documentation-writing/scenarios/level-2/validation-documentation.yaml +47 -0
  22. package/courses/api-documentation-writing/scenarios/level-2/versioning-changelog.yaml +42 -0
  23. package/courses/api-documentation-writing/scenarios/level-3/advanced-documentation-shift.yaml +43 -0
  24. package/courses/api-documentation-writing/scenarios/level-3/api-style-guide.yaml +40 -0
  25. package/courses/api-documentation-writing/scenarios/level-3/code-samples-multilang.yaml +40 -0
  26. package/courses/api-documentation-writing/scenarios/level-3/content-architecture.yaml +47 -0
  27. package/courses/api-documentation-writing/scenarios/level-3/deprecation-communication.yaml +44 -0
  28. package/courses/api-documentation-writing/scenarios/level-3/interactive-api-explorer.yaml +42 -0
  29. package/courses/api-documentation-writing/scenarios/level-3/migration-guides.yaml +42 -0
  30. package/courses/api-documentation-writing/scenarios/level-3/sdk-documentation.yaml +40 -0
  31. package/courses/api-documentation-writing/scenarios/level-3/webhook-documentation.yaml +48 -0
  32. package/courses/api-documentation-writing/scenarios/level-3/websocket-sse-docs.yaml +47 -0
  33. package/courses/api-documentation-writing/scenarios/level-4/api-changelog-management.yaml +44 -0
  34. package/courses/api-documentation-writing/scenarios/level-4/api-governance-standards.yaml +41 -0
  35. package/courses/api-documentation-writing/scenarios/level-4/api-product-strategy.yaml +41 -0
  36. package/courses/api-documentation-writing/scenarios/level-4/developer-portal-design.yaml +48 -0
  37. package/courses/api-documentation-writing/scenarios/level-4/docs-as-code.yaml +41 -0
  38. package/courses/api-documentation-writing/scenarios/level-4/documentation-localization.yaml +46 -0
  39. package/courses/api-documentation-writing/scenarios/level-4/documentation-metrics.yaml +45 -0
  40. package/courses/api-documentation-writing/scenarios/level-4/documentation-testing.yaml +41 -0
  41. package/courses/api-documentation-writing/scenarios/level-4/expert-documentation-shift.yaml +45 -0
  42. package/courses/api-documentation-writing/scenarios/level-4/multi-audience-docs.yaml +46 -0
  43. package/courses/api-documentation-writing/scenarios/level-5/ai-powered-documentation.yaml +44 -0
  44. package/courses/api-documentation-writing/scenarios/level-5/api-first-documentation.yaml +45 -0
  45. package/courses/api-documentation-writing/scenarios/level-5/api-marketplace-docs.yaml +42 -0
  46. package/courses/api-documentation-writing/scenarios/level-5/board-api-strategy.yaml +48 -0
  47. package/courses/api-documentation-writing/scenarios/level-5/documentation-program-strategy.yaml +42 -0
  48. package/courses/api-documentation-writing/scenarios/level-5/documentation-team-structure.yaml +47 -0
  49. package/courses/api-documentation-writing/scenarios/level-5/dx-competitive-advantage.yaml +46 -0
  50. package/courses/api-documentation-writing/scenarios/level-5/ecosystem-documentation.yaml +45 -0
  51. package/courses/api-documentation-writing/scenarios/level-5/industry-documentation-patterns.yaml +46 -0
  52. package/courses/api-documentation-writing/scenarios/level-5/master-documentation-shift.yaml +46 -0
  53. package/courses/code-review-feedback-writing/course.yaml +12 -0
  54. package/courses/code-review-feedback-writing/scenarios/level-1/approve-vs-request-changes.yaml +48 -0
  55. package/courses/code-review-feedback-writing/scenarios/level-1/asking-questions.yaml +50 -0
  56. package/courses/code-review-feedback-writing/scenarios/level-1/clear-comment-writing.yaml +45 -0
  57. package/courses/code-review-feedback-writing/scenarios/level-1/constructive-tone.yaml +43 -0
  58. package/courses/code-review-feedback-writing/scenarios/level-1/first-review-shift.yaml +46 -0
  59. package/courses/code-review-feedback-writing/scenarios/level-1/giving-praise.yaml +44 -0
  60. package/courses/code-review-feedback-writing/scenarios/level-1/nitpick-etiquette.yaml +44 -0
  61. package/courses/code-review-feedback-writing/scenarios/level-1/providing-context.yaml +46 -0
  62. package/courses/code-review-feedback-writing/scenarios/level-1/reviewing-small-prs.yaml +43 -0
  63. package/courses/code-review-feedback-writing/scenarios/level-1/style-vs-logic.yaml +48 -0
  64. package/courses/code-review-feedback-writing/scenarios/level-2/architectural-feedback.yaml +52 -0
  65. package/courses/code-review-feedback-writing/scenarios/level-2/intermediate-review-shift.yaml +46 -0
  66. package/courses/code-review-feedback-writing/scenarios/level-2/performance-feedback.yaml +50 -0
  67. package/courses/code-review-feedback-writing/scenarios/level-2/reviewing-breaking-changes.yaml +44 -0
  68. package/courses/code-review-feedback-writing/scenarios/level-2/reviewing-complex-prs.yaml +43 -0
  69. package/courses/code-review-feedback-writing/scenarios/level-2/reviewing-documentation.yaml +47 -0
  70. package/courses/code-review-feedback-writing/scenarios/level-2/reviewing-error-handling.yaml +50 -0
  71. package/courses/code-review-feedback-writing/scenarios/level-2/reviewing-tests.yaml +53 -0
  72. package/courses/code-review-feedback-writing/scenarios/level-2/security-review-comments.yaml +50 -0
  73. package/courses/code-review-feedback-writing/scenarios/level-2/suggesting-alternatives.yaml +42 -0
  74. package/courses/code-review-feedback-writing/scenarios/level-3/advanced-review-shift.yaml +48 -0
  75. package/courses/code-review-feedback-writing/scenarios/level-3/api-design-review.yaml +47 -0
  76. package/courses/code-review-feedback-writing/scenarios/level-3/cross-team-review.yaml +45 -0
  77. package/courses/code-review-feedback-writing/scenarios/level-3/database-migration-review.yaml +48 -0
  78. package/courses/code-review-feedback-writing/scenarios/level-3/design-pattern-feedback.yaml +48 -0
  79. package/courses/code-review-feedback-writing/scenarios/level-3/mentoring-through-review.yaml +46 -0
  80. package/courses/code-review-feedback-writing/scenarios/level-3/production-incident-review.yaml +42 -0
  81. package/courses/code-review-feedback-writing/scenarios/level-3/reviewing-senior-code.yaml +47 -0
  82. package/courses/code-review-feedback-writing/scenarios/level-3/reviewing-unfamiliar-code.yaml +43 -0
  83. package/courses/code-review-feedback-writing/scenarios/level-3/speed-vs-thoroughness.yaml +46 -0
  84. package/courses/code-review-feedback-writing/scenarios/level-4/automated-review-strategy.yaml +44 -0
  85. package/courses/code-review-feedback-writing/scenarios/level-4/expert-review-shift.yaml +46 -0
  86. package/courses/code-review-feedback-writing/scenarios/level-4/review-culture-design.yaml +41 -0
  87. package/courses/code-review-feedback-writing/scenarios/level-4/review-guidelines-standards.yaml +45 -0
  88. package/courses/code-review-feedback-writing/scenarios/level-4/review-load-balancing.yaml +39 -0
  89. package/courses/code-review-feedback-writing/scenarios/level-4/review-metrics.yaml +39 -0
  90. package/courses/code-review-feedback-writing/scenarios/level-4/review-process-optimization.yaml +48 -0
  91. package/courses/code-review-feedback-writing/scenarios/level-4/scaling-review-process.yaml +45 -0
  92. package/courses/code-review-feedback-writing/scenarios/level-4/security-review-standards.yaml +41 -0
  93. package/courses/code-review-feedback-writing/scenarios/level-4/training-reviewers.yaml +42 -0
  94. package/courses/code-review-feedback-writing/scenarios/level-5/board-quality-metrics.yaml +44 -0
  95. package/courses/code-review-feedback-writing/scenarios/level-5/knowledge-transfer-at-scale.yaml +42 -0
  96. package/courses/code-review-feedback-writing/scenarios/level-5/ma-review-alignment.yaml +50 -0
  97. package/courses/code-review-feedback-writing/scenarios/level-5/master-review-shift.yaml +49 -0
  98. package/courses/code-review-feedback-writing/scenarios/level-5/review-competitive-advantage.yaml +48 -0
  99. package/courses/code-review-feedback-writing/scenarios/level-5/review-organizational-learning.yaml +46 -0
  100. package/courses/code-review-feedback-writing/scenarios/level-5/review-roi-analysis.yaml +51 -0
  101. package/courses/code-review-feedback-writing/scenarios/level-5/review-velocity-impact.yaml +44 -0
  102. package/courses/code-review-feedback-writing/scenarios/level-5/scaling-reviews-100-plus.yaml +45 -0
  103. package/courses/code-review-feedback-writing/scenarios/level-5/toxic-culture-transformation.yaml +46 -0
  104. package/courses/technical-rfc-writing/course.yaml +11 -0
  105. package/courses/technical-rfc-writing/scenarios/level-1/first-rfc-shift.yaml +45 -0
  106. package/courses/technical-rfc-writing/scenarios/level-1/implementation-planning.yaml +47 -0
  107. package/courses/technical-rfc-writing/scenarios/level-1/open-questions.yaml +46 -0
  108. package/courses/technical-rfc-writing/scenarios/level-1/problem-statement.yaml +41 -0
  109. package/courses/technical-rfc-writing/scenarios/level-1/proposing-solutions.yaml +49 -0
  110. package/courses/technical-rfc-writing/scenarios/level-1/rfc-structure.yaml +41 -0
  111. package/courses/technical-rfc-writing/scenarios/level-1/risks-and-mitigations.yaml +43 -0
  112. package/courses/technical-rfc-writing/scenarios/level-1/scoping-an-rfc.yaml +49 -0
  113. package/courses/technical-rfc-writing/scenarios/level-1/success-metrics.yaml +43 -0
  114. package/courses/technical-rfc-writing/scenarios/level-1/writing-for-audience.yaml +42 -0
  115. package/courses/technical-rfc-writing/scenarios/level-2/risk-assessment-matrix.yaml +43 -0
  116. package/courses/technical-rfc-writing/scenarios/level-2/technical-design-detail.yaml +42 -0
  117. package/courses/technical-rfc-writing/scenarios/level-2/trade-off-analysis.yaml +43 -0
  118. package/courses/terraform-infrastructure-setup/scenarios/level-1/first-debugging-shift.yaml +66 -0
  119. package/courses/terraform-infrastructure-setup/scenarios/level-1/plan-output-reading.yaml +71 -0
  120. package/courses/terraform-infrastructure-setup/scenarios/level-1/resource-creation-failures.yaml +54 -0
  121. package/courses/terraform-infrastructure-setup/scenarios/level-1/resource-references.yaml +70 -0
  122. package/courses/terraform-infrastructure-setup/scenarios/level-1/state-file-basics.yaml +73 -0
  123. package/courses/terraform-infrastructure-setup/scenarios/level-1/terraform-fmt-validate.yaml +58 -0
  124. package/courses/terraform-infrastructure-setup/scenarios/level-2/count-vs-for-each.yaml +58 -0
  125. package/courses/terraform-infrastructure-setup/scenarios/level-2/dependency-management.yaml +80 -0
  126. package/courses/terraform-infrastructure-setup/scenarios/level-2/intermediate-debugging-shift.yaml +66 -0
  127. package/courses/terraform-infrastructure-setup/scenarios/level-2/lifecycle-rules.yaml +51 -0
  128. package/courses/terraform-infrastructure-setup/scenarios/level-2/locals-and-expressions.yaml +58 -0
  129. package/courses/terraform-infrastructure-setup/scenarios/level-2/module-structure.yaml +75 -0
  130. package/courses/terraform-infrastructure-setup/scenarios/level-2/provisioner-pitfalls.yaml +64 -0
  131. package/courses/terraform-infrastructure-setup/scenarios/level-2/remote-state-backend.yaml +55 -0
  132. package/courses/terraform-infrastructure-setup/scenarios/level-2/terraform-import.yaml +55 -0
  133. package/courses/terraform-infrastructure-setup/scenarios/level-2/workspace-management.yaml +51 -0
  134. package/courses/terraform-infrastructure-setup/scenarios/level-3/advanced-debugging-shift.yaml +63 -0
  135. package/courses/terraform-infrastructure-setup/scenarios/level-3/api-rate-limiting.yaml +50 -0
  136. package/courses/terraform-infrastructure-setup/scenarios/level-3/conditional-resources.yaml +66 -0
  137. package/courses/terraform-infrastructure-setup/scenarios/level-3/drift-detection.yaml +66 -0
  138. package/courses/terraform-infrastructure-setup/scenarios/level-3/dynamic-blocks.yaml +71 -0
  139. package/courses/terraform-infrastructure-setup/scenarios/level-3/large-scale-refactoring.yaml +59 -0
  140. package/courses/terraform-infrastructure-setup/scenarios/level-3/multi-provider-config.yaml +69 -0
  141. package/courses/terraform-infrastructure-setup/scenarios/level-3/state-surgery.yaml +57 -0
  142. package/courses/terraform-infrastructure-setup/scenarios/level-3/terraform-cloud-enterprise.yaml +59 -0
  143. package/courses/terraform-infrastructure-setup/scenarios/level-3/terraform-debugging.yaml +51 -0
  144. package/courses/terraform-infrastructure-setup/scenarios/level-4/blast-radius-management.yaml +51 -0
  145. package/courses/terraform-infrastructure-setup/scenarios/level-4/cicd-pipeline-design.yaml +50 -0
  146. package/courses/terraform-infrastructure-setup/scenarios/level-4/compliance-as-code.yaml +46 -0
  147. package/courses/terraform-infrastructure-setup/scenarios/level-4/cost-estimation-governance.yaml +42 -0
  148. package/courses/terraform-infrastructure-setup/scenarios/level-4/expert-debugging-shift.yaml +51 -0
  149. package/courses/terraform-infrastructure-setup/scenarios/level-4/iac-organization-strategy.yaml +45 -0
  150. package/courses/terraform-infrastructure-setup/scenarios/level-4/incident-response-iac.yaml +47 -0
  151. package/courses/terraform-infrastructure-setup/scenarios/level-4/infrastructure-testing.yaml +41 -0
  152. package/courses/terraform-infrastructure-setup/scenarios/level-4/module-registry-design.yaml +45 -0
  153. package/courses/terraform-infrastructure-setup/scenarios/level-4/multi-account-strategy.yaml +57 -0
  154. package/courses/terraform-infrastructure-setup/scenarios/level-5/board-infrastructure-investment.yaml +53 -0
  155. package/courses/terraform-infrastructure-setup/scenarios/level-5/disaster-recovery-iac.yaml +47 -0
  156. package/courses/terraform-infrastructure-setup/scenarios/level-5/enterprise-iac-transformation.yaml +48 -0
  157. package/courses/terraform-infrastructure-setup/scenarios/level-5/iac-technology-evolution.yaml +49 -0
  158. package/courses/terraform-infrastructure-setup/scenarios/level-5/ma-infrastructure-consolidation.yaml +54 -0
  159. package/courses/terraform-infrastructure-setup/scenarios/level-5/master-debugging-shift.yaml +53 -0
  160. package/courses/terraform-infrastructure-setup/scenarios/level-5/multi-cloud-strategy.yaml +49 -0
  161. package/courses/terraform-infrastructure-setup/scenarios/level-5/platform-engineering.yaml +47 -0
  162. package/courses/terraform-infrastructure-setup/scenarios/level-5/regulatory-compliance-automation.yaml +47 -0
  163. package/courses/terraform-infrastructure-setup/scenarios/level-5/terraform-vs-alternatives.yaml +46 -0
  164. package/dist/cli/commands/generate.d.ts.map +1 -1
  165. package/dist/cli/commands/generate.js +2 -1
  166. package/dist/cli/commands/generate.js.map +1 -1
  167. package/dist/cli/commands/train.d.ts.map +1 -1
  168. package/dist/cli/commands/train.js +6 -3
  169. package/dist/cli/commands/train.js.map +1 -1
  170. package/dist/cli/index.js +9 -6
  171. package/dist/cli/index.js.map +1 -1
  172. package/dist/cli/run-demo.js +3 -2
  173. package/dist/cli/run-demo.js.map +1 -1
  174. package/dist/engine/model-utils.d.ts +6 -0
  175. package/dist/engine/model-utils.d.ts.map +1 -1
  176. package/dist/engine/model-utils.js +28 -1
  177. package/dist/engine/model-utils.js.map +1 -1
  178. package/dist/engine/training.d.ts.map +1 -1
  179. package/dist/engine/training.js +4 -3
  180. package/dist/engine/training.js.map +1 -1
  181. package/dist/evaluator/judge.d.ts +7 -1
  182. package/dist/evaluator/judge.d.ts.map +1 -1
  183. package/dist/evaluator/judge.js +50 -11
  184. package/dist/evaluator/judge.js.map +1 -1
  185. package/dist/generator/course-generator.d.ts.map +1 -1
  186. package/dist/generator/course-generator.js +4 -3
  187. package/dist/generator/course-generator.js.map +1 -1
  188. package/dist/mcp/server.d.ts.map +1 -1
  189. package/dist/mcp/server.js +7 -3
  190. package/dist/mcp/server.js.map +1 -1
  191. package/dist/mcp/session-manager.d.ts.map +1 -1
  192. package/dist/mcp/session-manager.js +3 -2
  193. package/dist/mcp/session-manager.js.map +1 -1
  194. package/dist/types/index.d.ts +1 -1
  195. package/dist/types/index.d.ts.map +1 -1
  196. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ meta:
2
+ id: technical-design-detail
3
+ level: 2
4
+ course: technical-rfc-writing
5
+ type: output
6
+ description: "Write detailed technical designs — create architecture diagrams, data models, and API specifications within an RFC at the right level of detail"
7
+ tags: [RFC, technical-design, architecture, data-model, API, intermediate]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ You're writing the technical design section of an RFC proposing a
13
+ notification system. The system needs to:
14
+ - Send notifications via email, SMS, and push notifications
15
+ - Support user notification preferences (opt-in/out per channel)
16
+ - Handle templating for different notification types
17
+ - Queue notifications for reliability and rate limiting
18
+ - Track delivery status (sent, delivered, failed, read)
19
+
20
+ Your challenge: engineers want detailed technical design, but
21
+ managers keep asking "do I need to read all this?" You need to
22
+ provide enough detail for engineers to evaluate feasibility and
23
+ identify issues, without making the RFC impenetrable.
24
+
25
+ Task: Write the technical design section including: system
26
+ architecture (with component descriptions), data model, API
27
+ design, and sequence diagrams (in text/mermaid format). Show how
28
+ to provide technical depth while keeping the section navigable.
29
+
30
+ assertions:
31
+ - type: llm_judge
32
+ criteria: "Architecture is clearly described with components and interactions — components: (1) Notification Service API (receives notification requests, validates, queues). (2) Message Queue (decouples sending from requesting, enables retry). (3) Channel Dispatchers (email via SendGrid/SES, SMS via Twilio, push via FCM/APNS — each as separate workers). (4) Preference Service (reads user notification preferences, filters channels). (5) Template Engine (renders notification content from templates + variables). (6) Delivery Tracker (records status updates, provides read receipts). Data flow described: 'Service A calls Notification API with (user_id, notification_type, payload) → API checks preferences → renders templates → enqueues per channel → dispatchers process and report delivery status.' Component interactions are explicit — which component calls which, synchronous vs asynchronous boundaries clearly marked"
33
+ weight: 0.35
34
+ description: "Architecture clarity"
35
+ - type: llm_judge
36
+ criteria: "Data model and API design are specific enough to evaluate — data model includes key tables/schemas: notifications (id, user_id, type, status, created_at, channels), notification_preferences (user_id, channel, notification_type, enabled), notification_templates (type, channel, subject_template, body_template), delivery_log (notification_id, channel, status, provider_response, attempted_at). API endpoints defined: POST /notifications (send), GET /notifications/:id (status), PUT /preferences (update user prefs), with request/response shapes shown. Sequence diagram (text or mermaid) for the happy path: caller → API → preference check → template render → queue → dispatcher → provider → delivery callback. The design should be specific enough that an engineer could identify gaps ('what about batch notifications?') but not so detailed that it's pseudocode"
37
+ weight: 0.35
38
+ description: "Data model and API"
39
+ - type: llm_judge
40
+ criteria: "Technical depth is balanced — navigable structure: overview paragraph (3 sentences summarizing the architecture for skimmers), then detailed subsections with clear headings (Architecture Overview, Data Model, API Design, Sequence Flows). Each subsection starts with a one-sentence summary. Diagrams complement text rather than replacing it. Design decisions are called out: 'We use a message queue between the API and dispatchers because: synchronous sending would block the caller, retries are handled by the queue infrastructure, and we can add rate limiting per channel at the queue level.' Trade-offs acknowledged: 'Separate dispatcher workers per channel add operational complexity but allow independent scaling and deployment — email spikes (marketing campaigns) don't affect SMS delivery.' Non-obvious choices explained: why this queue technology, why these API patterns, why this data model structure. The section answers 'is this feasible?' and 'are there design flaws?' without being an implementation guide"
41
+ weight: 0.30
42
+ description: "Balanced depth"
@@ -0,0 +1,43 @@
1
+ meta:
2
+ id: trade-off-analysis
3
+ level: 2
4
+ course: technical-rfc-writing
5
+ type: output
6
+ description: "Analyze trade-offs systematically — evaluate competing solutions using weighted criteria and make the reasoning transparent"
7
+ tags: [RFC, trade-offs, decision-matrix, evaluation, criteria, intermediate]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ You're writing an RFC to choose a state management solution for your
13
+ growing React application. The app currently uses prop drilling and
14
+ local useState, but as it's grown to 50+ components across 8 feature
15
+ areas, state management has become a major pain point.
16
+
17
+ Options being debated:
18
+ 1. Redux Toolkit — mature, well-documented, large ecosystem
19
+ 2. Zustand — lightweight, minimal boilerplate, growing community
20
+ 3. React Context + useReducer — built-in, no dependencies, familiar
21
+ 4. Jotai — atomic state model, fine-grained reactivity, modern
22
+
23
+ Different team members advocate for different solutions based on
24
+ personal preference. The discussions are going in circles.
25
+
26
+ Task: Write a trade-off analysis section that evaluates these options
27
+ systematically using weighted criteria. The analysis should make the
28
+ decision process transparent and help the team converge on a choice
29
+ regardless of individual preferences.
30
+
31
+ assertions:
32
+ - type: llm_judge
33
+ criteria: "Evaluation criteria are defined and weighted before comparing options — criteria identified from project needs, not abstract quality: (1) Learning curve (weight: 25%) — team has 8 engineers with varying React experience, onboarding new hires quarterly. (2) Bundle size impact (weight: 15%) — mobile-first app, performance budget of 200KB JS. (3) Boilerplate/developer experience (weight: 20%) — team velocity matters, less ceremony preferred. (4) Scalability to 100+ components (weight: 20%) — app is growing, solution must handle complexity. (5) Community and ecosystem (weight: 20%) — long-term viability, available middleware, debugging tools. Weights are justified: 'Learning curve is weighted highest because our team composition means 3 engineers have never used external state management. An unfamiliar tool slows the entire team, not just adoption.' The criteria should emerge from the specific project context, not be a generic comparison"
34
+ weight: 0.35
35
+ description: "Weighted criteria"
36
+ - type: llm_judge
37
+ criteria: "Each option is scored fairly against criteria with evidence — scoring is specific, not 'good/bad': Redux Toolkit — learning curve: 3/5 (extensive docs but steep initial concepts: slices, thunks, selectors), bundle: 3/5 (11KB gzipped — within budget), DX: 3/5 (RTK reduces boilerplate significantly vs classic Redux but still more ceremony than alternatives), scalability: 5/5 (proven at massive scale, clear patterns), ecosystem: 5/5 (largest ecosystem, Redux DevTools, middleware). Zustand — learning curve: 5/5 (minimal API surface, hooks-based, familiar patterns), bundle: 5/5 (1KB gzipped), DX: 5/5 (minimal boilerplate, no providers), scalability: 4/5 (works well at scale but fewer established patterns for very large apps), ecosystem: 3/5 (growing but smaller than Redux). Similar depth for Context and Jotai. Scores have brief justifications. A weighted total is calculated. Sensitivity analysis: 'If we weight scalability higher (30%), Redux wins. With current weights, Zustand scores highest.' This shows the decision isn't arbitrary"
38
+ weight: 0.35
39
+ description: "Fair scoring with evidence"
40
+ - type: llm_judge
41
+ criteria: "Analysis leads to a clear recommendation with reversibility assessment — recommendation states: 'Based on weighted scoring, we recommend Zustand (weighted score: X) over Redux Toolkit (score: Y).' Why the scores matter: 'The 2-point advantage in learning curve and DX translates to faster adoption and higher team velocity in the first 3 months.' Acknowledges what's lost: 'We trade Redux's larger ecosystem and proven patterns at extreme scale for simplicity and developer experience. Given our current size (50 components) and growth trajectory, this trade-off favors Zustand.' Reversibility: 'Both Zustand and Redux use hooks-based APIs. Migration from Zustand to Redux, if needed, involves refactoring store definitions — estimated 2-3 weeks for current codebase. This makes Zustand a low-risk starting choice.' Conditions for revisiting: 'If the app exceeds 200 components or we need server-side state synchronization, re-evaluate Redux Toolkit or TanStack Query.' The analysis should feel objective enough that someone favoring Redux could accept the Zustand recommendation"
42
+ weight: 0.30
43
+ description: "Clear recommendation"
@@ -0,0 +1,66 @@
1
+ meta:
2
+ id: first-debugging-shift
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Combined beginner shift — handle multiple Terraform issues during your first on-call including init failures, plan errors, and state problems"
7
+ tags: [Terraform, troubleshooting, combined, shift-simulation, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ It's your first week managing Terraform infrastructure. You face
13
+ three issues in one day:
14
+
15
+ Issue 1 — New engineer can't get started:
16
+ ```
17
+ $ terraform init
18
+
19
+ Error: Failed to get existing workspaces: S3 bucket
20
+ "company-tf-state" does not exist.
21
+ ```
22
+ The engineer cloned the repo but nobody told them about the
23
+ backend S3 bucket setup.
24
+
25
+ Issue 2 — Staging plan shows unexpected destroy:
26
+ ```
27
+ $ terraform plan
28
+
29
+ # aws_instance.app[0] will be destroyed
30
+ # aws_instance.app[1] will be destroyed
31
+ # aws_instance.app[2] will be destroyed
32
+ # aws_instance.app["web-1"] will be created
33
+ # aws_instance.app["web-2"] will be created
34
+ # aws_instance.app["web-3"] will be created
35
+
36
+ Plan: 3 to add, 0 to change, 3 to destroy.
37
+ ```
38
+ Someone refactored from count to for_each. The 3 instances will be
39
+ destroyed and recreated, causing downtime.
40
+
41
+ Issue 3 — State lock stuck:
42
+ ```
43
+ Error: Error acquiring the state lock
44
+ Lock Info:
45
+ ID: abc-123
46
+ Who: jenkins@ci-server
47
+ Created: 2024-01-15 08:00:00 UTC
48
+ ```
49
+ The CI pipeline crashed mid-apply 6 hours ago and the lock is stale.
50
+
51
+ Task: Diagnose and fix all three issues. Explain the root causes
52
+ and preventive measures for each.
53
+
54
+ assertions:
55
+ - type: llm_judge
56
+ criteria: "Issue 1 (init failure) is resolved — the S3 backend bucket must exist before terraform init. Fix: create the bucket manually (or with a separate bootstrap Terraform config), or use terraform init -backend-config=path/to/backend.hcl for flexible backend configuration. Document the bootstrap process in README. Consider: use a Makefile or script that checks prerequisites before init. For new engineers: provide onboarding docs with exact setup steps, or use Terraform Cloud to avoid S3 backend setup entirely"
57
+ weight: 0.35
58
+ description: "Init failure"
59
+ - type: llm_judge
60
+ criteria: "Issue 2 (count to for_each migration) is resolved — switching from count to for_each changes resource addresses (aws_instance.app[0] → aws_instance.app['web-1']), causing Terraform to see them as different resources. Fix: use terraform state mv to rename resources in state: terraform state mv 'aws_instance.app[0]' 'aws_instance.app[\"web-1\"]' for each instance. This avoids recreation. Alternative: use moved blocks in Terraform 1.1+: moved { from = aws_instance.app[0], to = aws_instance.app[\"web-1\"] }. Always check plan after refactoring"
61
+ weight: 0.35
62
+ description: "Count to for_each"
63
+ - type: llm_judge
64
+ criteria: "Issue 3 (stuck lock) is resolved — the CI pipeline crashed and didn't release the DynamoDB lock. Verify the lock is stale (6 hours old, CI pipeline is dead). Fix: terraform force-unlock abc-123. This is safe because the original process is dead. Prevention: CI/CD pipeline should have timeout protection, use terraform apply with -lock-timeout=5m to wait for locks, ensure CI cleanup steps release locks on failure. Warning: never force-unlock if the original process might still be running"
65
+ weight: 0.30
66
+ description: "Stuck lock"
@@ -0,0 +1,71 @@
1
+ meta:
2
+ id: plan-output-reading
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Read terraform plan output — interpret change symbols, understand resource actions, identify destructive changes before apply"
7
+ tags: [Terraform, plan, output, changes, destroy, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ Your terraform plan shows this output and you need to understand
13
+ what will happen before approving:
14
+
15
+ ```
16
+ Terraform will perform the following actions:
17
+
18
+ # aws_instance.web will be destroyed and re-created
19
+ # (because ami has changed)
20
+ -/+ resource "aws_instance" "web" {
21
+ ~ ami = "ami-old123" -> "ami-new456" # forces replacement
22
+ ~ arn = "arn:aws:ec2:..." -> (known after apply)
23
+ ~ id = "i-abc123" -> (known after apply)
24
+ instance_type = "t3.micro"
25
+ ~ public_ip = "54.1.2.3" -> (known after apply)
26
+ + secondary_private_ips = (known after apply)
27
+ - tags = {} -> null
28
+ # (15 unchanged attributes hidden)
29
+ }
30
+
31
+ # aws_s3_bucket.data will be updated in-place
32
+ ~ resource "aws_s3_bucket" "data" {
33
+ id = "my-data-bucket"
34
+ ~ tags = {
35
+ + "Environment" = "prod"
36
+ }
37
+ }
38
+
39
+ # aws_security_group.old will be destroyed
40
+ - resource "aws_security_group" "old" {
41
+ - id = "sg-old789" -> null
42
+ - name = "old-sg" -> null
43
+ }
44
+
45
+ # aws_security_group.new will be created
46
+ + resource "aws_security_group" "new" {
47
+ + id = (known after apply)
48
+ + name = "new-sg"
49
+ }
50
+
51
+ Plan: 2 to add, 1 to change, 2 to destroy.
52
+ ```
53
+
54
+ Task: Explain how to read terraform plan output, what each symbol
55
+ means (+, -, ~, -/+), what "forces replacement" means and why it's
56
+ dangerous, "known after apply" values, and best practices for
57
+ reviewing plans before apply.
58
+
59
+ assertions:
60
+ - type: llm_judge
61
+ criteria: "Plan symbols are explained — + (create): new resource will be created. - (destroy): existing resource will be deleted. ~ (update in-place): resource will be modified without recreation. -/+ (destroy and recreate): resource must be destroyed and recreated (replacement). +/- (create before destroy): new resource created first, then old destroyed (lifecycle create_before_destroy). Within attributes: + (added), - (removed), ~ (changed). 'forces replacement' means changing that attribute requires destroying and recreating the resource (e.g., changing AMI on EC2 instance). '(known after apply)' means the value will be determined by the cloud provider during creation"
62
+ weight: 0.35
63
+ description: "Plan symbols"
64
+ - type: llm_judge
65
+ criteria: "Dangerous changes are identified — destroy and recreate (-/+) is dangerous: causes downtime, new IP address, new resource ID. The example: changing AMI forces EC2 instance replacement — means the server goes down, gets a new public IP, loses ephemeral storage. Review all -/+ changes carefully. Mitigation: lifecycle { create_before_destroy = true } creates the new resource before destroying the old one (reduces downtime). Pure destroy (-) is also dangerous: verify you actually want to remove the resource. Summary line 'Plan: 2 to add, 1 to change, 2 to destroy' is the quick check"
66
+ weight: 0.35
67
+ description: "Dangerous changes"
68
+ - type: llm_judge
69
+ criteria: "Plan review best practices are practical — always run plan before apply. Save plan: terraform plan -out=plan.tfplan, then terraform apply plan.tfplan (prevents drift between plan and apply). In CI/CD: plan on PR, apply on merge. Review checklist: (1) any destroys? expected? (2) any replacements? understand why? (3) count of changes matches expectations? (4) no sensitive data exposed in plan output? Use terraform plan -target=resource to plan specific resources. terraform plan -detailed-exitcode: exit 0 (no changes), exit 1 (error), exit 2 (changes present) — useful in scripts"
70
+ weight: 0.30
71
+ description: "Review practices"
@@ -0,0 +1,54 @@
1
+ meta:
2
+ id: resource-creation-failures
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Debug resource creation failures — diagnose API errors, dependency issues, naming conflicts, and partial apply states"
7
+ tags: [Terraform, resources, apply, errors, dependencies, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ You run `terraform apply` and it partially succeeds:
13
+
14
+ ```
15
+ aws_vpc.main: Creating...
16
+ aws_vpc.main: Creation complete after 3s [id=vpc-0abc123def456]
17
+ aws_subnet.public: Creating...
18
+ aws_subnet.public: Creation complete after 1s [id=subnet-0abc789]
19
+ aws_security_group.web: Creating...
20
+
21
+ Error: creating Security Group (web-sg): InvalidGroup.Duplicate:
22
+ The security group 'web-sg' already exists for VPC 'vpc-0abc123def456'
23
+
24
+ aws_instance.web: Creating...
25
+
26
+ Error: creating EC2 Instance: UnauthorizedOperation: You are not
27
+ authorized to perform this operation. Encoded authorization failure
28
+ message: ...
29
+ ```
30
+
31
+ State after partial apply:
32
+ - VPC: created ✓
33
+ - Subnet: created ✓
34
+ - Security Group: FAILED ✗
35
+ - EC2 Instance: FAILED ✗
36
+
37
+ Task: Explain how terraform apply works (dependency graph, parallel
38
+ creation, partial state), what happens when apply partially fails,
39
+ how to recover from partial failures, common resource creation errors
40
+ (duplicates, permissions, quotas), and terraform plan vs apply workflow.
41
+
42
+ assertions:
43
+ - type: llm_judge
44
+ criteria: "Apply process is explained — terraform builds a dependency graph (DAG) and creates resources in parallel where possible. Resources with dependencies wait for their dependencies. Partial failure: successfully created resources are saved to state. Failed resources are not in state. On next apply, Terraform will try to create the failed resources again (it won't recreate already-created ones). The state file tracks what exists. Recovery: fix the errors and run apply again. terraform plan shows what will happen without making changes"
45
+ weight: 0.35
46
+ description: "Apply process"
47
+ - type: llm_judge
48
+ criteria: "Common creation errors are diagnosed — (1) Duplicate resource: security group already exists outside Terraform. Fix: import it (terraform import) or use a unique name. (2) UnauthorizedOperation: IAM permissions missing. Decode the message: aws sts decode-authorization-message. Fix: add required IAM permissions. (3) Quota exceeded: AWS service limits. Fix: request limit increase. (4) Invalid parameter: wrong AMI for region, invalid CIDR block. (5) Timeout: resource takes too long to create (increase timeouts in resource block)"
49
+ weight: 0.35
50
+ description: "Common errors"
51
+ - type: llm_judge
52
+ criteria: "Plan vs apply workflow is practical — terraform plan: preview changes without modifying infrastructure. Shows: resources to add (+), change (~), destroy (-). Save plan: terraform plan -out=tfplan, then terraform apply tfplan (ensures exactly the planned changes are applied). Always review plan before apply in production. terraform apply -auto-approve: skips confirmation (only for CI/CD, not manual runs). terraform destroy: removes all managed resources. Partial state: use terraform state list to see what's managed, terraform show for current state"
53
+ weight: 0.30
54
+ description: "Plan vs apply"
@@ -0,0 +1,70 @@
1
+ meta:
2
+ id: resource-references
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Fix resource reference errors — debug circular dependencies, missing attributes, implicit vs explicit dependencies, and data source lookups"
7
+ tags: [Terraform, references, dependencies, data-sources, expressions, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ Your Terraform configuration has reference errors:
13
+
14
+ ```
15
+ Error: Cycle: aws_security_group.web, aws_security_group.db
16
+
17
+ Error: Unsupported attribute
18
+
19
+ on main.tf line 25:
20
+ 25: vpc_id = aws_vpc.main.vpc_id
21
+
22
+ A managed resource "aws_vpc" "main" has not been declared in the
23
+ root module.
24
+ ```
25
+
26
+ Your configuration:
27
+
28
+ ```hcl
29
+ resource "aws_security_group" "web" {
30
+ ingress {
31
+ from_port = 443
32
+ to_port = 443
33
+ security_groups = [aws_security_group.db.id]
34
+ }
35
+ }
36
+
37
+ resource "aws_security_group" "db" {
38
+ ingress {
39
+ from_port = 5432
40
+ to_port = 5432
41
+ security_groups = [aws_security_group.web.id]
42
+ }
43
+ }
44
+
45
+ resource "aws_subnet" "public" {
46
+ vpc_id = aws_vpc.main.vpc_id
47
+ }
48
+ ```
49
+
50
+ The VPC already exists in AWS (created by another team) — you need
51
+ to reference it, not create it.
52
+
53
+ Task: Explain Terraform resource references, implicit vs explicit
54
+ dependencies, circular dependency detection and resolution, data
55
+ sources for reading existing infrastructure, and expression syntax
56
+ for accessing resource attributes.
57
+
58
+ assertions:
59
+ - type: llm_judge
60
+ criteria: "Resource references and dependencies are explained — implicit dependency: when resource A references resource B's attribute (aws_security_group.web.id), Terraform automatically creates A after B. Explicit dependency: depends_on = [aws_security_group.web] when there's no attribute reference but order matters. Circular dependency: A references B and B references A — Terraform can't determine creation order. Fix: break the cycle by using aws_security_group_rule as separate resources instead of inline ingress blocks, or use depends_on with one direction only"
61
+ weight: 0.35
62
+ description: "Dependencies"
63
+ - type: llm_judge
64
+ criteria: "Data sources are explained — data sources read existing infrastructure without managing it. data 'aws_vpc' 'main' { filter { name = 'tag:Name', values = ['production'] } } reads the VPC. Reference: data.aws_vpc.main.id. Use data sources when: resource exists outside your Terraform config, managed by another team/state, or pre-existing infrastructure. Common data sources: aws_ami (find latest AMI), aws_vpc, aws_subnet, aws_caller_identity (current AWS account), aws_region. Data sources are refreshed on every plan"
65
+ weight: 0.35
66
+ description: "Data sources"
67
+ - type: llm_judge
68
+ criteria: "Expression syntax is covered — resource attributes: aws_instance.web.id, aws_instance.web.public_ip. With count: aws_instance.web[0].id or aws_instance.web[*].id (splat). With for_each: aws_instance.web['key'].id. Module outputs: module.vpc.vpc_id. Data sources: data.aws_vpc.main.id. Local values: local.common_tags. Built-in functions: lookup(), element(), concat(), join(). Conditional: condition ? true_val : false_val. For expressions: [for s in var.list : upper(s)]"
69
+ weight: 0.30
70
+ description: "Expression syntax"
@@ -0,0 +1,73 @@
1
+ meta:
2
+ id: state-file-basics
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Understand Terraform state — diagnose state file corruption, lock conflicts, state drift, and local vs remote state tradeoffs"
7
+ tags: [Terraform, state, tfstate, locking, drift, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ Your colleague runs `terraform plan` and gets unexpected results:
13
+
14
+ ```
15
+ $ terraform plan
16
+
17
+ Note: Objects have changed outside of Terraform
18
+
19
+ Terraform detected the following changes made outside of Terraform
20
+ since the last "terraform apply":
21
+
22
+ # aws_instance.web has been changed
23
+ ~ resource "aws_instance" "web" {
24
+ ~ instance_type = "t3.micro" -> "t3.large"
25
+ # (10 unchanged attributes hidden)
26
+ }
27
+
28
+ Terraform will perform the following actions:
29
+
30
+ # aws_instance.web will be updated in-place
31
+ ~ resource "aws_instance" "web" {
32
+ ~ instance_type = "t3.large" -> "t3.micro"
33
+ }
34
+
35
+ Plan: 0 to add, 1 to change, 0 to destroy.
36
+ ```
37
+
38
+ Someone changed the instance type in the AWS console from t3.micro
39
+ to t3.large. Terraform wants to revert it back to match the code.
40
+
41
+ Also, when two people run terraform at the same time:
42
+ ```
43
+ Error: Error acquiring the state lock
44
+
45
+ Error message: ConditionalCheckFailedException: The conditional
46
+ request failed
47
+ Lock Info:
48
+ ID: 12345-abcde
49
+ Path: my-bucket/prod/terraform.tfstate
50
+ Operation: OperationTypeApply
51
+ Who: colleague@laptop
52
+ Version: 1.7.0
53
+ Created: 2024-01-15 10:30:00 UTC
54
+ ```
55
+
56
+ Task: Explain Terraform state fundamentals, what the state file
57
+ contains and why it exists, state drift detection and resolution,
58
+ state locking (why it matters, how it works with DynamoDB), and
59
+ local vs remote state.
60
+
61
+ assertions:
62
+ - type: llm_judge
63
+ criteria: "State fundamentals are explained — terraform.tfstate is a JSON file mapping configuration to real infrastructure IDs. It tracks: resource IDs, attribute values, dependencies, metadata. Why state exists: (1) map config to real resources (Terraform needs to know which aws_instance.web is vpc-abc123), (2) track metadata (dependencies), (3) performance (cache attribute values instead of querying APIs every time). State is the source of truth for what Terraform manages. Drift: when real infrastructure differs from state, detected during plan/apply refresh"
64
+ weight: 0.35
65
+ description: "State fundamentals"
66
+ - type: llm_judge
67
+ criteria: "Drift detection and resolution are covered — Terraform refreshes state before plan (compares real infrastructure to state). Drift detected: plan shows changes to revert. Options: (1) apply to revert to code (desired state wins), (2) update code to match reality (if the manual change was intentional), (3) terraform apply -refresh-only to update state without changing infrastructure. Best practice: all changes through Terraform, never manual. If manual changes are needed: update the .tf files to match, then plan to confirm no changes"
68
+ weight: 0.35
69
+ description: "Drift resolution"
70
+ - type: llm_judge
71
+ criteria: "Locking and remote state are practical — local state: terraform.tfstate in working directory. Problem: not shared, no locking, easy to lose. Remote state: store in S3, GCS, Azure Blob, Terraform Cloud. S3 backend with DynamoDB: S3 stores state file, DynamoDB provides locking (prevents concurrent modifications). Lock error: someone else is running terraform. Fix: wait for them to finish, or terraform force-unlock <ID> (dangerous, only if lock is stale). Never commit terraform.tfstate to git (contains secrets). Add to .gitignore"
72
+ weight: 0.30
73
+ description: "Locking and remote"
@@ -0,0 +1,58 @@
1
+ meta:
2
+ id: terraform-fmt-validate
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Use terraform fmt and validate — enforce consistent formatting, catch configuration errors before plan, and set up pre-commit hooks"
7
+ tags: [Terraform, fmt, validate, formatting, pre-commit, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ Your team's Terraform codebase is a formatting mess. Every developer
13
+ uses different indentation, alignment, and spacing. Code reviews are
14
+ full of style nitpicks instead of substance:
15
+
16
+ ```hcl
17
+ resource "aws_instance" "web" {
18
+ ami = "ami-0c55b159cbfafe1f0"
19
+ instance_type="t3.micro"
20
+ tags={
21
+ Name ="web-server"
22
+ Environment= "prod"
23
+ }
24
+ }
25
+
26
+ variable "region" {
27
+ type=string
28
+ default ="us-east-1"
29
+ }
30
+ ```
31
+
32
+ Additionally, a developer pushed this broken config that wasn't caught
33
+ until CI ran terraform plan (wasting 10 minutes):
34
+
35
+ ```hcl
36
+ resource "aws_s3_bucket" "data" {
37
+ bucket = var.bucket_name
38
+ acl = "private" # acl argument removed in AWS provider v4+
39
+ }
40
+ ```
41
+
42
+ Task: Explain terraform fmt (auto-formatting), terraform validate
43
+ (configuration checking), how to enforce both in CI/CD and pre-commit
44
+ hooks, and the difference between validate and plan for error catching.
45
+
46
+ assertions:
47
+ - type: llm_judge
48
+ criteria: "terraform fmt is explained — terraform fmt rewrites .tf files to canonical format (2-space indent, aligned equals signs, consistent spacing). terraform fmt -check: returns non-zero exit code if files need formatting (for CI). terraform fmt -recursive: formats all .tf files in subdirectories. terraform fmt -diff: shows the formatting changes. The example code would be auto-fixed to consistent 2-space indentation with aligned = signs. Best practice: run fmt before every commit"
49
+ weight: 0.35
50
+ description: "Formatting"
51
+ - type: llm_judge
52
+ criteria: "terraform validate is explained with its limitations — validate checks: syntax errors, invalid argument names, type mismatches, missing required arguments, invalid resource references. validate does NOT check: cloud API validity (wrong AMI ID), permissions, resource existence, provider-specific logic. The acl argument error: validate might not catch this because it depends on provider version schema. Plan catches more because it initializes providers and checks against their schemas. Workflow: fmt → validate → plan → apply. validate is fast (no API calls), plan is thorough (makes API calls)"
53
+ weight: 0.35
54
+ description: "Validation"
55
+ - type: llm_judge
56
+ criteria: "CI/CD and pre-commit integration are practical — pre-commit hook: use pre-commit framework with terraform_fmt and terraform_validate hooks. CI pipeline: (1) terraform fmt -check -recursive (fail if unformatted), (2) terraform init -backend=false (for validate only), (3) terraform validate, (4) terraform plan. This catches formatting issues before PR, validation errors without cloud access, and full errors with plan. Tools: pre-commit-terraform hooks, GitHub Actions, GitLab CI. TFLint for additional linting beyond validate (naming conventions, deprecated syntax, best practices)"
57
+ weight: 0.30
58
+ description: "CI integration"
@@ -0,0 +1,58 @@
1
+ meta:
2
+ id: count-vs-for-each
3
+ level: 2
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Choose between count and for_each — understand index-based vs key-based resources, migration pitfalls, and when to use each"
7
+ tags: [Terraform, count, for_each, meta-arguments, iteration, intermediate]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ Your infrastructure uses count for EC2 instances:
13
+
14
+ ```hcl
15
+ variable "instances" {
16
+ default = ["web-1", "web-2", "web-3"]
17
+ }
18
+
19
+ resource "aws_instance" "web" {
20
+ count = length(var.instances)
21
+ ami = "ami-0c55b159cbfafe1f0"
22
+ instance_type = "t3.micro"
23
+ tags = {
24
+ Name = var.instances[count.index]
25
+ }
26
+ }
27
+ ```
28
+
29
+ A developer removes "web-2" from the list. Terraform plan shows:
30
+
31
+ ```
32
+ # aws_instance.web[1] will be updated in-place (web-3 → web-2 tags)
33
+ # aws_instance.web[2] will be destroyed
34
+
35
+ Plan: 0 to add, 1 to change, 1 to destroy.
36
+ ```
37
+
38
+ The web-3 instance gets renamed to web-2, and the real web-3 instance
39
+ gets destroyed! This is the wrong behavior — you wanted to remove
40
+ web-2, not web-3.
41
+
42
+ Task: Explain count vs for_each, why count causes index shift problems,
43
+ how for_each solves this with stable keys, how to migrate from count
44
+ to for_each safely, and when to use each approach.
45
+
46
+ assertions:
47
+ - type: llm_judge
48
+ criteria: "Count problems are explained — count uses numeric indices: web[0], web[1], web[2]. Removing a middle element shifts all subsequent indices. Removing 'web-2' (index 1) makes 'web-3' become index 1 — Terraform sees index 1 changed and index 2 disappeared. Result: wrong instance modified, wrong instance destroyed. This is a fundamental limitation of count with lists that can have elements removed. Count is safe only when: (1) all elements are identical, (2) you only add/remove from the end, (3) the count is a simple number not derived from a list"
49
+ weight: 0.35
50
+ description: "Count problems"
51
+ - type: llm_judge
52
+ criteria: "for_each solution is explained — for_each uses stable map keys: web['web-1'], web['web-2'], web['web-3']. Removing 'web-2' only affects web['web-2'] — other instances untouched. Implementation: resource 'aws_instance' 'web' { for_each = toset(var.instances), tags = { Name = each.key } } or with a map: for_each = var.instances_map, using each.key and each.value. for_each accepts: set(string) or map. Not list — use toset() to convert. Access instances: aws_instance.web['web-1'].id"
53
+ weight: 0.35
54
+ description: "for_each solution"
55
+ - type: llm_judge
56
+ criteria: "Migration strategy is covered — migrating count to for_each changes resource addresses (web[0] → web['web-1']). Without state management, Terraform destroys and recreates all instances. Safe migration: (1) use moved blocks (Terraform 1.1+): moved { from = aws_instance.web[0], to = aws_instance.web['web-1'] }. (2) Or use terraform state mv: terraform state mv 'aws_instance.web[0]' 'aws_instance.web[\"web-1\"]'. Verify with plan — should show no changes. When to use count: simple numeric repetition (create N identical resources). When to use for_each: named resources, resources that may be individually added/removed"
57
+ weight: 0.30
58
+ description: "Migration"
@@ -0,0 +1,80 @@
1
+ meta:
2
+ id: dependency-management
3
+ level: 2
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Manage resource dependencies — debug dependency graphs, resolve circular references, use depends_on correctly, and understand the DAG"
7
+ tags: [Terraform, dependencies, DAG, circular, depends-on, intermediate]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ Your infrastructure has a complex dependency chain that's causing
13
+ issues during apply:
14
+
15
+ ```hcl
16
+ resource "aws_iam_role" "lambda" {
17
+ name = "lambda-role"
18
+ assume_role_policy = jsonencode({...})
19
+ }
20
+
21
+ resource "aws_iam_role_policy" "lambda" {
22
+ role = aws_iam_role.lambda.name
23
+ policy = jsonencode({
24
+ Statement = [{
25
+ Action = "s3:GetObject"
26
+ Resource = aws_s3_bucket.data.arn
27
+ }]
28
+ })
29
+ }
30
+
31
+ resource "aws_lambda_function" "processor" {
32
+ function_name = "processor"
33
+ role = aws_iam_role.lambda.arn
34
+ handler = "index.handler"
35
+ runtime = "nodejs18.x"
36
+ filename = "lambda.zip"
37
+ }
38
+
39
+ resource "aws_s3_bucket_notification" "trigger" {
40
+ bucket = aws_s3_bucket.data.id
41
+ lambda_function {
42
+ lambda_function_arn = aws_lambda_function.processor.arn
43
+ events = ["s3:ObjectCreated:*"]
44
+ }
45
+ }
46
+
47
+ resource "aws_lambda_permission" "s3" {
48
+ action = "lambda:InvokeFunction"
49
+ function_name = aws_lambda_function.processor.function_name
50
+ principal = "s3.amazonaws.com"
51
+ source_arn = aws_s3_bucket.data.arn
52
+ }
53
+ ```
54
+
55
+ Error:
56
+ ```
57
+ Error: error creating S3 Bucket Notification: Unable to validate
58
+ the following destination configurations: Lambda function ARN
59
+
60
+ The Lambda function doesn't have permission to be invoked by S3 yet
61
+ (the permission resource hasn't been created).
62
+ ```
63
+
64
+ Task: Explain the Terraform dependency graph (DAG), implicit vs
65
+ explicit dependencies, how to debug dependency ordering issues,
66
+ terraform graph command, and depends_on best practices.
67
+
68
+ assertions:
69
+ - type: llm_judge
70
+ criteria: "DAG and implicit dependencies are explained — Terraform builds a directed acyclic graph (DAG) from resource references. Implicit: when resource A uses resource B's attribute, A depends on B. The chain: role → role_policy (references role.name), role → lambda (references role.arn), bucket → notification (references bucket.id), lambda → notification (references lambda.arn). The error: s3_bucket_notification depends on lambda (implicit) but NOT on lambda_permission (no attribute reference). S3 notification tries to verify the Lambda ARN but permission doesn't exist yet"
71
+ weight: 0.35
72
+ description: "DAG explained"
73
+ - type: llm_judge
74
+ criteria: "The fix uses depends_on correctly — add depends_on = [aws_lambda_permission.s3] to the aws_s3_bucket_notification resource. This creates an explicit dependency where no implicit one exists. depends_on is needed because the notification resource doesn't reference any attribute of the permission resource, but the permission must exist for the notification to succeed. terraform graph: visualize dependencies with terraform graph | dot -Tsvg > graph.svg. Look for missing edges that represent real-world dependencies"
75
+ weight: 0.35
76
+ description: "Fix with depends_on"
77
+ - type: llm_judge
78
+ criteria: "depends_on best practices are covered — use depends_on sparingly: prefer implicit dependencies (reference attributes). depends_on forces sequential creation (reduces parallelism). Common scenarios needing depends_on: IAM permissions before resources that need them, DNS records before health checks, network resources before resources placed in them (when ID isn't directly referenced). Anti-pattern: depends_on everywhere 'just in case' — slows down apply. Use terraform graph to verify dependency order before adding depends_on. Module-level depends_on: depends_on on module blocks waits for entire module to complete"
79
+ weight: 0.30
80
+ description: "Best practices"