terraform block using a backend configuration. This structure is the same regardless of backend choice. (Note: if you are using HCP Terraform you will use a cloud block instead of a backend block; all other backends use backend.)
Key components
- Backend type: where the state is stored (for example:
s3,azurerm,gcs, etc.). - Backend configuration: provider-specific settings that tell Terraform how to access the backend (bucket/container names, region, authentication).
- State locking: optional but strongly recommended to prevent concurrent operations and state corruption.
- Backend configuration must be placed in the top-level
terraformblock — not inside aproviderblock. - After adding or changing backend configuration run
terraform initso Terraform can reinitialize the backend and, if necessary, migrate existing state to the configured remote location. See the Terraform init docs.
terraform init -backend-config="bucket=prd-terraform-state"- Or use
-backend-config=path/to/backend.hclto keep secrets out of VCS.
bucket: the S3 bucket where Terraform stores the state file. Create this beforehand or manage it outside the same Terraform run.key: path/file name inside the bucket for your state (e.g.,prod/terraform.tfstatehelps organize multiple environments).region: AWS region for the bucket.encrypt: enable server-side encryption for the state object.dynamodb_table: used to enable state locking with S3 by pointing to a DynamoDB table. Check the official docs for supported locking behavior for your Terraform and provider versions: https://developer.hashicorp.com/terraform/language/settings/backends/s3
storage_account_name: the Azure Storage account containing the blob container.container_name: the blob container (similar in concept to an S3 bucket).key: the blob name/file used to store the state.- Authentication: prefer managed identities, environment variables, or service principals passed securely (not hard-coded credentials inside the backend block).
Do not hard-code authentication credentials in backend configuration. Use managed identities, environment variables, or other secure auth mechanisms in production.
Always run
terraform init after changing backend configuration. Terraform will prompt to migrate state if needed — do not skip this step when moving state between backends.- No easy team collaboration (single-user file on a machine)
- No automatic state locking
- Plain-text state file stored locally (security risk)
- No centralized backups/versioning across a team
- Centralized shared storage (single source of truth)
- State locking to prevent concurrent changes
- Better access control and security posture
- Automated versioning/backups depending on backend features
| Use case | Local state | Remote state |
|---|---|---|
| Solo experiments / learning | ✅ Simple, zero setup | ⚠️ Overkill |
| Team collaboration | ❌ Not recommended | ✅ Single source of truth |
| State locking | ❌ No | ✅ DynamoDB / backend-provided |
| Secure access & auditing | ❌ Limited | ✅ IAM, RBAC, logging |
| Backups & versioning | ❌ Manual | ✅ Backend features (S3 versioning, Azure storage) |
- Use local state only for learning and experimentation.
- Use remote state with locking for team projects and production.
- Keep backend configuration in the top-level
terraformblock. - Run
terraform initafter adding or modifying backends to initialize and migrate state if necessary. See terraform init. - Avoid hard-coding credentials; prefer managed identities, service principals via environment variables, or other secure methods.
- Use separate state files (different
key/ path) per environment (prod, staging, dev) to avoid accidental cross-environment changes.

- Learning, demos, or lone tinkering: local state is sufficient.
- Any professional, team, or production scenario: use remote state with locking and secure authentication.
- Terraform init docs: https://developer.hashicorp.com/terraform/cli/commands/init
- S3 backend docs: https://developer.hashicorp.com/terraform/language/settings/backends/s3
- Azure backend docs: https://developer.hashicorp.com/terraform/language/settings/backends/azurerm
- HCP Terraform Cloud: https://developer.hashicorp.com/terraform/cloud