# Project Editor

Source: https://docs.ops0.com/docs/iac/editor

The IDE-like workspace for building infrastructure with AI assistance. Three resizable panels: Chat, Code Editor, and File Explorer.

## Editor Panels

- **Chat**: Describe infrastructure in plain English. AI writes code with reasoning.

- **Code Editor**: Monaco editor with HCL syntax highlighting, auto-complete, and code folding.

- **File Explorer**: File tree with color-coded icons. Right-click for actions.

## Toolbar Actions

| Button | Description |
|--------|-------------|
| **Validate** | Check Terraform syntax and run TFLint |
| **GitHub** | Push, sync, or create PR |
| **Deploy** | Open the deploy modal — plan, apply, destroy, or targeted deploy |
| **Outputs** | View Terraform output values and cloud-managed secrets |
| **Cost** | Full monthly cost breakdown by resource |
| **Settings** | Cloud integration, state backend, and project configuration |

---

## Deploy Modal

Click **Deploy** to open the deployment panel. The modal has the following options:

| Field | Description |
|-------|-------------|
| **Mode** | **Apply** (default) — create/update resources; **Destroy** — delete all resources in state |
| **Auto-approve** | Skip the plan review step and apply immediately (use with caution) |
| **Targeted resources** | Limit the deployment to specific resources using Terraform `-target` (e.g. `aws_instance.web`, `module.vpc`) — one per line |

### Blast Radius Card

Before applying, the Deploy modal shows a **Blast Radius** summary: how many resources will be added, changed, and destroyed. This is derived from the plan output. Review this before clicking Apply, especially for destructive changes.

### Cost Delta

The Deploy modal also shows the estimated cost impact — the difference between the current monthly estimate and the new estimate after the planned changes. A positive delta means costs will increase.

### Approval State

If the project has an approval policy attached, the Apply button is replaced with a **Request Approval** button. After approval is granted, the deployment state shows:
- Who approved and when
- A link to the approved deployment

---

## Outputs Panel

Click **Outputs** in the toolbar to open the Outputs & Secrets panel.

### Outputs Tab

Shows all `output` blocks defined in the project's Terraform code with their current values from state:

| Column | Description |
|--------|-------------|
| **Name** | Output name as defined in `outputs.tf` |
| **Value** | Current value (sensitive outputs are masked as `••••••••`) |
| **Description** | The `description` attribute if set |
| **Sensitive** | Whether the output is marked `sensitive = true` |

Actions: **Copy** (copies value to clipboard), **Reveal** (for sensitive outputs — requires permission), **Refresh** (re-reads from state without redeploying).

### Secrets Tab

Shows cloud-managed secrets from the integration connected to the project — AWS Secrets Manager, Azure Key Vault, or GCP Secret Manager. Only secrets tagged/labelled with `ops0-managed` are shown.

Clicking **Copy** on a secret value securely retrieves and copies the plaintext to clipboard. The value is never displayed in the UI. All retrievals are logged in audit logs.

---

## Cost Report Modal

Click **Cost** in the toolbar to open the full cost report.

| Section | Description |
|---------|-------------|
| **Total estimate** | Current monthly cost for all resources in state |
| **By resource** | Per-resource cost with hourly and monthly breakdown |
| **By category** | Costs grouped by resource type (Compute, Storage, Network, etc.) |
| **Budget comparison** | Current estimate vs configured budget limit (if set) |
| **Cost trend** | Sparkline chart of cost across recent deployments |

Click any resource row to see the detailed pricing breakdown (instance hours, storage GB, data transfer, etc.).

---

## Settings Modal

Click **Settings** to configure the project's cloud integration and state backend.

### Cloud Integration

Select which connected cloud integration (AWS role, GCP service account, Azure service principal) this project deploys against. Only integrations compatible with the project's configured provider are shown.

### State Backend

Configure where Terraform state is stored:

| Backend | Fields |
|---------|--------|
| **Local (ops0)** | No config needed — state stored in ops0 database |
| **S3** | Bucket, key (path), region, optional DynamoDB table for locking |
| **Azure Blob** | Storage account, container, key (path) |
| **GCS** | Bucket, prefix (path) |
| **Oxid** | PostgreSQL connection string |

Click **Test Backend** before saving to verify connectivity.

### Terraform Variables

The Settings modal also surfaces any declared `variable` blocks without defaults, allowing you to set values that are passed to every deployment without hardcoding them in `terraform.tfvars`.

---

## AI Chat

Create Terraform code by describing what you need in plain English.

### Example Prompts

- **Create Resources**: "Create an RDS PostgreSQL instance with db.t3.medium, Multi-AZ, and automated backups"

- **Modify Existing**: "Add a lifecycle policy to delete S3 objects after 90 days"

- **Explain Code**: "What does the security group in main.tf do?"

- **Fix Errors**: "I am getting InvalidParameterValue on the EC2 instance"

### Example Conversation

**You:** Create an EKS cluster with 3 t3.medium nodes in us-east-1

**AI:** I'll create an EKS cluster with a managed node group. Here's what I'm setting up:

- VPC with public/private subnets (EKS requires specific networking)
- EKS cluster with Kubernetes 1.28
- Managed node group with 3 t3.medium instances
- IAM roles for cluster and nodes
- Security groups for cluster communication

```hcl
module "eks" {
  source          = "terraform-aws-modules/eks/aws"
  version         = "~> 19.0"

  cluster_name    = "production-eks"
  cluster_version = "1.28"

  vpc_id          = module.vpc.vpc_id
  subnet_ids      = module.vpc.private_subnets

  eks_managed_node_groups = {
    default = {
      min_size       = 3
      max_size       = 5
      desired_size   = 3
      instance_types = ["t3.medium"]
    }
  }
}
```

**You:** Add cluster autoscaler

**AI:** I'll add the Cluster Autoscaler to automatically adjust node count based on demand...

### Tips for Better Results

**Prompting Tips**

  - **Be specific** - Include instance sizes, regions, naming conventions
  - **Reference existing code** - "Add a security group to the EC2 in main.tf"
  - **Ask follow-ups** - "Now add CloudWatch alarms for that RDS"
  - **Include constraints** - Compliance requirements, budget limits

---

## Code Editor

Monaco-based editor (same as VS Code) with full Terraform support.

### Features

- **Syntax Highlighting**: HCL, JSON, YAML, Markdown support.

- **Auto-Complete**: Intelligent completion for resource types, attributes, and functions.

- **Code Folding**: Collapse resource blocks to focus on what matters.

- **Auto-Save**: Automatically saves your work after 2s of inactivity.

### Keyboard Shortcuts

| Action | Windows/Linux | Mac |
|--------|---------------|-----|
| Save | `Ctrl + S` | `Cmd + S` |
| Find | `Ctrl + F` | `Cmd + F` |
| Replace | `Ctrl + H` | `Cmd + H` |
| Comment | `Ctrl + /` | `Cmd + /` |
| Go to line | `Ctrl + G` | `Cmd + G` |
| Delete line | `Ctrl + Shift + K` | `Cmd + Shift + K` |
| Duplicate line | `Ctrl + Shift + D` | `Cmd + Shift + D` |

### Error Indicators

| Indicator | Meaning |
|-----------|---------|
| Red underline | Syntax error |
| Yellow underline | Warning |
| Red dot in margin | Error on this line |

---

## File Explorer

Manage your Terraform files with a tree view.

### File Tree Example

```
EXPLORER
├── main.tf
├── variables.tf
├── outputs.tf
├── terraform.tfvars
└── modules/
    └── vpc.tf
```

### File Actions

| Action | How |
|--------|-----|
| **Create file** | Click + in header |
| **Create folder** | Click folder icon in header |
| **Rename** | Right-click → Rename |
| **Delete** | Right-click → Delete |
| **Copy path** | Right-click → Copy Path |

### File Indicators

| Indicator | Meaning |
|-----------|---------|
| **Bold text** | Currently open file |
| **Purple dot** | Unsaved changes |

---

## Example: Building an S3 Static Website

### Create Files
In the file explorer, create:
- `main.tf`
- `variables.tf`
- `outputs.tf`

### Ask AI
```
Create an S3 bucket configured for static website hosting with:
- Bucket name from variable
- index.html as default document
- error.html for 404s
- Public read access via bucket policy
- CloudFront distribution for HTTPS
```

### Produced Code

**main.tf**
```hcl
resource "aws_s3_bucket" "website" {
  bucket = var.bucket_name
}

resource "aws_s3_bucket_website_configuration" "website" {
  bucket = aws_s3_bucket.website.id

  index_document {
    suffix = "index.html"
  }

  error_document {
    key = "error.html"
  }
}

resource "aws_s3_bucket_public_access_block" "website" {
  bucket = aws_s3_bucket.website.id

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

resource "aws_s3_bucket_policy" "website" {
  bucket = aws_s3_bucket.website.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "PublicReadGetObject"
        Effect    = "Allow"
        Principal = "*"
        Action    = "s3:GetObject"
        Resource  = "${aws_s3_bucket.website.arn}/*"
      }
    ]
  })
}

resource "aws_cloudfront_distribution" "website" {
  enabled             = true
  default_root_object = "index.html"

  origin {
    domain_name = aws_s3_bucket_website_configuration.website.website_endpoint
    origin_id   = "S3-Website"

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }
  }

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = "S3-Website"
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}
```

**variables.tf**
```hcl
variable "bucket_name" {
  description = "Name of the S3 bucket for website hosting"
  type        = string
}
```

**outputs.tf**
```hcl
output "website_url" {
  description = "S3 website URL"
  value       = aws_s3_bucket_website_configuration.website.website_endpoint
}

output "cloudfront_url" {
  description = "CloudFront distribution URL (HTTPS)"
  value       = "https://${aws_cloudfront_distribution.website.domain_name}"
}
```

### Validate and Deploy
1. Click **Validate** to check syntax
2. Click **GitHub** to push code
3. Click **Deploy** → Enter `bucket_name` value → **Apply**

---

## Status Indicators

| Indicator | Meaning |
|-----------|---------|
| **Purple dot** on file | Unsaved changes |
| **Orange dot** on GitHub | Unpushed changes |
| **Green checkmark** | Validation passed |
| **Cost badge** | Monthly estimate |
