Terraform Backend Configuration
The backend section under terraform: or components.terraform.<name>: configures
where Terraform stores state for your components. Settings defined here become defaults
for all Terraform components in the stack.
backend: with provision.backend:The backend: block on this page describes where state is stored (bucket, region, key).
The separate provision.backend: block tells Atmos to automatically create that location
if it doesn't exist. See Backend Provisioning.
Setting Defaults for Terraform Components
When you define backend configuration under the terraform: section, it applies to
all Terraform components in that stack manifest:
terraform:
backend_type: s3
backend:
s3:
bucket: acme-ue1-root-tfstate
region: us-east-1
encrypt: true
use_lockfile: true
Every Terraform component that imports this manifest inherits these backend settings. Individual components can override specific values as needed.
Component-Level Overrides
Override backend settings for a specific component:
components:
terraform:
vpc:
# Inherits org defaults, overrides key prefix
backend:
s3:
workspace_key_prefix: networking/vpc
secrets-manager:
# Uses a separate, more restricted bucket
backend:
s3:
bucket: acme-ue1-prod-secrets-tfstate
kms_key_id: alias/secrets-state-key
Backend Types
Atmos supports all Terraform backend types. Configure using backend_type and the corresponding configuration under backend.
S3 Backend
The most common backend for AWS environments. We recommend using use_lockfile: true for native S3 state locking (Terraform 1.10+, OpenTofu 1.8+) instead of DynamoDB:
- Stack Configuration
- Generated File
terraform:
backend_type: s3
backend:
s3:
bucket: acme-ue1-root-tfstate
region: us-east-1
key: "{{ .environment }}/{{ .stage }}/{{ .component }}/terraform.tfstate"
encrypt: true
use_lockfile: true # Native S3 locking (Terraform 1.10+)
{
"terraform": {
"backend": {
"s3": {
"bucket": "acme-ue1-root-tfstate",
"region": "us-east-1",
"key": "ue1/prod/vpc/terraform.tfstate",
"encrypt": true,
"use_lockfile": true
}
}
}
}
S3 Backend with Assume Role
For cross-account access, configure the backend to assume a role:
- Stack Configuration
- Generated File
terraform:
backend_type: s3
backend:
s3:
bucket: acme-ue1-root-tfstate
region: us-east-1
key: "{{ .environment }}/{{ .stage }}/{{ .component }}/terraform.tfstate"
encrypt: true
use_lockfile: true
assume_role:
role_arn: "arn:aws:iam::{{ .vars.state_account_id }}:role/TerraformStateAccess"
session_name: "atmos-{{ .component }}"
{
"terraform": {
"backend": {
"s3": {
"bucket": "acme-ue1-root-tfstate",
"region": "us-east-1",
"key": "ue1/prod/vpc/terraform.tfstate",
"encrypt": true,
"use_lockfile": true,
"assume_role": {
"role_arn": "arn:aws:iam::123456789012:role/TerraformStateAccess",
"session_name": "atmos-vpc"
}
}
}
}
}
S3 Backend with SSE-C Encryption
For state files encrypted with SSE-C (Server-Side Encryption with Customer-Provided Keys),
provide the customer key so that !terraform.state can decrypt state when reading directly from S3:
terraform:
backend_type: s3
backend:
s3:
bucket: acme-ue1-root-tfstate
region: us-east-1
key: "{{ .environment }}/{{ .stage }}/{{ .component }}/terraform.tfstate"
encrypt: true
use_lockfile: true
sse_customer_key: "base64-encoded-32-byte-key"
The sse_customer_key must be a base64-encoded 256-bit (32-byte) key. It can also be provided via the AWS_SSE_CUSTOMER_KEY
environment variable. The backend attribute takes precedence over the environment variable.
The sse_customer_key attribute is used by Atmos when reading state directly via !terraform.state.
Terraform/OpenTofu handles SSE-C independently through its own backend configuration.
S3 Backend with DynamoDB Locking (Legacy)
For Terraform versions before 1.10, use DynamoDB for state locking:
terraform:
backend_type: s3
backend:
s3:
bucket: acme-ue1-root-tfstate
region: us-east-1
key: "{{ .environment }}/{{ .stage }}/{{ .component }}/terraform.tfstate"
dynamodb_table: acme-ue1-root-tfstate-lock
encrypt: true
Azure Blob Backend
For Azure environments:
- Stack Configuration
- Generated File
terraform:
backend_type: azurerm
backend:
azurerm:
resource_group_name: terraform-state-rg
storage_account_name: tfstateaccount
container_name: tfstate
key: "{{ .environment }}/{{ .stage }}/{{ .component }}/terraform.tfstate"
{
"terraform": {
"backend": {
"azurerm": {
"resource_group_name": "terraform-state-rg",
"storage_account_name": "tfstateaccount",
"container_name": "tfstate",
"key": "ue1/prod/vpc/terraform.tfstate"
}
}
}
}
GCS Backend
For Google Cloud environments:
- Stack Configuration
- Generated File
terraform:
backend_type: gcs
backend:
gcs:
bucket: acme-terraform-state
prefix: "{{ .environment }}/{{ .stage }}/{{ .component }}"
{
"terraform": {
"backend": {
"gcs": {
"bucket": "acme-terraform-state",
"prefix": "ue1/prod/vpc"
}
}
}
}
Terraform Cloud / Enterprise
For Terraform Cloud or Enterprise:
- Stack Configuration
- Generated File
terraform:
backend_type: remote
backend:
remote:
hostname: app.terraform.io
organization: acme
workspaces:
name: "{{ .namespace }}-{{ .environment }}-{{ .stage }}-{{ .component }}"
Or using the newer cloud backend:
terraform:
backend_type: cloud
backend:
cloud:
organization: acme
workspaces:
name: "{{ .namespace }}-{{ .environment }}-{{ .stage }}-{{ .component }}"
{
"terraform": {
"backend": {
"remote": {
"hostname": "app.terraform.io",
"organization": "acme",
"workspaces": {
"name": "acme-ue1-prod-vpc"
}
}
}
}
}
Local Backend
For development or single-user scenarios:
- Stack Configuration
- Generated File
terraform:
backend_type: local
backend:
local:
path: "{{ .component }}/terraform.tfstate"
{
"terraform": {
"backend": {
"local": {
"path": "vpc/terraform.tfstate"
}
}
}
}
Remote State Backend
The remote_state_backend configuration is separate from backend and controls how other components can read this component's state:
terraform:
# Where this component stores its state
backend_type: s3
backend:
s3:
bucket: acme-ue1-root-tfstate
region: us-east-1
# How other components read this component's state
remote_state_backend_type: s3
remote_state_backend:
s3:
bucket: acme-ue1-root-tfstate
region: us-east-1
This separation allows for scenarios like:
- Using Terraform Cloud for operations but S3 for remote state access
- Different credentials for writing vs. reading state
- Custom remote state configurations
Backend Provisioning
Atmos can automatically provision S3 backend infrastructure before running Terraform commands, solving the bootstrap problem of "how do I create state storage before I can use Terraform?"
Enable Automatic Provisioning
terraform:
backend_type: s3
backend:
s3:
bucket: acme-ue1-dev-tfstate
region: us-east-1
use_lockfile: true
provision:
backend:
enabled: true # Automatically create backend if it doesn't exist
When provision.backend.enabled is true, Atmos will:
- Check if the backend exists before running Terraform
- Create it with secure defaults (versioning, encryption, public access blocked)
- Proceed with normal Terraform operations
See Backend Provisioning for complete documentation.
Examples
Environment-Specific State Buckets
Dynamic State Keys with Templates
Component-Specific Backend Override
Multi-Cloud Configuration
Workspace Configuration
For backends that support workspaces, you can configure workspace patterns:
terraform:
backend_type: remote
backend:
remote:
organization: acme
workspaces:
prefix: "acme-"
components:
terraform:
vpc:
terraform_workspace: "{{ .environment }}-{{ .stage }}-vpc"
See Terraform Workspaces for detailed workspace configuration.
Best Practices
-
Use Remote State: Always use a remote backend for team environments to enable collaboration and state locking.
-
Enable Encryption: Always enable encryption for backends that support it (S3, Azure Blob, GCS).
-
Configure State Locking: Use
use_lockfile: truefor S3 (Terraform 1.10+), blob leases for Azure, or built-in locking for other backends. -
Organize State Keys: Use a consistent key structure that includes environment, stage, and component information.
-
Separate Sensitive State: Consider using separate state buckets or additional encryption for components managing secrets.
-
Use Templates: Leverage Go templates for dynamic backend configuration based on context variables.
Related
- Generate Terraform Backend - Stack-level backend configuration
- Terraform Backends - Conceptual overview
- Backend Provisioning - Automatic backend creation
- Remote State - Reading state from other components
- Terraform Workspaces