Chapter 3: AI for Infrastructure as Code – Structure Over Speed¶
Why Metadata-First Design Makes AI-Generated IaC Manageable
Part of: The DevOps Engineer's Guide to Effective AI Usage
Table of Contents¶
- Executive Summary – The Core Problem
- Part 1: The AI IaC Paradox – Fast Generation, Unmanageable Output
- Part 2: The Solution – Structure Before Generation
- Part 3: InfraCtl – A Working Example of Structured AI IaC
- Part 4: AI Roles Within the Structure
- Part 5: VSCode Integration for Structured Workflows
- Part 6: Validation – Keeping AI Within Bounds
- Part 7: Iteration Points – Your Feedback Needed
- Appendix: Structured Prompt Templates
1. Executive Summary – The Core Problem ¶
💡 5-Minute Win: Before reading further, try this: 1. Open any Terraform file AI recently generated for you 2. Look for hardcoded values, missing variable descriptions, or no
depends_on3. Move one hardcoded value to a variable with a descriptionYou've just applied metadata-first thinking to AI-generated IaC.
Without Structure vs. With Structure¶
| Without Structure | With Structure |
|---|---|
AI generates inline .tfvars → environment drift |
Metadata-first design → consistent environments |
| Hardcoded values across modules → brittle code | Variables with descriptions → maintainable IaC |
No depends_on declarations → race conditions |
Explicit dependencies → reliable execution order |
| No audit trail → can't trace AI decisions | Schema-validated metadata → accountable changes |
| AI-generated code diverges per-engineer | Shared module contracts → team-level consistency |
The Hard Truth About AI and IaC¶
┌─────────────────────────────────────────────────────────────┐
│ THE AI IaC PARADOX │
├─────────────────────────────────────────────────────────────┤
│ │
│ [Without Structure] │
│ • AI generates Terraform 5-10x faster ✓ │
│ • AI generates working code ✓ │
│ • BUT: Code becomes unmanageable over time ✗ │
│ • BUT: Environment drift accumulates ✗ │
│ • BUT: Security gaps introduced ✗ │
│ • BUT: No audit trail of changes ✗ │
│ │
│ [With Structure] │
│ • AI generates Terraform 5-10x faster ✓ │
│ • AI generates working code ✓ │
│ • AND: Code remains manageable ✓ │
│ • AND: Environment separation enforced ✓ │
│ • AND: Security gaps caught ✓ │
│ • AND: Clear audit trail ✓ │
│ │
│ THE DIFFERENCE: │
│ Structure (metadata-first design) │
│ │
└─────────────────────────────────────────────────────────────┘
Why This Chapter Exists¶
Chapter 1 taught you: AI needs symbolic constraints + data-driven patterns
Chapter 2 taught you: How to integrate AI into VSCode effectively
Chapter 3 teaches you: How to apply Chapters 1-2 to IaC WITH STRUCTURE that prevents AI from creating unmanageable messes
The Core Thesis¶
"AI can generate all the code you need for IaC. But without clear structure, that code becomes unmanageable. This chapter provides the structure (metadata-driven design) that allows AI to be used effectively without sacrificing maintainability."
What You'll Learn¶
| Section | What You'll Gain | Why It Matters |
|---|---|---|
| Part 1: The Paradox | Understand WHY unstructured AI IaC fails | Avoid costly mistakes |
| Part 2: The Solution | Learn metadata-first design principles | Foundation for everything |
| Part 3: InfraCtl | See a working implementation | Practical example |
| Part 4: AI Roles | Know WHERE AI fits in the structure | Effective augmentation |
| Part 5: VSCode | Integrate AI into your workflow | Daily productivity |
| Part 6: Validation | Keep AI within bounds | Safety and compliance |
2. Part 1: The AI IaC Paradox – Fast Generation, Unmanageable Output ¶
2.1 The Promise: AI Generates IaC Fast¶
# Typical AI IaC Workflow (Without Structure)
Engineer: "Generate Terraform for an S3 bucket with encryption"
AI: [Generates 50 lines of Terraform in 10 seconds]
Engineer: "Great! Now generate one for RDS"
AI: [Generates 100 lines of Terraform in 10 seconds]
Engineer: "Now add staging environment"
AI: [Copies and modifies, adds inline .tfvars]
Engineer: "Now add production with different values"
AI: [Copies again, more inline .tfvars]
6 Months Later:
- 50+ Terraform files
- Inline .tfvars scattered everywhere
- No clear separation of logic vs. data
- Can't tell what changed between environments
- Security review is a nightmare
- New engineers can't understand the structure
Result: AI saved time initially, but created technical debt that compounds.
2.2 The Problem: Why Unstructured AI IaC Fails¶
| Problem | Cause | Consequence |
|---|---|---|
| Environment drift | AI generates inline .tfvars per environment | Can't track what differs between dev/staging/prod |
| Security gaps | AI doesn't know your security baseline | Hardcoded secrets, missing encryption, open access |
| No audit trail | AI changes scattered across files | Can't audit who changed what and why |
| Breaking changes | AI modifies module interfaces | Downstream modules break unexpectedly |
| Unmanageable scale | No separation of logic vs. data | 100+ files become impossible to navigate |
| Compliance failures | AI doesn't enforce compliance rules | Audit failures, regulatory issues |
2.3 The Root Cause: AI Needs Symbolic Constraints¶
From Chapter 1:
"AI pattern-matches; it doesn't reason. Your prompts must provide the logical structure."
Applied to IaC:
┌─────────────────────────────────────────────────────────────┐
│ WHY AI FAILS AT IaC WITHOUT STRUCTURE │
├─────────────────────────────────────────────────────────────┤
│ │
│ [AI's Nature] │
│ • Excels at: Pattern completion, code generation │
│ • Struggles with: Long-term architecture, consistency │
│ • Doesn't know: Your security baseline, compliance needs │
│ │
│ [What AI Needs] │
│ • SYMBOLIC CONSTRAINTS: Rules it cannot violate │
│ • CLEAR BOUNDARIES: Where logic ends, data begins │
│ • VALIDATION: Automated checks before changes apply │
│ • AUDIT TRAIL: Clear record of what changed and why │
│ │
│ [Without These] │
│ • AI generates code that works today, breaks tomorrow │
│ • AI introduces drift between environments │
│ • AI creates security gaps you don't discover until later │
│ │
└─────────────────────────────────────────────────────────────┘
2.4 The Solution Preview: Structure Before Generation¶
┌─────────────────────────────────────────────────────────────┐
│ STRUCTURED AI IaC WORKFLOW │
├─────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Define Structure (Human) │
│ • Metadata schema (what variables, types, constraints) │
│ • Module contracts (inputs, outputs, dependencies) │
│ • Environment separation (where values live) │
│ │
│ Step 2: AI Generates Within Structure (AI) │
│ • AI fills in metadata (NOT inline .tfvars) │
│ • AI generates module code (following contracts) │
│ • AI cannot violate structure (enforced by validation) │
│ │
│ Step 3: Validate Before Apply (Automated) │
│ • Automated checks (infractl validate) │
│ • Security scanning (tfsec, checkov) │
│ • Human review (critical changes) │
│ │
│ Step 4: Apply with Audit Trail (Automated) │
│ • Clear record of metadata changes │
│ • Generated code is deterministic │
│ • Rollback is straightforward │
│ │
│ Result: AI speed + Human oversight + Manageable code │
│ │
└─────────────────────────────────────────────────────────────┘
3. Part 2: The Solution – Structure Before Generation ¶
3.1 The Core Principle: Metadata-First Design¶
┌─────────────────────────────────────────────────────────────┐
│ METADATA-FIRST DESIGN FOR AI IaC │
├─────────────────────────────────────────────────────────────┤
│ │
│ [Traditional IaC + AI] │
│ • AI generates: main.tf, variables.tf, outputs.tf │
│ • AI generates: .tfvars per environment │
│ • Problem: Logic and data mixed together │
│ • Problem: No clear contract between modules │
│ • Problem: AI can introduce drift │
│ │
│ [Metadata-First IaC + AI] │
│ • AI generates: meta/live/{module}.json (contract) │
│ • AI generates: meta/env/{env}/live-modules.json (data) │
│ • AI generates: live/{module}/main.tf (reusable logic) │
│ • AI CANNOT: Mix logic and data │
│ • AI CANNOT: Introduce environment drift │
│ • AI CANNOT: Violate module contracts │
│ │
│ Key Insight: │
│ Metadata = SYMBOLIC CONSTRAINTS for AI (Chapter 1) │
│ Module code = DATA-DRIVEN GENERATION (Chapter 1) │
│ │
└─────────────────────────────────────────────────────────────┘
3.2 The Three-Layer Architecture¶
┌─────────────────────────────────────────────────────────────┐
│ THREE-LAYER IaC ARCHITECTURE │
├─────────────────────────────────────────────────────────────┤
│ │
│ [Layer 1: Metadata (meta/)] │
│ • WHAT: Module contracts, environment values │
│ • WHO: Human defines structure, AI fills values │
│ • AI ROLE: Validate structure, suggest optimizations │
│ • RULE: AI CANNOT violate metadata schema │
│ │
│ [Layer 2: Logic (live/)] │
│ • WHAT: Reusable module code (Terraform/Pulumi) │
│ • WHO: AI generates following contracts │
│ • AI ROLE: Generate code within contract bounds │
│ • RULE: NO environment-specific values allowed │
│ │
│ [Layer 3: Generated (build/)] │
│ • WHAT: Deterministic output from metadata + logic │
│ • WHO: Automated generation (infractl generate) │
│ • AI ROLE: Review for drift, compare against expected │
│ • RULE: NEVER commit to git, NEVER edit directly │
│ │
└─────────────────────────────────────────────────────────────┘
3.3 The Separation of Concerns¶
┌─────────────────────────────────────────────────────────────┐
│ SEPARATION OF CONCERNS IN METADATA-FIRST IaC │
├─────────────────────────────────────────────────────────────┤
│ │
│ [Logic (live/)] [Data (meta/env/)] │
│ • Reusable across envs • Environment-specific │
│ • Never changes per env • Changes per environment │
│ • AI can generate • AI can suggest │
│ • Validated by contract • Validated by schema │
│ │
│ Example: VPC Module │
│ │
│ live/vpc/main.tf: meta/env/prod/live-modules.json:│
│ ─────────────────── ─────────────────────────────── │
│ module "this" { { │
│ source = ".../aws-vpc" "modules": { │
│ vpc_id = var.vpc_id "vpc": { │
│ tags = var.tags "enabled": true, │
│ } "inputs": { │
│ "vpc_id": "vpc-prod-123", │
│ "tags": { │
│ "Environment": "production" │
│ } │
│ } │
│ } │
│ } │
│ │
│ KEY: Logic never knows about "production" │
│ Data never modifies logic │
│ AI works within this separation │
│ │
└─────────────────────────────────────────────────────────────┘
3.4 The AI Boundaries¶
┌─────────────────────────────────────────────────────────────┐
│ WHERE AI CAN AND CANNOT GO │
├─────────────────────────────────────────────────────────────┤
│ │
│ [AI CAN] │
│ ✓ Generate module contracts (meta/live/*.json) │
│ ✓ Suggest environment values (meta/env/*/live-modules.json)│
│ ✓ Generate reusable module code (live/*/) │
│ ✓ Validate metadata structure │
│ ✓ Detect inconsistencies │
│ ✓ Generate documentation │
│ ✓ Generate changelogs │
│ │
│ [AI CANNOT] │
│ ✗ Generate inline .tfvars (breaks metadata-first) │
│ ✗ Modify live/ with environment values (breaks reusability)│
│ ✗ Edit build/ directly (causes drift) │
│ ✗ Commit generated code to git (bloats repo) │
│ ✗ Hardcode secrets (security violation) │
│ ✗ Skip validation (compliance violation) │
│ │
│ [ENFORCEMENT] │
│ • Automated validation (infractl validate) │
│ • Pre-commit hooks (block violations) │
│ • CI/CD checks (fail on violations) │
│ • Human review (critical changes) │
│ │
└─────────────────────────────────────────────────────────────┘
3.5 The Workflow: Structure Enables Speed¶
┌─────────────────────────────────────────────────────────────┐
│ STRUCTURED AI IaC WORKFLOW │
├─────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Define/Update Metadata │
│ Human: Define module contract in meta/live/{module}.json │
│ AI: Validate structure, suggest improvements │
│ Output: Validated metadata contract │
│ │
│ Step 2: Configure Environment │
│ Human: Define environment values in meta/env/{env}/ │
│ AI: Suggest values based on patterns, validate schema │
│ Output: Environment-specific configuration │
│ │
│ Step 3: Generate (Automated) │
│ Command: infractl generate {env} │
│ AI: Review generated output for drift │
│ Output: Deterministic Terraform in build/ │
│ │
│ Step 4: Plan (Automated) │
│ Command: infractl plan {env} │
│ AI: Summarize changes in human-readable format │
│ Output: Change summary with risk assessment │
│ │
│ Step 5: Human Review (CRITICAL) │
│ Human: Review AI summary, approve/reject │
│ AI: Document decision rationale │
│ Output: Approved change ready for apply │
│ │
│ Step 6: Apply (Automated) │
│ Command: infractl apply {env} │
│ AI: Monitor progress, capture errors │
│ Output: Deployed infrastructure │
│ │
│ Step 7: Validate & Document │
│ Command: infractl test {env} │
│ AI: Generate changelog, update docs │
│ Output: Validated deployment + documentation │
│ │
│ Result: AI speed WITH structure and oversight │
│ │
└─────────────────────────────────────────────────────────────┘
4. Part 3: InfraCtl – A Working Example of Structured AI IaC ¶
4.1 Why InfraCtl Exists¶
InfraCtl is a concrete implementation of the metadata-first design principles in this chapter. It provides:
- ✅ Structured metadata – Clear separation of logic and data
- ✅ AI boundaries – Automated enforcement of what AI can/cannot do
- ✅ Validation – Automated checks before changes apply
- ✅ Audit trail – Clear record of metadata changes
- ✅ AI augmentation – AI works WITHIN the structure, not around it
4.2 InfraCtl Directory Structure¶
infractl/
├── meta/ # METADATA LAYER (AI can modify)
│ ├── live/ # Module contracts
│ │ ├── vpc.json
│ │ ├── rds.json
│ │ └── eks.json
│ └── env/ # Environment values
│ ├── dev/
│ │ └── live-modules.json
│ ├── staging/
│ │ └── live-modules.json
│ └── prod/
│ └── live-modules.json
│
├── live/ # LOGIC LAYER (AI can generate)
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── rds/
│ └── eks/
│
├── build/ # GENERATED LAYER (AI can review)
│ ├── dev/ # NEVER commit to git
│ ├── staging/
│ └── prod/
│
├── tests/ # TEST LAYER (AI can generate)
│ ├── vpc_test.go
│ └── rds_test.go
│
└── infractl # CLI TOOL
├── generate
├── plan
├── apply
├── test
└── validate
4.3 The Metadata Contract¶
File: meta/live/vpc.json
{
"source": "../../terraform/modules/aws-vpc",
"variables": {
"vpc_id": {
"type": "string",
"required": true,
"description": "VPC ID for the module"
},
"tags": {
"type": "map(string)",
"required": false,
"default": {},
"description": "Tags to apply to resources"
}
},
"depends_on": ["network"],
"files": ["main.tf", "variables.tf", "outputs.tf"],
"security": {
"encryption_required": true,
"audit_logging": true,
"public_access": false
}
}
AI's Role: Validate this structure, suggest improvements, NEVER violate it.
4.4 The Environment Configuration¶
File: meta/env/prod/live-modules.json
{
"modules": {
"vpc": {
"enabled": true,
"inputs": {
"vpc_id": "vpc-prod-12345",
"tags": {
"Environment": "production",
"Team": "platform",
"Compliance": "HIPAA"
}
}
},
"rds": {
"enabled": true,
"inputs": {
"instance_class": "db.r5.2xlarge",
"multi_az": true,
"backup_retention": 30
}
}
}
}
AI's Role: Suggest values based on patterns, validate against schema, NEVER put these in live/.
4.5 The Reusable Logic¶
File: live/vpc/main.tf
# NO environment-specific values here
# AI can generate this, following the contract
variable "vpc_id" {
description = "VPC ID for the module"
type = string
}
variable "tags" {
description = "Tags to apply to resources"
type = map(string)
default = {}
}
module "this" {
source = "../../terraform/modules/aws-vpc"
vpc_id = var.vpc_id
tags = var.tags
# Security constraints enforced by contract
encryption_enabled = true
audit_logging = true
public_access = false
}
output "subnet_ids" {
description = "List of created subnet IDs"
value = module.this.subnet_ids
}
AI's Role: Generate this following the contract, NEVER add environment-specific values.
4.6 The Generated Output¶
File: build/prod/main.tf (NEVER committed to git)
# Generated by: infractl generate prod
# DO NOT EDIT - Changes will be overwritten
# This is deterministic output from:
# - meta/live/vpc.json (contract)
# - meta/env/prod/live-modules.json (values)
# - live/vpc/main.tf (logic)
module "vpc" {
source = "../../terraform/modules/aws-vpc"
vpc_id = "vpc-prod-12345"
tags = {
Environment = "production"
Team = "platform"
Compliance = "HIPAA"
}
encryption_enabled = true
audit_logging = true
public_access = false
}
AI's Role: Review for drift, compare against expected, NEVER edit directly.
5. Part 4: AI Roles Within the Structure ¶
5.1 AI Role 1: Metadata Validation¶
## Task: Validate Metadata Structure
### Prompt Template:
"Validate InfraCtl metadata for {environment}.
SYMBOLIC CONSTRAINTS (InfraCtl Rules):
1. All modules MUST have: source, variables, depends_on
2. All variables MUST have: type, description
3. No inline .tfvars allowed
4. Environment values ONLY in meta/env/
AI ACTION:
1. Check meta/live/*.json against schema
2. Check meta/env/*/live-modules.json for violations
3. Flag any inline .tfvars (PROHIBITED)
4. Run: infractl validate {env}
OUTPUT:
- List validation errors with severity
- Suggest specific fixes
- Regenerate metadata with fixes"
Why This Matters: AI enforces the structure that keeps IaC manageable.
5.2 AI Role 2: Module Generation (Within Bounds)¶
## Task: Generate Module Within Contract
### Prompt Template:
"Generate InfraCtl module for {resource_type}.
SYMBOLIC CONSTRAINTS:
1. Create meta/live/{module}.json with contract
2. Create live/{module}/main.tf following contract
3. NEVER include environment-specific values in live/
4. MUST have: source, variables, depends_on, files
AI ACTION:
1. Generate metadata contract first
2. Generate module code following contract
3. Validate with infractl validate
4. Document module purpose
OUTPUT:
- meta/live/{module}.json
- live/{module}/main.tf
- live/{module}/variables.tf
- live/{module}/outputs.tf
- README.md
VALIDATION:
infractl validate {env}
infractl generate {env} --dry-run"
Why This Matters: AI generates code, but within the structure that prevents drift.
5.3 AI Role 3: Environment Configuration (Data, Not Logic)¶
## Task: Configure Environment Values
### Prompt Template:
"Configure InfraCtl metadata for {environment}.
SYMBOLIC CONSTRAINTS:
1. ONLY modify meta/env/{env}/live-modules.json
2. NEVER modify live/ modules
3. NEVER create inline .tfvars
4. MUST validate after changes
AI ACTION:
1. Review existing environment structure
2. Suggest values based on patterns (dev vs. prod)
3. Validate against module contracts
4. Run: infractl validate {env}
OUTPUT:
- meta/env/{env}/live-modules.json updates
- Validation results
- Rollback plan if needed
VALIDATION:
infractl validate {env}
infractl generate {env} --dry-run
infractl plan {env}"
Why This Matters: AI helps configure environments without breaking reusability.
5.4 AI Role 4: Drift Detection¶
## Task: Detect Drift Between Generated and Expected
### Prompt Template:
"Detect drift in InfraCtl generated output.
SYMBOLIC CONSTRAINTS:
1. Compare build/ against expected from metadata
2. Flag any manual edits to build/ (PROHIBITED)
3. Check for environment drift (dev vs. staging vs. prod)
4. Validate security constraints enforced
AI ACTION:
1. Run: infractl generate {env} --dry-run
2. Compare generated vs. committed (should be none)
3. Compare environments for unexpected differences
4. Flag security constraint violations
OUTPUT:
- Drift report with severity
- Root cause analysis
- Remediation steps
VALIDATION:
infractl validate {env}
infractl generate {env}"
Why This Matters: AI catches drift before it becomes unmanageable.
5.5 AI Role 5: Changelog Generation¶
## Task: Generate Changelog from Metadata Diffs
### Prompt Template:
"Generate changelog for InfraCtl metadata changes.
SYMBOLIC CONSTRAINTS:
1. Compare metadata diffs between commits
2. Format: ## Module: <name> - Added/Changed/Removed
3. Flag breaking changes
4. Note compliance impacts
AI ACTION:
1. Analyze git diff for meta/ changes
2. Summarize module changes
3. Identify dependency updates
4. Flag breaking changes
OUTPUT:
- Human-readable changelog
- Breaking change warnings
- Compliance impact summary
- Rollback instructions
VALIDATION:
Review changelog against actual changes"
Why This Matters: AI provides audit trail for compliance and team communication.
5.6 AI Role 6: Security & Compliance Review¶
## Task: Security and Compliance Review
### Prompt Template:
"Review InfraCtl metadata for security and compliance.
SYMBOLIC CONSTRAINTS:
1. Check for hardcoded secrets (NEVER allow)
2. Check for encryption requirements (ALWAYS enforce)
3. Check for audit logging (REQUIRED for compliance)
4. Check for least-privilege (ENFORCE)
COMPLIANCE FRAMEWORKS:
- HIPAA: PHI handling, audit logs, encryption
- SOC2: Access controls, change management
- PCI-DSS: Network segmentation, encryption
AI ACTION:
1. Scan metadata for security violations
2. Check compliance requirements per environment
3. Flag issues with severity
4. Suggest remediation
OUTPUT:
- Security issues with severity
- Compliance gaps with framework reference
- Remediation steps
- Verification commands
VALIDATION:
tfsec live/{module}/
checkov -d live/{module}/
infractl validate {env}"
Why This Matters: AI enforces security boundaries that humans might miss.
6. Part 5: VSCode Integration for Structured Workflows ¶
6.1 Continue.dev Configuration for InfraCtl¶
File: ~/.continue/config.json
{
"models": [
{
"title": "🔵 Qwen-2.5-Coder (Module Generation)",
"provider": "openai",
"model": "qwen-2.5-coder",
"apiKey": "${QWEN_API_KEY}",
"apiBase": "https://dashscope.aliyuncs.com/compatible-mode/v1"
},
{
"title": "🟢 DeepSeek-V3 (Metadata Reasoning)",
"provider": "openai",
"model": "deepseek-chat",
"apiKey": "${DEEPSEEK_API_KEY}",
"apiBase": "https://api.deepseek.com/v1",
"default": true
},
{
"title": "🟠 Claude-3.5-Sonnet (Security Review)",
"provider": "anthropic",
"model": "claude-3-5-sonnet-20241022",
"apiKey": "${ANTHROPIC_API_KEY}"
},
{
"title": "🔴 Ollama (Sensitive Metadata)",
"provider": "ollama",
"model": "codellama",
"apiBase": "http://localhost:11434"
}
],
"customCommands": [
{
"name": "infractl-module",
"prompt": "Generate new InfraCtl module for {{{ input }}}. CRITICAL: 1) Create meta/live/{module}.json with contract FIRST, 2) Create live/{module}/ following contract, 3) NEVER include environment-specific values in live/, 4) Validate with infractl validate. Follow metadata-first design from Chapter 3.",
"description": "Generate InfraCtl module with metadata contract"
},
{
"name": "infractl-env",
"prompt": "Configure InfraCtl environment for {{{ input }}}. CRITICAL: 1) ONLY modify meta/env/{env}/live-modules.json, 2) NEVER modify live/ modules, 3) NEVER create inline .tfvars, 4) Validate after changes. Follow separation of concerns from Chapter 3.",
"description": "Configure InfraCtl environment metadata"
},
{
"name": "infractl-validate",
"prompt": "Validate InfraCtl metadata for {{{ input }}}. Check: 1) Module contract structure, 2) Environment inputs, 3) Dependencies, 4) Security/compliance. Run infractl validate and report ALL issues. This enforces the structure that keeps IaC manageable.",
"description": "Validate InfraCtl metadata structure"
},
{
"name": "infractl-drift",
"prompt": "Detect drift in InfraCtl generated output. Compare build/ against expected from metadata. Flag ANY manual edits to build/ (PROHIBITED). Check for environment drift. This catches issues before they become unmanageable.",
"description": "Detect drift in InfraCtl output"
},
{
"name": "infractl-security",
"prompt": "Review InfraCtl metadata for security. Check: 1) No hardcoded secrets, 2) Encryption enforced, 3) Audit logging configured, 4) Least-privilege IAM. Flag issues with severity. This enforces security boundaries.",
"description": "Security review for InfraCtl"
},
{
"name": "infractl-changelog",
"prompt": "Generate changelog for InfraCtl metadata changes. Compare commits, format as ## Module: <name> - Added/Changed/Removed. Flag breaking changes. This provides audit trail.",
"description": "Generate InfraCtl changelog"
}
]
}
6.2 VSCode Snippets for InfraCtl¶
File: ~/.vscode/snippets/infractl.json
{
"InfraCtl Module Contract": {
"prefix": "infractl-contract",
"body": [
"{",
" \"source\": \"../../terraform/modules/${1:module-name}\",",
" \"variables\": {",
" \"${2:variable_name}\": {",
" \"type\": \"${3:string}\",",
" \"required\": ${4:true},",
" \"description\": \"${5:Description of variable}\"",
" }",
" },",
" \"depends_on\": [\"${6:dependency}\"],",
" \"files\": [\"${7:main.tf}\"],",
" \"security\": {",
" \"encryption_required\": ${8:true},",
" \"audit_logging\": ${9:true},",
" \"public_access\": ${10:false}",
" }",
"}"
],
"description": "InfraCtl module contract template"
},
"InfraCtl Environment Config": {
"prefix": "infractl-env",
"body": [
"{",
" \"modules\": {",
" \"${1:module_name}\": {",
" \"enabled\": ${2:true},",
" \"inputs\": {",
" \"${3:variable}\": \"${4:value}\"",
" }",
" }",
" }",
"}"
],
"description": "InfraCtl environment configuration template"
},
"InfraCtl Validation Command": {
"prefix": "infractl-val",
"body": [
"infractl validate ${1:env} -v",
"infractl generate ${1:env} --dry-run",
"infractl plan ${1:env}"
],
"description": "InfraCtl validation commands"
}
}
6.3 The Structured Workflow in VSCode¶
┌─────────────────────────────────────────────────────────────┐
│ STRUCTURED INFRACTL WORKFLOW IN VSCODE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Open Continue Panel (Ctrl+L) │
│ • Select model: DeepSeek-V3 (metadata reasoning) │
│ │
│ Step 2: Use Custom Command │
│ • Type: /infractl-module │
│ • Enter: module name and requirements │
│ • AI generates metadata contract FIRST │
│ • AI generates module code SECOND (following contract) │
│ │
│ Step 3: Review Structure (CRITICAL) │
│ • Verify metadata contract is correct │
│ • Verify live/ has NO environment values │
│ • AI explains structure decisions │
│ │
│ Step 4: Validate │
│ • Run: infractl validate {env} │
│ • Fix any structure violations │
│ • AI suggests fixes │
│ │
│ Step 5: Generate & Plan │
│ • Run: infractl generate {env} │
│ • Run: infractl plan {env} │
│ • AI summarizes plan │
│ │
│ Step 6: Human Review (CRITICAL) │
│ • Engineer reviews structure + plan │
│ • Engineer approves │
│ • AI documents decision │
│ │
│ Step 7: Apply & Test │
│ • Run: infractl apply {env} │
│ • Run: infractl test {env} │
│ • AI documents results │
│ │
│ Result: AI speed WITH structure that keeps IaC manageable │
│ │
└─────────────────────────────────────────────────────────────┘
7. Part 6: Validation – Keeping AI Within Bounds ¶
7.1 The Validation Hierarchy¶
┌─────────────────────────────────────────────────────────────┐
│ VALIDATION HIERARCHY FOR AI IaC │
├─────────────────────────────────────────────────────────────┤
│ │
│ [Level 1: Automated Validation] │
│ • infractl validate {env} │
│ • Checks: Metadata structure, contracts, dependencies │
│ • AI Role: Run automatically, report issues │
│ • Enforcement: Block generation if validation fails │
│ │
│ [Level 2: Security Scanning] │
│ • tfsec live/{module}/ │
│ • checkov -d live/{module}/ │
│ • Checks: Security vulnerabilities, compliance │
│ • AI Role: Scan output, flag issues │
│ • Enforcement: Block apply if critical issues found │
│ │
│ [Level 3: Human Review] │
│ • Engineer reviews AI summary + plan │
│ • Checks: Business logic, compliance, risk │
│ • AI Role: Summarize changes, flag risks │
│ • Enforcement: Require approval for production changes │
│ │
│ [Level 4: Post-Apply Validation] │
│ • infractl test {env} │
│ • Checks: Actual state matches expected │
│ • AI Role: Compare, detect drift │
│ • Enforcement: Alert on drift, suggest fixes │
│ │
└─────────────────────────────────────────────────────────────┘
7.2 Pre-Commit Hooks (Automated Enforcement)¶
File: .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: infractl-validate
name: Validate InfraCtl Metadata
entry: infractl validate
language: system
files: meta/.*\.json$
pass_filenames: false
- id: no-inline-tfvars
name: Block Inline .tfvars
entry: grep -r '\.tfvars' --include='*.tf' live/
language: system
files: live/.*\.tf$
pass_filenames: false
- id: no-secrets
name: Block Hardcoded Secrets
entry: detect-secrets scan
language: system
files: meta/ live/
- id: terraform-fmt
name: Format Terraform
entry: terraform fmt -check
language: system
files: live/.*\.tf$
Why This Matters: Automated enforcement prevents AI (and humans) from violating structure.
7.3 CI/CD Checks (Pipeline Enforcement)¶
File: .github/workflows/infractl-validate.yml
name: InfraCtl Validation
on:
push:
paths:
- 'meta/**'
- 'live/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Metadata Structure
run: |
for env in dev staging prod; do
infractl validate $env -v
done
- name: Security Scan
run: |
tfsec live/
checkov -d live/
- name: Generate and Plan
run: |
for env in dev staging; do
infractl generate $env
infractl plan $env
done
- name: Block Production Without Review
if: github.ref == 'refs/heads/main'
run: |
echo "Production changes require manual approval"
echo "Please review infractl plan prod output"
Why This Matters: CI/CD enforces structure even when humans forget.
7.4 The Human Review Checklist¶
# Human Review Checklist for AI-Generated IaC
## Structure Validation:
□ Metadata contract exists (meta/live/*.json)
□ Environment values in correct location (meta/env/*/)
□ NO inline .tfvars anywhere
□ NO environment values in live/
□ Generated code in build/ (not committed)
## Security Validation:
□ No hardcoded secrets
□ Encryption enabled where required
□ Audit logging configured
□ Least-privilege IAM policies
□ Network segmentation correct
## Compliance Validation:
□ HIPAA/SOC2/PCI requirements met
□ Audit trail of changes exists
□ Changelog generated and reviewed
□ Approval documented for production changes
## AI-Specific Validation:
□ AI suggestions reviewed (not blindly accepted)
□ AI-generated code tested
□ AI summary matches actual changes
□ AI flagged issues addressed
## Sign-Off:
□ Engineer name: ________________
□ Date: ________________
□ Approved for: □ dev □ staging □ prod
□ Notes: ________________
Why This Matters: Human review catches what automation misses.
8. Part 7: Iteration Points – Your Feedback Needed ¶
8.1 This Chapter's Core Message¶
"AI can generate all the code you need for IaC. But without clear structure, that code becomes unmanageable. This chapter provides the structure (metadata-first design) that allows AI to be used effectively without sacrificing maintainability."
8.2 Questions for Your Feedback¶
□ Question 1: Does the "structure over speed" message come through clearly?
- Is this the right framing for your experience?
- What would make it clearer?
□ Question 2: Is the metadata-first concept explained well?
- Does the three-layer architecture make sense?
- What examples would help?
□ Question 3: Are the AI roles practical?
- Do these match how you actually use AI for IaC?
- What roles are missing?
□ Question 4: Is InfraCtl a good example?
- Should we use your actual InfraCtl implementation?
- What specifics should we add?
□ Question 5: Is the VSCode integration practical?
- Do you use Continue.dev or different tools?
- What workflows would save you time?
□ Question 6: Is validation comprehensive enough?
- What validation checks do you actually use?
- What enforcement mechanisms work for your team?
□ Question 7: What's missing?
- What topics should be added?
- What should be removed or condensed?
8.3 Proposed Iteration Process¶
Iteration 1 (This Draft):
□ You review against Section 8.2 questions
□ You provide feedback on what works/doesn't
Iteration 2 (Enhanced Draft):
□ I incorporate your feedback
□ Add your actual InfraCtl examples
□ Add your team's actual workflows
Iteration 3 (Final Chapter):
□ Polish language and flow
□ Ensure consistent with Chapters 1-2
□ Add diagrams where helpful
9. Appendix: Structured Prompt Templates ¶
9.1 Complete Prompt Library for Structured IaC¶
# STRUCTURED IaC PROMPT LIBRARY (Chapter 3)
## 1. Module Creation (With Structure)
/infractl-module {module_name}
"Generate new InfraCtl module. CRITICAL: 1) Create meta/live/{module}.json contract FIRST, 2) Create live/{module}/ following contract, 3) NEVER include environment values in live/, 4) Validate with infractl validate."
## 2. Environment Configuration (Data, Not Logic)
/infractl-env {environment}
"Configure InfraCtl environment. CRITICAL: 1) ONLY modify meta/env/{env}/live-modules.json, 2) NEVER modify live/, 3) NEVER create inline .tfvars, 4) Validate after changes."
## 3. Validation (Enforce Structure)
/infractl-validate {environment}
"Validate InfraCtl metadata. Check: 1) Module contract structure, 2) Environment inputs, 3) Dependencies, 4) Security/compliance. This enforces the structure that keeps IaC manageable."
## 4. Drift Detection (Catch Issues Early)
/infractl-drift {environment}
"Detect drift in generated output. Compare build/ against expected. Flag ANY manual edits to build/ (PROHIBITED). Check environment drift. Catch issues before unmanageable."
## 5. Security Review (Enforce Boundaries)
/infractl-security {module_or_env}
"Review for security. Check: 1) No hardcoded secrets, 2) Encryption enforced, 3) Audit logging, 4) Least-privilege. Enforce security boundaries AI might miss."
## 6. Changelog (Audit Trail)
/infractl-changelog {commit_range}
"Generate changelog from metadata diffs. Format: ## Module: <name> - Added/Changed/Removed. Flag breaking changes. Provides audit trail for compliance."
## 7. Cost Optimization (Within Structure)
/infractl-cost {environment}
"Analyze for cost optimization. Identify: 1) Over-provisioned resources, 2) Unused modules, 3) Optimization opportunities. Quantify savings. Work within structure."
## 8. Test Generation (Validate Structure)
/infractl-test {module}
"Generate test scaffolds. Create: 1) Unit tests for contract validation, 2) Integration tests for dependencies, 3) Security tests, 4) Compliance tests. Validate structure."
## 9. Documentation (Explain Structure)
/infractl-docs {module}
"Generate README. Include: 1) Module purpose, 2) Inputs/outputs, 3) Dependencies (Mermaid), 4) Usage per environment, 5) Compliance notes. Explain structure to team."
## 10. Migration (Preserve Structure)
/infractl-migrate {current} {target}
"Plan migration. Analyze: 1) Current structure, 2) Target requirements, 3) Breaking changes, 4) Rollback. Preserve structure throughout migration."
9.2 The Chapter 3 Checklist¶
# Chapter 3: Structure Over Speed - Checklist
## Before Using AI for IaC:
□ Understand metadata-first design (Section 3.1)
□ Know the three-layer architecture (Section 3.2)
□ Understand AI boundaries (Section 3.4)
## When Generating IaC with AI:
□ Use structured prompt templates (Appendix 9.1)
□ AI generates metadata contract FIRST
□ AI generates module code SECOND (following contract)
□ NEVER allow inline .tfvars
□ NEVER allow environment values in live/
## After AI Generation:
□ Run: infractl validate {env}
□ Run: tfsec live/{module}/
□ Run: checkov -d live/{module}/
□ Human review with checklist (Section 7.4)
□ Document AI suggestions in commit message
## Ongoing Maintenance:
□ Run: infractl drift {env} weekly
□ Generate changelog for all metadata changes
□ Review AI-generated code quarterly
□ Update structure as needed (with team approval)
## Key Principle:
"AI can generate all the code. Structure keeps it manageable."
Chapter Summary¶
The Core Message¶
┌─────────────────────────────────────────────────────────────┐
│ CHAPTER 3 IN ONE SENTENCE │
├─────────────────────────────────────────────────────────────┤
│ │
│ "AI can generate all the code you need for IaC. │
│ But without clear structure, that code becomes │
│ unmanageable. This chapter provides the structure │
│ (metadata-first design) that allows AI to be used │
│ effectively without sacrificing maintainability." │
│ │
└─────────────────────────────────────────────────────────────┘
Key Takeaways¶
✅ AI generates IaC fast – but speed without structure = technical debt
✅ Metadata-first design provides SYMBOLIC CONSTRAINTS for AI (Chapter 1)
✅ Three-layer architecture: Metadata (meta/) + Logic (live/) + Generated (build/)
✅ AI boundaries: What AI can/cannot do, enforced by validation
✅ VSCode integration: Continue.dev with InfraCtl custom commands
✅ Validation hierarchy: Automated + Security + Human + Post-Apply
✅ The goal: AI speed WITH structure that keeps IaC manageable
Connection to Other Chapters¶
| Chapter | Connection |
|---|---|
| Chapter 1 | Metadata = Symbolic Constraints, Module Code = Data-Driven Generation |
| Chapter 2 | VSCode + Continue.dev configured for InfraCtl workflows |
| Chapter 3 | Structure enables AI to be effective without creating messes |
| Chapter 4 | CI/CD pipelines enforce the structure automatically |
Document Version: 0.2 (Restructured for Core Message) Part of: The DevOps Engineer's Guide to Effective AI Usage Last Updated: [Current Date] Prepared By: [Your Name]
This is a DRAFT for iteration. Please provide feedback on Section 8.2 questions so we can refine this chapter together. The core message is: Structure over speed. AI generates code fast, but structure keeps it manageable.