This project uses different Azure Storage Accounts for different environments. Multiple Storage Accounts serve as security boundaries. Per best practice production resources require elevated privileges, i.e. different credentials.
This assumes you already have an Azure Storage Account.
-
Create configuration files by copying backend.hcl.sample and renaming to:
dev.backend.hcl
staging.backend.hcl
production.backend.hcl
-
Add azurerm backend configuration for each file, for example:
storage_account_name = "storageaccountname"
container_name = "aks-clusters"
key = "dev.cluster.tfstate"
use_azuread_auth = true # option 1 (preferred)
sas_token = "?se=…" # option 2
When you initialize the terraform project, point it to the corresponding state file, for example:
terraform init -backend-config=backends/dev.backend.hcl
When we switch between clusters, we need to update the terraform configuration. For example, if we are changing to staging
.
First point to the staging backend configuration and -reconfigure
the backend:
terraform init -backend-config=backends/staging.backend.hcl -reconfigure
Then use -var-file
for terraform commands to pass staging specific configuration, e.g. getting current state:
terraform refresh -var-file=environments/staging/staging.cluster.tfvars
More details about this "real life" setup.
Can I use different Shared Access Signatures (SAS) tokens for different state files in a single Storage Account?
Technically that would work. But then you lose the security boundary because the terraform workspace
command looks for state files in your account and thus needs permissions scoped the account. An attacker would only need your non-production SAS token to find and access the production state file.
Terraform State has a built in "workspace" feature that lets you toggle between states. But per Terraform documentation, workspaces are not meant for targeting different environments:
In particular, organizations commonly want to create a strong separation between multiple deployments of the same infrastructure serving different development stages (e.g. staging vs. production) or different internal teams. In this case, the backend used for each deployment often belongs to that deployment, with different credentials and access controls. Named workspaces are not a suitable isolation mechanism for this scenario.
Emphasis added. Please be aware workspace here refers to Terraform State, not Terraform Cloud, which is a completely different feature… with the same name 🤷♀️