thothctl

Generate IaC — Intent-to-Infrastructure

Generate governed Infrastructure as Code from natural language descriptions. ThothCTL reads your organizational conventions (.thothcf.toml, steering docs, existing patterns) and produces compliant code validated by Checkov and OPA.

Quick Start

# Generate a VPC (dry-run by default — shows code without writing)
thothctl generate iac -i "VPC with 3 private subnets and NAT gateway for production"

# Write to disk
thothctl generate iac -i "EKS cluster with managed node groups" --apply -o ./stacks/platform/eks

# Use AWS Bedrock instead of local Ollama
thothctl generate iac -i "S3 bucket with versioning and encryption" -p bedrock

# Use Kiro CLI for tool-augmented generation (reads docs, validates, self-corrects)
thothctl generate iac -i "RDS Aurora cluster with read replicas and failover" -p kiro

How It Works

Your intent (natural language)
       ↓
1. Load Context — reads .thothcf.toml, steering docs, existing patterns, OPA policies
       ↓
2. Generate — AI produces IaC code following your org conventions
       ↓
3. Validate — Checkov + OPA scan the generated code
       ↓
4. Self-Correct — if violations found, AI fixes them (up to 3 attempts)
       ↓
5. Output — display (dry-run) or write to disk (--apply)

The AI produces compliant code because your organizational rules are injected directly into its context — not because of a separate policy engine. Existing Checkov and OPA validate the output as a safety net.

Options

Flag Short Default Description
--intent -i (required) What infrastructure to create
--project-type -pt auto terraform, terraform-terragrunt, terragrunt, cloudformation, cdkv2
--provider -p ollama AI provider: ollama, bedrock, openai, azure, kiro
--model -m (provider default) Model override or Kiro agent name (e.g., llama3, us.anthropic.claude-sonnet-4-6, iac-expert)
--output-dir -o current dir Where to write generated files
--dry-run / --no-dry-run   dry-run Preview without writing
--apply   off Write files to disk
--self-correct / --no-self-correct   on Fix validation violations automatically
--max-iterations   3 Maximum self-correction attempts
--skip-validation   off Skip Checkov/OPA (trust AI output)
--include-diagram / --no-diagram   on Generate architecture diagram
--composition   single single (one stack), full (multi-stack project), incremental (add stacks to existing)
--mode   project blueprint (template with #{...}# placeholders) or project (resolved, ready to deploy)
--space   Space name to load deployment parameters (for project mode)
--plan-validation   disabled disabled, per-stack, full-project, terraform
--plan-profile   AWS profile for plan validation credentials
--plan-iam-role   IAM role ARN for temporal credentials during plan
--plan-filter   Terragrunt filter for targeted stack validation

Examples

Basic VPC (Terragrunt)

thothctl generate iac \
  -i "VPC with 3 private subnets, 3 public subnets, NAT gateway per AZ, flow logs enabled" \
  -pt terraform-terragrunt \
  --apply -o ./stacks/foundation/network/vpc

Generates:

stacks/foundation/network/vpc/
├── terragrunt.hcl    # include root, dependency blocks, inputs
├── main.tf           # terraform-aws-modules/vpc/aws with flow logs
├── variables.tf      # cidr, environment, tags
└── outputs.tf        # vpc_id, subnet_ids, nat_gateway_ids

EKS Cluster (Terraform)

thothctl generate iac \
  -i "Production EKS cluster with managed node groups, Karpenter autoscaler, and IRSA" \
  -pt terraform \
  -p bedrock -m claude-sonnet-4-20250514 \
  --apply -o ./modules/eks

S3 with Security (validates automatically)

thothctl generate iac \
  -i "S3 bucket for application logs with encryption, versioning, lifecycle rules, and no public access"

The self-correction loop ensures:

Composition Mode (v0.26.1+)

Generate entire multi-stack projects from a single intent:

# Full project: root.hcl + common/ + multiple stacks with dependencies
thothctl generate iac \
  -i "Create a microservices platform with VPC, EKS, RDS, and ElastiCache" \
  --composition full \
  -p bedrock -m us.anthropic.claude-sonnet-4-6 \
  --apply -o ./my-platform

Generates:

my-platform/
├── root.hcl                          # Backend + provider config
├── common/common.hcl                 # Shared variables and locals
├── common/common.tfvars              # Deployment parameters
├── .gitignore
├── .pre-commit-config.yaml
└── stacks/
    ├── foundation/networking/vpc/
    │   ├── terragrunt.hcl            # include root, inputs
    │   ├── main.tf                   # terraform-aws-modules/vpc/aws
    │   ├── variables.tf              # ONLY variable blocks
    │   └── outputs.tf                # ONLY output blocks
    ├── platform/compute/eks/
    │   ├── terragrunt.hcl            # dependency on vpc
    │   ├── main.tf
    │   ├── variables.tf
    │   └── outputs.tf
    └── platform/data/rds/
        ├── terragrunt.hcl            # dependency on vpc
        ├── main.tf
        ├── variables.tf
        └── outputs.tf

Composition modes:

Blueprint vs Project Mode (v0.27.1+)

Control whether output is a reusable template or a ready-to-deploy project:

Project Mode (default)

thothctl generate iac \
  -i "VPC with subnets in us-east-1 for production" \
  --mode project \
  --space labvel-devsecops \
  --composition full \
  --apply -o ./vpc-prod

Output has resolved values from space config + intent:

# common/common.hcl
locals {
  profile           = "labvel-devsecops"   # From --space
  project           = "vpc-prod"           # From --output-dir
  deployment_region = "us-east-1"          # Extracted from intent
  environment       = "prod"              # Extracted from "for production"
}

Blueprint Mode

thothctl generate iac \
  -i "VPC with subnets" \
  --mode blueprint \
  --composition full \
  --apply -o ./vpc-template

Output keeps #{...}# placeholders (for Backstage, thothctl init project, or CI/CD):

# common/common.hcl
locals {
  profile           = "#{deployment_profile}#"
  project           = "#{project_name}#"
  deployment_region = "#{deployment_region}#"
}

Value Resolution (Project Mode)

Values are resolved from these sources (priority order):

Priority Source Example
1 Intent NLP extraction “in us-east-1” → deployment_region
2 Space config ~/.thothcf/spaces/<name>/orchestration/terragrunt.toml
3 CLI flags --output-dir vpc-prodproject_name
4 Scaffold defaults template_input_parameters.template_value

Plan Validation (v0.27.0+)

Validate generated code with terraform/terragrunt plan before output:

# Per-stack: runs terragrunt plan on each generated stack
thothctl generate iac \
  -i "VPC with subnets" \
  --composition full \
  --plan-validation per-stack \
  --plan-profile labvel-devsecops

# Full-project: runs terragrunt run --all -- plan --graph (DAG-aware)
thothctl generate iac \
  -i "VPC with subnets" \
  --composition full \
  --plan-validation full-project

# With IAM role for temporal credentials (15-min session)
thothctl generate iac \
  -i "VPC with subnets" \
  --plan-validation per-stack \
  --plan-iam-role arn:aws:iam::123456789012:role/thothctl-plan-readonly

Plan validation modes:

Mode What it does Requires
disabled (default) No plan Nothing
per-stack terragrunt plan per stack during generation AWS credentials + terragrunt
full-project terragrunt run --all -- plan --graph after all stacks AWS credentials + terragrunt
terraform terraform plan for non-terragrunt projects AWS credentials + terraform/tofu

When plan fails, violations are fed back to the AI for self-correction (same loop as Checkov/OPA).

Configuration (.thothcf.toml)

[generation.plan]
plan_validation = "per-stack"
iam_assume_role = "arn:aws:iam::123456789012:role/plan-readonly"
session_duration = 900
provider_cache = true
plan_timeout = 120

Dashboard Integration (v0.27.4+)

Every generation run is recorded and viewable in the ThothCTL dashboard:

thothctl dashboard launch
# Navigate to ✨ Generation tab

The dashboard shows:

CloudFormation

thothctl generate iac \
  -i "Application Load Balancer with HTTPS listener and WAF" \
  -pt cloudformation \
  --apply -o ./stacks/application/web-tier.yaml

Skip Validation (fast iteration)

thothctl generate iac \
  -i "CloudWatch dashboard with CPU, memory, and request metrics" \
  --skip-validation --apply

Context Sources

ThothCTL compiles organizational context from these sources (in priority order):

Source What’s Used Token Budget
.thothcf.toml Project type, naming patterns, environment, tags ~500
.kiro/steering/iac-rules.md or .claude/rules/*.md IaC composition rules, module preferences, prohibited practices ~2000
.kiro/steering/product.md or CLAUDE.md Project purpose, architecture layers ~500
Existing files in stacks/ Real examples from your project (few-shot) ~2000
policies/*.rego or THOTH_ORG_POLICY OPA rule names and descriptions ~500

Total context: ~5,500 tokens — leaves room for generation within most model limits.

No Context? No Problem

If none of these files exist, the command still works — it generates standard Terraform following AWS best practices. Context just makes the output match your conventions.

AI Providers

Provider Flag Requires Best For
Ollama -p ollama Local Ollama running Offline, private, fast iteration
AWS Bedrock -p bedrock AWS credentials Production quality, Claude models
OpenAI -p openai OPENAI_API_KEY GPT-4 Turbo
Azure OpenAI -p azure Azure endpoint configured Enterprise Azure environments
Kiro CLI -p kiro kiro-cli installed Complex generation with tool access

Kiro Provider (v0.27.12+)

Kiro CLI in headless mode acts as a tool-augmented AI agent — unlike raw LLM providers that only see the prompt, Kiro can:

This makes it the best choice for complex multi-resource generation where the AI needs to understand your codebase deeply.

# Use Kiro as the generation engine
thothctl generate iac -i "EKS cluster with Karpenter and IRSA" -p kiro

# Use a custom Kiro agent optimized for IaC
thothctl generate iac -i "VPC with Transit Gateway" -p kiro -m iac-expert

Custom Kiro Agent Setup (optional):

Create .kiro/agents/iac-expert.yaml for specialized IaC generation:

name: iac-expert
model: auto
allowedTools:
  - read
  - write
  - grep
  - glob
  - shell
  - web_search
  - web_fetch
  - aws___search_documentation
  - aws___read_documentation
  - resolveProviderDocID
  - getProviderDocs
  - search_cloudformation_documentation
  - search_cdk_documentation
steering:
  - .kiro/steering/iac-generation-rules.md

Tradeoffs:

  Kiro Direct LLM (Ollama/Bedrock)
Latency 15-60s (tool access overhead) 3-15s
Context richness Full (reads files, docs, web) Prompt-only (what thothctl injects)
Self-correction Built-in + thothctl loop ThothCTL loop only
Cost visibility Not tracked by thothctl Full token/cost tracking
Offline Needs kiro-cli binary Ollama works fully offline

Recursion protection: When thothctl runs as an MCP tool inside Kiro, the --provider kiro option is automatically blocked to prevent infinite loops.

Provider Model Quality Speed
Ollama llama3 (default) Good Fast
Ollama codellama:34b Better Slower
Bedrock claude-sonnet-4-20250514 Excellent Fast
OpenAI gpt-4-turbo Excellent Medium

Self-Correction

When Checkov finds violations, the AI automatically fixes them:

🤖 Generating infrastructure code...
  ✅ Generated 4 files

🔒 Validating with Checkov...
  ⚠️ 2 findings: CKV_AWS_130 (VPC flow logs), CKV_AWS_178 (NAT HA)

🔄 Self-correcting (iteration 1/3)...
  ✅ Fixed: added flow logs + multi-AZ NAT

🔒 Re-validating...
  ✅ Validation passed

Disable with --no-self-correct if you want raw output without fixes.

MCP Integration

The command is also available as an MCP tool for AI assistants (Kiro, Claude Code):

{
  "name": "thothctl_generate_iac",
  "description": "Generate governed IaC from natural language intent",
  "parameters": {
    "intent": "VPC with 3 private subnets",
    "project_type": "terraform-terragrunt",
    "self_correct": true,
    "apply": false
  }
}

Start the MCP server: thothctl mcp server

Tips

  1. Be specific — “VPC with 3 private subnets, NAT per AZ, flow logs” produces better results than “create a VPC”
  2. Use your scaffold — run from a project that has .thothcf.toml and existing stacks for best context
  3. Start with dry-run — review the generated code before --apply
  4. Iterate — if the output isn’t perfect, refine your intent and re-run
  5. Use Bedrock for production — Claude Sonnet produces the highest quality IaC

Troubleshooting

“AI returned no files”

The AI provider couldn’t parse the intent or returned invalid JSON. Try:

“Validation: N violations remain”

Self-correction reached max iterations without passing all checks. Options:

Slow generation with Ollama

Large models + long context = slow. Solutions:

Provider not initialized

Failed to initialize AI provider: ...

Check provider configuration:

Kiro: “Recursive invocation detected”

RuntimeError: Recursive invocation detected

This means thothctl is running inside a Kiro session (as an MCP tool) and tried to use --provider kiro. Use a different provider:

# Inside Kiro MCP context, use ollama or bedrock instead
thothctl generate iac -i "..." -p ollama

Kiro: “kiro-cli not found”

Install Kiro CLI or specify the binary path in your AI config (~/.thothctl/ai_config.yaml):

ai_review:
  providers:
    kiro:
      endpoint: /path/to/kiro-cli

Kiro: Slow generation

Kiro headless mode is slower (15-60s) than direct API calls because it uses tools (reads files, searches docs). For quick iterations, use -p ollama. Reserve -p kiro for complex tasks where context richness matters.