# Terraform Validation Errors

| Error | Fix |
|-------|-----|
| `Backend init failed` | Check storage account access |
| `Provider version conflict` | Update required_providers |
| `State lock failed` | Wait or force unlock |
| `Validation failed` | Check terraform validate output |
| `Error: Cycle:` | See [Cycle Errors](#cycle-errors) below |

## Cycle Errors

`terraform validate` reports a cycle when two or more resources reference each other's attributes, creating a circular dependency.

### Common Pattern: CORS Cross-Reference

Multi-service App Service deployments often introduce a cycle when the API's CORS configuration references the frontend hostname and the frontend's app settings reference the API hostname:

```
Error: Cycle: azurerm_linux_web_app.frontend, azurerm_linux_web_app.api
```

**Cause — circular attribute references:**

```hcl
# API references frontend.default_hostname in CORS
resource "azurerm_linux_web_app" "api" {
  site_config {
    cors {
      allowed_origins = ["https://${azurerm_linux_web_app.frontend.default_hostname}"]
    }
  }
}

# Frontend references api.default_hostname in app_settings
resource "azurerm_linux_web_app" "frontend" {
  app_settings = {
    API_URL = "https://${azurerm_linux_web_app.api.default_hostname}"
  }
}
```

### Fix Strategies

**Option A (recommended):** Use a Terraform variable for the frontend origin so CORS is restrictive by default and the cycle is broken. Define the variable with a sensible default and pass the real frontend URL after the first deployment:

```hcl
variable "frontend_origin" {
  type        = string
  description = "Frontend origin for API CORS. Set after first deployment."
  default     = ""
}

resource "azurerm_linux_web_app" "api" {
  site_config {
    cors {
      allowed_origins     = var.frontend_origin != "" ? [var.frontend_origin] : ["*"]
      support_credentials = var.frontend_origin != "" ? true : false
    }
  }
}
```

> ⚠️ **Warning:** If using `["*"]` as a temporary bootstrap value, you **must** set `frontend_origin` to the actual URL (e.g., `https://app-web-*.azurewebsites.net`) and re-run `terraform apply` in the same deployment session before reporting success. Do not leave wildcard CORS in a completed deployment.

**Option B:** Use `azurerm_app_service_custom_hostname_binding` or a `null_resource` with a `local-exec` provisioner to configure CORS after both resources are created, breaking the dependency chain.

**Option C:** Use `lifecycle { ignore_changes = [site_config[0].cors] }` on the API resource and configure CORS via a separate `azurerm_web_app_active_slot` or post-deployment script.

### After Fixing

1. Run `terraform fmt -recursive` to fix formatting
2. Re-run `terraform validate` to confirm the cycle is resolved
3. Run `terraform plan` to verify the configuration is correct

## Debug

```bash
TF_LOG=DEBUG terraform plan
```
