| slug | azure-blob-terraform-state-support | |
|---|---|---|
| title | Azure Blob Storage Support for !terraform.state Function | |
| sidebar_label | Azure Blob Storage for !terraform.state | |
| authors |
|
|
| tags |
|
|
| date | 2025-10-21 00:00:00 UTC | |
| release | v1.196.0 |
Atmos now supports Azure Blob Storage backends in the !terraform.state YAML function. Read Terraform outputs directly from Azure-backed state files without initializing Terraform—bringing the same blazing-fast performance to Azure that S3 users already enjoy.
The !terraform.state YAML function now supports Azure Blob Storage (azurerm) backends, joining existing support for S3 and local backends. This means you can retrieve Terraform outputs from Azure-backed state files at lightning speed—without the overhead of Terraform initialization.
Before this feature, if you were using Azure Blob Storage as your Terraform backend, you had two options for reading remote state:
!terraform.output- Slow but reliable. Requires full Terraform initialization, provider downloads, and varfile generation.!store- Fast but requires extra setup. You had to manually configure external secret stores.
Now you can use !terraform.state with Azure backends—getting 10-100x faster performance compared to !terraform.output by reading directly from blob storage.
Configure your Terraform component with an azurerm backend:
components:
terraform:
vpc:
backend_type: azurerm
backend:
azurerm:
storage_account_name: "mystorageaccount"
container_name: "tfstate"
key: "vpc.terraform.tfstate"Use the !terraform.state function to read outputs:
components:
terraform:
eks-cluster:
vars:
# Get vpc_id output from vpc component in current stack
vpc_id: !terraform.state vpc vpc_id
# Get private subnet IDs
subnet_ids: !terraform.state vpc private_subnet_ids
# Get first subnet using YQ expression
subnet_id: !terraform.state vpc .private_subnet_ids[0]Reference components from different stacks:
components:
terraform:
tgw:
vars:
# Get VPC ID from production stack
vpc_id: !terraform.state vpc plat-ue2-prod vpc_id
# Use template for dynamic stack names
vpc_id: !terraform.state vpc {{ printf "net-%s-%s" .vars.environment .vars.stage }} vpc_idThe Azure Blob Storage integration uses Azure DefaultAzureCredential, which supports multiple authentication methods automatically:
- Environment variables -
AZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_CLIENT_SECRET - Managed Identity - When running in Azure (AKS, VMs, Functions)
- Azure CLI credentials -
az login - Visual Studio Code credentials - Authenticated VS Code sessions
No additional configuration needed—just authenticate using your preferred method.
Azure Blob Storage uses a specific naming convention for workspaces:
- Default workspace: Uses the key as-is (e.g.,
terraform.tfstate) - Non-default workspaces: Appends workspace as suffix (e.g.,
terraform.tfstateenv:dev)
Atmos handles this automatically—you don't need to worry about the naming convention.
If you have:
- Key:
apimanagement.terraform.tfstate - Workspace:
dev-wus3-apimanagement-be
Atmos will look for: apimanagement.terraform.tfstateenv:dev-wus3-apimanagement-be
$ time atmos terraform plan eks-cluster -s plat-ue2-dev
# Must initialize Terraform for each dependency
Initializing vpc component...
Downloading providers...
Generating backend config...
Generating varfiles...
Reading outputs...
real 2m34.521s$ time atmos terraform plan eks-cluster -s plat-ue2-dev
# Direct blob storage access
Reading state from Azure Blob Storage...
real 0m3.142s~50x faster in this example—and the speedup grows with infrastructure complexity.
Use YQ expressions for complex data extraction:
vars:
# Get nested map values
db_endpoint: !terraform.state database .config_map.endpoint
# String concatenation
jdbc_url: !terraform.state postgres ".master_hostname | \"jdbc:postgresql://\" + . + \":5432/events\""
# Default values for unprovisioned components
username: !terraform.state config ".username // \"default-user\""Results are cached in memory per CLI execution:
vars:
# All three calls use the same cached result
sg_id_1: !terraform.state vpc security_group_id
sg_id_2: !terraform.state vpc security_group_id
sg_id_3: !terraform.state vpc {{ .stack }} security_group_idThe first call reads from Azure; subsequent calls return cached data instantly.
- Blob not found (404): Returns
null(component not provisioned yet) - Permission denied (403): Returns clear error message
- Network errors: Automatically retries up to 2 times with exponential backoff
- Azure SDK for Go - Uses official
github.com/Azure/azure-sdk-for-go/sdk/storage/azblobpackage - Client caching - Azure Blob clients are cached per storage account/container
- Retry logic - Automatic retry with exponential backoff for transient failures
- Nil safety - Robust error handling prevents panics
- Test coverage - Comprehensive unit tests with mocked Azure SDK
- Cross-platform - Works on Linux, macOS, and Windows
All standard Azure backend options are supported:
backend:
azurerm:
storage_account_name: "mystorageaccount" # Required
container_name: "tfstate" # Required
key: "terraform.tfstate" # Optional (default: terraform.tfstate)
# Authentication happens via DefaultAzureCredentialThe syntax is identical—just replace !terraform.output with !terraform.state:
# Before
vpc_id: !terraform.output vpc vpc_id
# After
vpc_id: !terraform.state vpc vpc_idSimplify your configuration by removing store setup:
# Before: Required store configuration
vpc_id: !store azurekeyvault plat-ue2-dev vpc vpc_id
# After: Direct state access
vpc_id: !terraform.state vpc vpc_idcomponents:
terraform:
app:
vars:
# String output
security_group_id: !terraform.state security-group id
# List output
subnet_ids: !terraform.state vpc private_subnet_ids
# Map output
config: !terraform.state config config_mapcomponents:
terraform:
replication:
vars:
# Reference component from different region
primary_db: !terraform.state database {{ printf "%s-use1-%s" .vars.tenant .vars.stage }} endpointcomponents:
terraform:
failover:
vars:
# Primary region
primary_vpc: !terraform.state vpc plat-ue2-prod vpc_id
# DR region with default fallback
dr_vpc: !terraform.state vpc plat-uw2-prod ".vpc_id // \"vpc-mock-dr\""- Secrets exposure: Using
!terraform.statewith secrets will expose them inatmos describeoutput - Permission scoping: Ensure your Azure credentials have access to all referenced storage accounts
- Cross-region access: Consider latency when reading state across regions
- Cold starts: Components not yet provisioned return
null(use YQ default values to handle this)
Upgrade to the latest Atmos release and start using Azure Blob Storage backends:
# Check your version
atmos version
# Describe a component using Azure backend
atmos describe component vpc -s plat-ue2-dev
# Use !terraform.state in your stack configs
# (See examples above)- !terraform.state Function Reference - Complete usage documentation
- Terraform Backends - Backend configuration guide
- Remote State - Data sharing patterns
We're building Atmos in the open and welcome your feedback:
- 💬 Discuss - Share thoughts in GitHub Discussions.
- 🐛 Report Issues - Found a bug? Open an issue.
- 🚀 Contribute - Want to add features? Review our contribution guide.
Next up: Google Cloud Storage (GCS) backend support for !terraform.state. Stay tuned!