dojo.md 0.2.1 → 0.2.3

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 (152) hide show
  1. package/courses/GENERATION_LOG.md +20 -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/cross-team-review.yaml +45 -0
  75. package/courses/code-review-feedback-writing/scenarios/level-3/mentoring-through-review.yaml +46 -0
  76. package/courses/code-review-feedback-writing/scenarios/level-3/reviewing-unfamiliar-code.yaml +43 -0
  77. package/courses/terraform-infrastructure-setup/scenarios/level-1/first-debugging-shift.yaml +66 -0
  78. package/courses/terraform-infrastructure-setup/scenarios/level-1/hcl-syntax-errors.yaml +65 -0
  79. package/courses/terraform-infrastructure-setup/scenarios/level-1/plan-output-reading.yaml +71 -0
  80. package/courses/terraform-infrastructure-setup/scenarios/level-1/provider-configuration.yaml +62 -0
  81. package/courses/terraform-infrastructure-setup/scenarios/level-1/resource-creation-failures.yaml +54 -0
  82. package/courses/terraform-infrastructure-setup/scenarios/level-1/resource-references.yaml +70 -0
  83. package/courses/terraform-infrastructure-setup/scenarios/level-1/state-file-basics.yaml +73 -0
  84. package/courses/terraform-infrastructure-setup/scenarios/level-1/terraform-fmt-validate.yaml +58 -0
  85. package/courses/terraform-infrastructure-setup/scenarios/level-1/variable-and-output-errors.yaml +78 -0
  86. package/courses/terraform-infrastructure-setup/scenarios/level-2/count-vs-for-each.yaml +58 -0
  87. package/courses/terraform-infrastructure-setup/scenarios/level-2/dependency-management.yaml +80 -0
  88. package/courses/terraform-infrastructure-setup/scenarios/level-2/intermediate-debugging-shift.yaml +66 -0
  89. package/courses/terraform-infrastructure-setup/scenarios/level-2/lifecycle-rules.yaml +51 -0
  90. package/courses/terraform-infrastructure-setup/scenarios/level-2/locals-and-expressions.yaml +58 -0
  91. package/courses/terraform-infrastructure-setup/scenarios/level-2/module-structure.yaml +75 -0
  92. package/courses/terraform-infrastructure-setup/scenarios/level-2/provisioner-pitfalls.yaml +64 -0
  93. package/courses/terraform-infrastructure-setup/scenarios/level-2/remote-state-backend.yaml +55 -0
  94. package/courses/terraform-infrastructure-setup/scenarios/level-2/terraform-import.yaml +55 -0
  95. package/courses/terraform-infrastructure-setup/scenarios/level-2/workspace-management.yaml +51 -0
  96. package/courses/terraform-infrastructure-setup/scenarios/level-3/advanced-debugging-shift.yaml +63 -0
  97. package/courses/terraform-infrastructure-setup/scenarios/level-3/api-rate-limiting.yaml +50 -0
  98. package/courses/terraform-infrastructure-setup/scenarios/level-3/conditional-resources.yaml +66 -0
  99. package/courses/terraform-infrastructure-setup/scenarios/level-3/drift-detection.yaml +66 -0
  100. package/courses/terraform-infrastructure-setup/scenarios/level-3/dynamic-blocks.yaml +71 -0
  101. package/courses/terraform-infrastructure-setup/scenarios/level-3/large-scale-refactoring.yaml +59 -0
  102. package/courses/terraform-infrastructure-setup/scenarios/level-3/multi-provider-config.yaml +69 -0
  103. package/courses/terraform-infrastructure-setup/scenarios/level-3/state-surgery.yaml +57 -0
  104. package/courses/terraform-infrastructure-setup/scenarios/level-3/terraform-cloud-enterprise.yaml +59 -0
  105. package/courses/terraform-infrastructure-setup/scenarios/level-3/terraform-debugging.yaml +51 -0
  106. package/courses/terraform-infrastructure-setup/scenarios/level-4/blast-radius-management.yaml +51 -0
  107. package/courses/terraform-infrastructure-setup/scenarios/level-4/cicd-pipeline-design.yaml +50 -0
  108. package/courses/terraform-infrastructure-setup/scenarios/level-4/compliance-as-code.yaml +46 -0
  109. package/courses/terraform-infrastructure-setup/scenarios/level-4/cost-estimation-governance.yaml +42 -0
  110. package/courses/terraform-infrastructure-setup/scenarios/level-4/expert-debugging-shift.yaml +51 -0
  111. package/courses/terraform-infrastructure-setup/scenarios/level-4/iac-organization-strategy.yaml +45 -0
  112. package/courses/terraform-infrastructure-setup/scenarios/level-4/incident-response-iac.yaml +47 -0
  113. package/courses/terraform-infrastructure-setup/scenarios/level-4/infrastructure-testing.yaml +41 -0
  114. package/courses/terraform-infrastructure-setup/scenarios/level-4/module-registry-design.yaml +45 -0
  115. package/courses/terraform-infrastructure-setup/scenarios/level-4/multi-account-strategy.yaml +57 -0
  116. package/courses/terraform-infrastructure-setup/scenarios/level-5/board-infrastructure-investment.yaml +53 -0
  117. package/courses/terraform-infrastructure-setup/scenarios/level-5/disaster-recovery-iac.yaml +47 -0
  118. package/courses/terraform-infrastructure-setup/scenarios/level-5/enterprise-iac-transformation.yaml +48 -0
  119. package/courses/terraform-infrastructure-setup/scenarios/level-5/iac-technology-evolution.yaml +49 -0
  120. package/courses/terraform-infrastructure-setup/scenarios/level-5/ma-infrastructure-consolidation.yaml +54 -0
  121. package/courses/terraform-infrastructure-setup/scenarios/level-5/master-debugging-shift.yaml +53 -0
  122. package/courses/terraform-infrastructure-setup/scenarios/level-5/multi-cloud-strategy.yaml +49 -0
  123. package/courses/terraform-infrastructure-setup/scenarios/level-5/platform-engineering.yaml +47 -0
  124. package/courses/terraform-infrastructure-setup/scenarios/level-5/regulatory-compliance-automation.yaml +47 -0
  125. package/courses/terraform-infrastructure-setup/scenarios/level-5/terraform-vs-alternatives.yaml +46 -0
  126. package/dist/cli/commands/generate.d.ts.map +1 -1
  127. package/dist/cli/commands/generate.js +2 -1
  128. package/dist/cli/commands/generate.js.map +1 -1
  129. package/dist/cli/commands/train.d.ts.map +1 -1
  130. package/dist/cli/commands/train.js +6 -3
  131. package/dist/cli/commands/train.js.map +1 -1
  132. package/dist/cli/index.js +9 -6
  133. package/dist/cli/index.js.map +1 -1
  134. package/dist/cli/run-demo.js +3 -2
  135. package/dist/cli/run-demo.js.map +1 -1
  136. package/dist/engine/model-utils.d.ts +6 -0
  137. package/dist/engine/model-utils.d.ts.map +1 -1
  138. package/dist/engine/model-utils.js +28 -1
  139. package/dist/engine/model-utils.js.map +1 -1
  140. package/dist/engine/training.d.ts.map +1 -1
  141. package/dist/engine/training.js +4 -3
  142. package/dist/engine/training.js.map +1 -1
  143. package/dist/generator/course-generator.d.ts.map +1 -1
  144. package/dist/generator/course-generator.js +4 -3
  145. package/dist/generator/course-generator.js.map +1 -1
  146. package/dist/mcp/server.d.ts.map +1 -1
  147. package/dist/mcp/server.js +7 -3
  148. package/dist/mcp/server.js.map +1 -1
  149. package/dist/mcp/session-manager.d.ts.map +1 -1
  150. package/dist/mcp/session-manager.js +3 -2
  151. package/dist/mcp/session-manager.js.map +1 -1
  152. package/package.json +3 -2
@@ -0,0 +1,65 @@
1
+ meta:
2
+ id: hcl-syntax-errors
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Fix HCL syntax errors — diagnose missing braces, incorrect attribute assignments, string interpolation issues, and block structure problems"
7
+ tags: [Terraform, HCL, syntax, validation, formatting, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ You run `terraform validate` and get multiple errors:
13
+
14
+ ```
15
+ Error: Missing closing brace
16
+
17
+ on main.tf line 12:
18
+ 12: tags = {
19
+ 13: Name = "web-server"
20
+ 14:
21
+
22
+ Error: Unsupported argument
23
+
24
+ on main.tf line 8, in resource "aws_instance" "web":
25
+ 8: ami := "ami-0c55b159cbfafe1f0"
26
+
27
+ Error: Invalid reference
28
+
29
+ on main.tf line 15, in resource "aws_instance" "web":
30
+ 15: subnet_id = "${var.subnet_id}"
31
+ ```
32
+
33
+ Your main.tf:
34
+
35
+ ```hcl
36
+ resource "aws_instance" "web" {
37
+ ami := "ami-0c55b159cbfafe1f0"
38
+ instance_type = var.instance_type
39
+
40
+ tags = {
41
+ Name = "web-server"
42
+
43
+ vpc_security_group_ids = [aws_security_group.web.id]
44
+ }
45
+ ```
46
+
47
+ Task: Explain HCL syntax fundamentals, common syntax errors and
48
+ how to fix them, the difference between = and := (Terraform only
49
+ uses =), string interpolation rules, terraform fmt for auto-formatting,
50
+ terraform validate for catching errors before plan, and block structure
51
+ (resource, data, variable, output, locals).
52
+
53
+ assertions:
54
+ - type: llm_judge
55
+ criteria: "HCL syntax fundamentals are explained — blocks: resource, data, variable, output, locals, terraform, provider. Attribute assignment uses = (not :=, that's Go syntax). String interpolation: use ${} inside quoted strings, but for simple references just use var.name directly (no interpolation needed since Terraform 0.12). Heredoc syntax: <<-EOT for multi-line strings. Comments: # for single line, /* */ for multi-line. Lists: [], maps: {}. The specific errors: (1) := should be =, (2) missing closing brace for tags block, (3) bare ${var.subnet_id} should be just var.subnet_id (interpolation-only expressions are deprecated)"
56
+ weight: 0.35
57
+ description: "HCL fundamentals"
58
+ - type: llm_judge
59
+ criteria: "terraform fmt and validate workflow is covered — terraform fmt: auto-formats HCL files to canonical style (consistent indentation, alignment). Run before committing. terraform fmt -check in CI to enforce formatting. terraform validate: checks configuration for internal consistency (syntax, attribute names, required arguments). Does NOT check against cloud APIs. Workflow order: fmt → validate → plan → apply. validate catches: missing required arguments, unknown attributes, type mismatches, invalid references"
60
+ weight: 0.35
61
+ description: "Formatting and validation"
62
+ - type: llm_judge
63
+ criteria: "Block structure is explained — resource 'type' 'name' {}: creates infrastructure. data 'type' 'name' {}: reads existing infrastructure. variable 'name' {}: input parameters (type, default, description, validation). output 'name' {}: export values. locals {}: computed local values (like constants). terraform {}: settings (required_version, required_providers, backend). provider 'name' {}: provider configuration. Each block type has specific allowed arguments. Meta-arguments available on resources: depends_on, count, for_each, provider, lifecycle"
64
+ weight: 0.30
65
+ description: "Block structure"
@@ -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,62 @@
1
+ meta:
2
+ id: provider-configuration
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Configure Terraform providers — set up AWS credentials, handle authentication errors, manage provider aliases for multi-region deployments"
7
+ tags: [Terraform, providers, AWS, authentication, credentials, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ You run `terraform plan` and get this error:
13
+
14
+ ```
15
+ Error: No valid credential sources found
16
+
17
+ with provider["registry.terraform.io/hashicorp/aws"],
18
+ on main.tf line 5, in provider "aws":
19
+ 5: provider "aws" {
20
+
21
+ Please see https://registry.terraform.io/providers/hashicorp/aws
22
+ for more information about providing credentials.
23
+ ```
24
+
25
+ Your configuration:
26
+
27
+ ```hcl
28
+ provider "aws" {
29
+ region = "us-east-1"
30
+ }
31
+
32
+ resource "aws_s3_bucket" "data" {
33
+ bucket = "my-data-bucket-12345"
34
+ }
35
+
36
+ resource "aws_s3_bucket" "logs" {
37
+ provider = aws.west
38
+ bucket = "my-logs-bucket-12345"
39
+ }
40
+ ```
41
+
42
+ You have AWS CLI installed with a profile named "dev" but haven't
43
+ configured any credentials for Terraform.
44
+
45
+ Task: Explain Terraform provider configuration, AWS credential
46
+ chain (how Terraform finds credentials), provider aliases for
47
+ multi-region, common authentication errors and fixes, and best
48
+ practices for credential management (never hardcode keys).
49
+
50
+ assertions:
51
+ - type: llm_judge
52
+ criteria: "AWS credential chain is explained — Terraform AWS provider checks credentials in order: (1) provider block (access_key/secret_key — NEVER do this), (2) environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN), (3) shared credentials file (~/.aws/credentials), (4) shared config file (~/.aws/config with profile), (5) EC2 instance metadata / ECS task role / Lambda execution role. Fix: export AWS_PROFILE=dev or set profile in provider block. For CI/CD: use environment variables or OIDC federation (GitHub Actions → AWS IAM role)"
53
+ weight: 0.35
54
+ description: "Credential chain"
55
+ - type: llm_judge
56
+ criteria: "Provider aliases are explained — to use multiple regions, define provider aliases: provider 'aws' { region = 'us-east-1' } and provider 'aws' { alias = 'west', region = 'us-west-2' }. Reference alias: provider = aws.west in resource block. Without the alias provider block defined, the aws.west reference will fail. Default provider (no alias) is used when provider isn't specified. Each alias can have different credentials, regions, or assume_role configurations"
57
+ weight: 0.35
58
+ description: "Provider aliases"
59
+ - type: llm_judge
60
+ criteria: "Security best practices are covered — NEVER hardcode credentials in .tf files (they end up in version control and state files). Use: environment variables, AWS profiles, IAM roles (instance profiles, task roles), or OIDC federation. For assume_role: provider block supports assume_role {} for cross-account access. State files contain provider config — ensure state is encrypted and access-controlled. Use terraform plan output to verify no credentials are exposed. Add *.tfvars with secrets to .gitignore"
61
+ weight: 0.30
62
+ description: "Security 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,78 @@
1
+ meta:
2
+ id: variable-and-output-errors
3
+ level: 1
4
+ course: terraform-infrastructure-setup
5
+ type: output
6
+ description: "Debug variable and output errors — fix type mismatches, missing required variables, default values, and output reference issues"
7
+ tags: [Terraform, variables, outputs, types, validation, beginner]
8
+
9
+ state: {}
10
+
11
+ trigger: |
12
+ You run `terraform plan` and hit these errors:
13
+
14
+ ```
15
+ Error: No value for required variable
16
+
17
+ on variables.tf line 1:
18
+ 1: variable "environment" {
19
+
20
+ The root module input variable "environment" is not set, and has
21
+ no default value.
22
+
23
+ Error: Invalid value for variable
24
+
25
+ on variables.tf line 7:
26
+ 7: variable "instance_count" {
27
+
28
+ This variable does not accept the value "three". Expected type number.
29
+
30
+ Error: Unsupported attribute
31
+
32
+ on outputs.tf line 3:
33
+ 3: value = aws_instance.web.public_dns
34
+ ```
35
+
36
+ Your files:
37
+
38
+ variables.tf:
39
+ ```hcl
40
+ variable "environment" {
41
+ type = string
42
+ description = "Deployment environment"
43
+ }
44
+
45
+ variable "instance_count" {
46
+ type = number
47
+ default = 1
48
+ }
49
+
50
+ variable "allowed_cidrs" {
51
+ type = list(string)
52
+ default = ["0.0.0.0/0"]
53
+ }
54
+ ```
55
+
56
+ terraform.tfvars:
57
+ ```hcl
58
+ instance_count = "three"
59
+ ```
60
+
61
+ Task: Explain Terraform variables (types, defaults, validation),
62
+ how to pass values (tfvars, CLI, env vars, auto.tfvars), output
63
+ values and their uses, type system (string, number, bool, list,
64
+ map, object, tuple), and common variable/output errors.
65
+
66
+ assertions:
67
+ - type: llm_judge
68
+ criteria: "Variable system is explained — types: string, number, bool (primitives), list(type), set(type), map(type), object({key=type}), tuple([types]) (complex). Required vs optional: variables without default are required. Validation blocks: variable 'env' { validation { condition = contains(['dev','prod'], var.env), error_message = '...' } }. Sensitive = true: hides value in plan output. Nullable = false: disallows null values. The errors: (1) environment has no default and no value provided, (2) instance_count expects number but got string 'three', (3) public_dns might not exist if count = 0 or resource uses for_each"
69
+ weight: 0.35
70
+ description: "Variable system"
71
+ - type: llm_judge
72
+ criteria: "Value passing methods are covered in precedence order — (1) -var flag on CLI: terraform plan -var='environment=prod'. (2) -var-file flag: terraform plan -var-file=prod.tfvars. (3) terraform.tfvars or terraform.tfvars.json (auto-loaded). (4) *.auto.tfvars files (auto-loaded, alphabetical order). (5) TF_VAR_name environment variables: TF_VAR_environment=prod. Later sources override earlier ones. Best practice: use terraform.tfvars for defaults, environment-specific .tfvars files for overrides, never commit secrets in tfvars"
73
+ weight: 0.35
74
+ description: "Value passing"
75
+ - type: llm_judge
76
+ criteria: "Outputs are explained — output blocks export values after apply. Uses: display information, pass data between modules (module.vpc.vpc_id), feed into other tools. Attributes: value (required), description, sensitive, depends_on. terraform output command to retrieve values. terraform output -json for machine-readable format. Common errors: referencing attribute that doesn't exist on resource type, referencing resource with count/for_each without index (aws_instance.web[0].public_dns or aws_instance.web[*].public_dns)"
77
+ weight: 0.30
78
+ description: "Outputs"
@@ -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"