atmos terraform backend
Use these commands to manage Terraform state backend infrastructure. This solves the Terraform bootstrap problem by automatically provisioning backend storage with secure defaults, making it compatible with any Terraform-managed backend.
Usageβ
atmos terraform backend <subcommand> [options]
Available Subcommandsβ
create <component>- Provision backend infrastructure for a component
list- List all backends in a stack
describe <component>- Show backend configuration from stack
update <component>- Update backend configuration (idempotent)
delete <component>- Delete backend infrastructure (requires --force)
Creating Backendsβ
Provision backend infrastructure for a component in a specific stack:
atmos terraform backend create <component> --stack <stack>
The backend must have provision.backend.enabled: true in its stack configuration.
Examplesβ
Create Backendβ
Provision an S3 bucket with secure defaults:
atmos terraform backend create vpc --stack dev
This creates an S3 bucket (if it doesn't exist) with:
- Versioning enabled
- AES-256 encryption
- Public access blocked
- Resource tags applied
List Backendsβ
Show all backend configurations in a stack:
atmos terraform backend list --stack dev
Describe Backend Configurationβ
View a component's backend configuration from the stack:
atmos terraform backend describe vpc --stack dev
atmos terraform backend describe vpc --stack dev --format json
Update Backendβ
Apply configuration changes to existing backend (idempotent):
atmos terraform backend update vpc --stack dev
Delete Backendβ
Remove backend infrastructure (requires --force for safety):
atmos terraform backend delete vpc --stack dev --force
Provision Multiple Backendsβ
atmos terraform backend create vpc --stack dev
atmos terraform backend create eks --stack dev
atmos terraform backend create rds --stack dev
Argumentsβ
component- The Atmos component name (required for create, describe, update, delete)
Flagsβ
--stack/-s- Atmos stack name (required). Can also be set via
ATMOS_STACKenvironment variable --identity/-i- Identity to use for authentication. Overrides component's default identity. Use without value to select interactively
--format/-f- Output format for list and describe commands:
table,yaml,json(default: varies by command) --force- Force deletion without confirmation (delete command only)
Authenticationβ
Backend commands support both global and component-level authentication, consistent with regular Terraform commands.
Component-Level Identityβ
Components can specify their own authentication identity with a default:
# stacks/dev.yaml
components:
terraform:
vpc:
# Component-level auth configuration
auth:
identities:
vpc-deployer:
default: true # Used automatically for this component
kind: aws/permission-set
via:
provider: aws-sso
principal:
name: "NetworkAdmin"
account:
name: "network-dev"
With this configuration, backend commands automatically use the vpc-deployer identity:
# Automatically uses vpc-deployer identity
atmos terraform backend create vpc --stack dev
atmos terraform backend delete vpc --stack dev --force
Identity Flag Overrideβ
The --identity flag overrides the component's default identity:
# Override component default with admin identity
atmos terraform backend create vpc --stack dev --identity admin
Global Identityβ
Without component-level auth, backend commands use global auth configuration from atmos.yaml or the --identity flag.
See Authentication and Identity for complete auth configuration details.
How It Worksβ
Manual Provisioningβ
When you run atmos terraform backend create:
- Load Configuration - Atmos loads the component's stack configuration
- Check Provisioning - Verifies
provision.backend.enabled: trueis set - Select Provisioner - Chooses provisioner based on
backend_type(s3, gcs, azurerm) - Check Existence - Verifies if backend already exists (idempotent)
- Provision - Creates backend with hardcoded security defaults if needed
- Apply Settings - Configures versioning, encryption, access controls, and tags
Automatic Provisioningβ
Backends are also provisioned automatically when running Terraform commands if provision.backend.enabled: true:
# Backend provisioned automatically before terraform init
atmos terraform plan vpc --stack dev
atmos terraform apply vpc --stack dev
The automatic flow:
Auth Setup (TerraformPreHook)
β
Backend Provisioning (if enabled)
β
Terraform Init
β
Terraform Command
Solving the Terraform Bootstrap Problemβ
Terraform has a chicken-and-egg problem: you need infrastructure to store state, but you need state to manage infrastructure. Atmos solves this by:
- Automatic Detection - Reads backend configuration from stack manifests
- Secure Defaults - Creates backend with hardcoded security settings
- Idempotent Operations - Safe to run multiple times
- Terraform Compatible - Works with any Terraform-managed backend
This eliminates manual backend setup and makes Terraform backends work like any other infrastructure resource.
Configurationβ
Enable backend provisioning in your stack manifest:
# stacks/dev.yaml
components:
terraform:
vpc:
backend_type: s3 # Must be at component level
backend:
bucket: acme-ue1-dev-tfstate
key: vpc/terraform.tfstate
region: us-east-1
use_lockfile: true # Enable native S3 locking (Terraform 1.10+)
provision:
backend:
enabled: true # Enable automatic provisioning
Configuration Hierarchyβ
The provision.backend configuration supports Atmos's deep-merge system and can be specified at multiple levels in the stack hierarchy. This provides flexibility to set defaults at high levels and override at component level.
Global Default (Organization-Level)β
Enable provisioning for all components in an organization:
# stacks/orgs/acme/_defaults.yaml
terraform:
provision:
backend:
enabled: true
All components in this organization will inherit provision.backend.enabled: true unless explicitly overridden.
Environment-Level Configurationβ
Set different provisioning policies per environment:
# stacks/orgs/acme/plat/dev/_defaults.yaml
terraform:
provision:
backend:
enabled: true # Auto-provision in dev
# stacks/orgs/acme/plat/prod/_defaults.yaml
terraform:
provision:
backend:
enabled: false # Pre-provisioned backends in prod
Component Inheritanceβ
Use metadata.inherits to share provision configuration:
# stacks/catalog/vpc/defaults.yaml
components:
terraform:
vpc/defaults:
provision:
backend:
enabled: true
# stacks/dev.yaml
components:
terraform:
vpc:
metadata:
inherits: [vpc/defaults]
# Inherits provision.backend.enabled: true
Component-Level Overrideβ
Override inherited settings per component:
components:
terraform:
vpc:
provision:
backend:
enabled: false # Disable for this specific component
Deep-Merge Behavior: Atmos combines configurations from all levels, giving you maximum flexibility:
- Set defaults at organization or environment level
- Override per component when needed
- Use catalog inheritance for reusable patterns
- Component-level configuration has highest precedence
Supported Backend Typesβ
S3 (AWS)β
Hardcoded Defaults:
- Versioning: Enabled
- Encryption: AES-256 (AWS-managed keys)
- Public Access: Blocked (all 4 settings)
- Locking: Native S3 locking (Terraform 1.10+)
- Tags:
Name,ManagedBy=Atmos
Required Configuration:
backend_type: s3 # Must be at component level
backend:
bucket: my-terraform-state # Required
key: component/terraform.tfstate
region: us-east-1 # Required
use_lockfile: true # Enable native S3 locking (Terraform 1.10+)
Cross-Account Support:
backend:
bucket: my-terraform-state
region: us-east-1
use_lockfile: true # Enable native S3 locking (Terraform 1.10+)
assume_role:
role_arn: arn:aws:iam::999999999999:role/TerraformStateAdmin
The provisioner assumes the role to create the bucket in the target account.
Error Handlingβ
Exit Codesβ
| Exit Code | Error Type | Action |
|---|---|---|
| 0 | Success | Backend created or already exists |
| 1 | General error | Check error message for details |
| 2 | Configuration error | Fix provision.backend configuration |
| 3 | Permission error | Grant required IAM permissions |
| 4 | Resource conflict | Change bucket name (globally unique) |
| 5 | Network error | Check network connectivity to cloud provider |
Example Errorsβ
Missing Configuration:
Error: backend.bucket is required in backend configuration
Hint: Add bucket name to stack manifest
Example:
backend:
bucket: my-terraform-state
region: us-east-1
Permission Denied:
Error: failed to create bucket: AccessDenied
Hint: Verify AWS credentials have s3:CreateBucket permission
Required IAM permissions:
- s3:CreateBucket
- s3:HeadBucket
- s3:PutBucketVersioning
- s3:PutBucketEncryption
- s3:PutBucketPublicAccessBlock
- s3:PutBucketTagging
Bucket Name Conflict:
Error: failed to create bucket: BucketAlreadyExists
Hint: S3 bucket names are globally unique across all AWS accounts
Try a different bucket name:
- acme-ue1-dev-tfstate-123456789012 (add account ID)
- acme-ue1-dev-tfstate-randomsuffix (add random suffix)
Required IAM Permissionsβ
S3 Backendβ
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:HeadBucket",
"s3:PutBucketVersioning",
"s3:PutBucketEncryption",
"s3:PutBucketPublicAccessBlock",
"s3:PutBucketTagging"
],
"Resource": "arn:aws:s3:::my-terraform-state*"
}
]
}
For cross-account provisioning, also add:
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::999999999999:role/TerraformStateAdmin"
}
Migrating to Terraform-Managed Backendsβ
Once your backend is provisioned, you can import it into Terraform for advanced management:
Step 1: Provision the Backendβ
Use Atmos to create the backend with secure defaults:
atmos terraform backend create vpc --stack prod
Step 2: Import into Terraformβ
Add the backend to your Terraform configuration and import it:
# Import the provisioned backend
import {
to = aws_s3_bucket.terraform_state
id = "acme-ue1-prod-tfstate"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "acme-ue1-prod-tfstate"
}
Step 3: Add Advanced Featuresβ
Extend the backend with production-specific features:
# Add lifecycle rules
resource "aws_s3_bucket_lifecycle_configuration" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
rule {
id = "delete-old-versions"
status = "Enabled"
noncurrent_version_expiration {
noncurrent_days = 90
}
}
}
# Add replication
resource "aws_s3_bucket_replication_configuration" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
role = aws_iam_role.replication.arn
rule {
id = "replicate-state"
status = "Enabled"
destination {
bucket = aws_s3_bucket.terraform_state_replica.arn
storage_class = "STANDARD_IA"
}
}
}
Step 4: Disable Automatic Provisioningβ
Once Terraform manages the backend, disable automatic provisioning:
provision:
backend:
enabled: false # Backend now managed by Terraform
See the Automatic Backend Provisioning docs for more migration patterns.
Idempotent Operationsβ
The provision command is idempotentβrunning it multiple times is safe:
$ atmos terraform backend create vpc --stack dev
Running backend provisioner...
Creating S3 bucket 'acme-ue1-dev-tfstate'...
β Successfully provisioned backend
$ atmos terraform backend create vpc --stack dev
Running backend provisioner...
S3 bucket 'acme-ue1-dev-tfstate' already exists (idempotent)
β Backend provisioning completed
Related Commandsβ
atmos terraform init- Initialize Terraform (auto-provisions if enabled)atmos terraform plan- Plan Terraform changes (auto-provisions if enabled)atmos terraform apply- Apply Terraform changes (auto-provisions if enabled)