# Validation

Source: https://docs.ops0.com/docs/iac/deployments/validation

ops0 validates your IaC code in two layers before any deployment runs: **syntax validation** (via `terraform validate`) and **lint checking** (via TFLint). Both must pass before the plan stage is allowed to proceed.

---

## Validation Layers

| Layer | Tool | What It Checks |
|-------|------|----------------|
| **Syntax validation** | `terraform validate` / `tofu validate` | HCL syntax, argument names, type errors, missing required fields, broken references |
| **Lint checking** | TFLint | Best-practice rules, deprecated arguments, provider-specific issues, naming conventions |

---

## When Validation Runs

Validation triggers automatically in three situations:

| Trigger | When |
|---------|------|
| **On save** | ~2 seconds after you stop typing in the editor |
| **On AI generation** | Immediately after AI writes or modifies files |
| **Before deployment** | Gating check — deployment is blocked if validation fails |

You can also trigger it manually at any time by clicking **Validate** in the project toolbar.

---

## Syntax Validation

Runs `terraform validate` (or `tofu validate` / `oxid validate` depending on engine) against all files in the project.

### Success Output

```
✓ Terraform Validation Passed

Checked 12 files in 2.3 seconds
No issues found
```

### Failure Output

```
✗ Terraform Validation Failed — 3 errors in 2 files

main.tf:
  Line 15: Unsupported argument "instance_types" on resource "aws_instance"
  Line 23: Missing required argument "ami"

modules/database/main.tf:
  Line 8: Invalid reference: var.databse_name (did you mean var.database_name?)
```

Errors are also shown inline in the editor with red underline markers and margin indicators.

### Common Syntax Errors

**Missing required argument**
```
Error: Missing required argument
  The argument "ami" is required.
```
Fix: Add the missing argument to the resource block.

**Unsupported argument**
```
Error: Unsupported argument
  An argument named "instance_types" is not expected here.
  Did you mean "instance_type"?
```
Fix: Check the provider docs for the correct argument name.

**Invalid reference**
```
Error: Reference to undeclared resource
  There is no resource "aws_vpc" "main" declared.
```
Fix: Declare the resource or correct the reference.

**Missing closing brace**
```
Error: Invalid block definition
  Missing closing brace for resource block starting at line 10.
```
Fix: Add the missing `}`.

---

## TFLint

TFLint runs after syntax validation passes. It applies provider-specific rules and best-practice checks that `terraform validate` cannot catch.

### What TFLint Checks

| Rule Type | Example |
|-----------|---------|
| **Invalid instance types** | `t3.xxxxlarge` does not exist in AWS |
| **Deprecated arguments** | Using a removed attribute on a resource |
| **Naming conventions** | Resource names don't match org naming rules |
| **Required tags** | Resources missing mandatory tags |
| **Provider version constraints** | Missing or overly permissive version pins |
| **Security rules** | Unencrypted storage, public S3 buckets |

### TFLint Output

Findings are shown per-file with severity and line number:

```
TFLint Results — 2 findings

main.tf:
  ⚠ WARNING  Line 12: aws_instance.web — "t3.xxxxlarge" is not a valid instance type (aws_instance_invalid_type)
  ℹ NOTICE   Line 45: aws_s3_bucket.data — Missing required tag "Environment" (required_tags)
```

### Severity Levels

| Severity | Icon | Meaning |
|----------|------|---------|
| **Error** | ✗ | Blocks deployment (rule is violated and must be fixed) |
| **Warning** | ⚠ | Highlighted in results, does not block |
| **Notice** | ℹ | Informational, does not block |

---

## Validation History

Every validation run is recorded with its full output, trigger type, and findings. Access the history from **Project → Validation History**.

### What's Recorded

| Field | Description |
|-------|-------------|
| **Triggered by** | `manual`, `auto_save`, or `auto_generate` |
| **Timestamp** | When the validation ran |
| **Status** | Passed or Failed |
| **Syntax errors** | Count and details |
| **TFLint findings** | Count, severity breakdown, and per-finding details |
| **Files checked** | Number of files in the project at time of run |

### TFLint Finding Details

Each TFLint finding in history includes:

| Field | Description |
|-------|-------------|
| **Rule name** | e.g. `aws_instance_invalid_type` |
| **Severity** | error / warning / notice |
| **File** | Path to the affected file |
| **Line range** | Start and end line of the issue |
| **Message** | Human-readable description |
| **Link** | Rule documentation URL (when available) |

### Pagination

History is paginated (20 entries per page). Use the **Previous / Next** controls to browse older runs.

---

## Fixing Validation Errors

### Read the error
The error message includes the file name, line number, and a description. Errors also appear inline in the editor.

### Navigate to the line
Click the file/line reference in the validation panel, or use the inline editor marker.

### Fix the code
Correct the issue — argument name, type, reference, or missing block.

### Save
The editor auto-validates ~2 seconds after you stop typing. Or click **Validate** manually.

### Confirm pass
The validation status badge in the toolbar turns green.

---

## Next Steps

- [Policy Checking](https://docs.ops0.com/docs/iac/deployments/policies): Enforce security and compliance policies after validation passes

- [Deployments](https://docs.ops0.com/docs/iac/deployments): Deploy infrastructure once validation passes

- [Editor](https://docs.ops0.com/docs/iac/editor): Write and edit IaC code with inline validation feedback
