# Terraform Generation Instructions

This document describes how to generate Terraform configurations using the Terraform MCP server.

## Overview

You have access to the Terraform MCP server which provides live documentation from the Terraform Registry. ALWAYS use this to get accurate, up-to-date resource schemas instead of relying on memorized configurations.

## Available MCP Tools

### Provider Discovery

**`mcp__terraform__search_providers`**
Search for Terraform providers in the registry.

```
Input: { "query": "google", "limit": 5 }
Output: List of matching providers with names and descriptions
```

**`mcp__terraform__get_provider_details`**
Get detailed information about a provider including all resources and data sources.

```
Input: { "provider": "hashicorp/google", "version": "latest" }
Output: Provider details, resource list, data source list
```

### Resource Documentation

**`mcp__terraform__get_resource_details`**
Get the full schema and documentation for a specific resource.

```
Input: { "provider": "hashicorp/google", "resource": "google_cloud_run_v2_service" }
Output: All arguments, attributes, examples
```

### Module Discovery

**`mcp__terraform__search_modules`**
Search for reusable modules.

```
Input: { "query": "gcp cloud run" }
Output: List of modules with descriptions and download counts
```

## Terraform Generation Workflow

### Step 1: Determine Required Resources

Based on codebase analysis and selected template, list the resources needed:

Example for an API service on GCP:
- `google_artifact_registry_repository` - Container registry
- `google_cloud_run_v2_service` - API service
- `google_sql_database_instance` - Database (if needed)
- `google_secret_manager_secret` - Secrets
- `google_vpc_access_connector` - VPC connectivity (if private DB)

### Step 2: Query Resource Documentation

For EACH resource, query the Terraform MCP to get the current schema:

```
mcp__terraform__get_resource_details:
  provider: hashicorp/google
  resource: google_cloud_run_v2_service
```

This returns:
- Required arguments
- Optional arguments with defaults
- Nested block structures
- Attribute references
- Example configurations

### Step 3: Generate Terraform Files

Create the following files in `.infera/terraform/`:

#### `main.tf`

```hcl
# Generated by Infera
# Project: {project_name}
# Provider: {provider}

terraform {
  required_version = ">= 1.0"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

# Enable required APIs first
resource "google_project_service" "required_apis" {
  for_each = toset([
    "run.googleapis.com",
    "artifactregistry.googleapis.com",
    "sqladmin.googleapis.com",
    # Add APIs based on resources used
  ])
  service            = each.value
  disable_on_destroy = false
}

# Resources follow...
```

#### `variables.tf`

```hcl
variable "project_id" {
  description = "GCP project ID"
  type        = string
}

variable "region" {
  description = "GCP region"
  type        = string
  default     = "us-central1"
}

# Add variables for configurable values
```

#### `outputs.tf`

```hcl
output "service_url" {
  description = "URL of the deployed service"
  value       = google_cloud_run_v2_service.main.uri
}

# Add outputs for important values
```

### Step 4: Resource Dependencies

Ensure proper dependency ordering:

1. **API enablement** - Must complete before any resources
2. **Networking** (VPC, subnets) - Before resources that use them
3. **Storage** (buckets, registries) - Before services that reference them
4. **Databases** - Before services that connect to them
5. **Secrets** - Before services that use them
6. **Compute** (Cloud Run, GKE) - Depends on all above
7. **IAM** - After resources exist

Use `depends_on` when implicit dependencies aren't detected:

```hcl
resource "google_cloud_run_v2_service" "api" {
  # ...
  depends_on = [
    google_project_service.required_apis,
    google_artifact_registry_repository.registry,
  ]
}
```

## Provider-Specific Patterns

### GCP (Google Cloud Platform)

#### Cloud Run v2

Always query `google_cloud_run_v2_service` for current schema. Key patterns:

```hcl
resource "google_cloud_run_v2_service" "api" {
  name     = var.service_name
  location = var.region

  template {
    containers {
      image = var.container_image

      ports {
        container_port = 8080
      }

      resources {
        limits = {
          cpu    = "1"
          memory = "512Mi"
        }
      }

      # Environment variables
      env {
        name  = "ENV"
        value = "production"
      }

      # Secret environment variables
      env {
        name = "DATABASE_URL"
        value_source {
          secret_key_ref {
            secret  = google_secret_manager_secret.db_url.secret_id
            version = "latest"
          }
        }
      }
    }

    scaling {
      min_instance_count = 0
      max_instance_count = 10
    }

    # VPC access for private resources
    vpc_access {
      connector = google_vpc_access_connector.main.id
      egress    = "PRIVATE_RANGES_ONLY"
    }
  }
}

# Public access
resource "google_cloud_run_service_iam_member" "public" {
  location = google_cloud_run_v2_service.api.location
  name     = google_cloud_run_v2_service.api.name
  role     = "roles/run.invoker"
  member   = "allUsers"
}
```

#### Cloud SQL

Query `google_sql_database_instance` for current schema:

```hcl
resource "google_sql_database_instance" "main" {
  name             = var.db_instance_name
  database_version = "POSTGRES_15"
  region           = var.region

  settings {
    tier      = "db-f1-micro"  # Smallest for dev
    disk_size = 10
    disk_type = "PD_SSD"

    backup_configuration {
      enabled    = true
      start_time = "03:00"
    }

    ip_configuration {
      ipv4_enabled    = false  # Private only
      private_network = google_compute_network.main.id
    }
  }

  deletion_protection = false  # Set true for production
}

resource "google_sql_database" "main" {
  name     = var.db_name
  instance = google_sql_database_instance.main.name
}

resource "google_sql_user" "main" {
  name     = var.db_user
  instance = google_sql_database_instance.main.name
  password = random_password.db_password.result
}
```

#### Cloud Storage (Static Sites)

Query `google_storage_bucket` for current schema:

```hcl
resource "google_storage_bucket" "static" {
  name     = var.bucket_name
  location = var.region

  website {
    main_page_suffix = "index.html"
    not_found_page   = "404.html"
  }

  cors {
    origin          = ["*"]
    method          = ["GET", "HEAD"]
    response_header = ["Content-Type"]
    max_age_seconds = 3600
  }

  uniform_bucket_level_access = true
}

# Public access
resource "google_storage_bucket_iam_member" "public" {
  bucket = google_storage_bucket.static.name
  role   = "roles/storage.objectViewer"
  member = "allUsers"
}
```

### AWS (Amazon Web Services)

Query the `hashicorp/aws` provider for resource schemas.

### Azure

Query the `hashicorp/azurerm` provider for resource schemas.

## Best Practices

1. **Always query MCP for current schemas** - Don't assume argument names
2. **Use variables for configurable values** - project_id, region, names
3. **Enable APIs before creating resources** - Use `google_project_service`
4. **Use `for_each` for multiple similar resources** - Cleaner than `count`
5. **Add meaningful descriptions** - Help users understand purpose
6. **Output important values** - URLs, IPs, connection strings
7. **Consider lifecycle rules** - `prevent_destroy` for stateful resources
8. **Use `random_password` for credentials** - Never hardcode secrets

## Validation

Before finalizing, verify:

1. All required arguments are provided
2. Dependencies are correctly ordered
3. IAM permissions are configured
4. Outputs include necessary values
5. Variables have sensible defaults

Write the files using the Write tool to `.infera/terraform/`.
