## TL;DR

Backend blocks cannot use variables. Terraform configures the backend before it evaluates any `variable` blocks, so `var.*`, `local.*`, and resource references are all rejected there. Move the values out: use `-backend-config` flags or a backend config file, and keep the backend block to static keys or an empty stub.

## The error

```text
Error: Variables not allowed

  on backend.tf line 3, in terraform:
   3:     bucket = var.state_bucket

Variables may not be used here.
```

## Steps to fix

1. Remove every `var.`/`local.`/resource reference from the `backend` block. Leave static values or an empty block:
   ```hcl
   terraform {
     backend "s3" {}
   }
   ```
   - Expected: no variable references remain in the backend block.
2. Supply the values at init time instead:
   ```bash
   terraform init -backend-config="bucket=my-state-bucket" -backend-config="key [your value] -backend-config="region=us-east-1"
   ```
   or keep them in a file: `terraform init -backend-config=backend-prod.hcl`.
   - Expected: init configures the backend from the flags/file.
3. Re-run `terraform init`.
   - Expected: backend initializes without the variables error.

## When to use this

- `terraform init` fails with `Variables not allowed` / `Variables may not be used here` pointing at a `backend` block.

## When NOT to use this

- Variables are fine in `provider` blocks and everywhere else; this restriction is backend-only. `terraform_remote_state` data sources can use variables in their `config`.

## Compatibility

- All Terraform versions; backend evaluation order is fundamental and unchanged.

## Root cause

The backend must be configured before Terraform can read state, and state may be needed to evaluate variables. To avoid the chicken-and-egg problem, backend configuration accepts only literal values, environment variables (for some backends), and `-backend-config` inputs.

## Edge cases

- Partial backend configuration (empty `backend "s3" {}`) still requires every required argument via `-backend-config`; missing ones prompt interactively and fail in CI.
- Some backends read credentials from environment variables (e.g. AWS_*); those are allowed and often cleaner than flags.
- Changing backend config values later requires `terraform init -reconfigure`.