By default, there is one state file (terraform.tfstate) per configuration directory. Sometimes, we want to reuse the same configuration files for multiple projects. Instead of creating a directory for each project and copy-pasting files, we can use Terraform's feature called workspaces. Each workspace has its own, isolate state. When in particular workspace, terraform plan can see only its state.
When we create a configuration file, before explicitly creating any workspaces, Terraform implicitly creates a workspace named default:
$ terraform console
> terraform.workspace
default
In a new project, at this point, if we use s3 bucket for state backend, the state file will be in the root directory of the bucket.
To create a workspace:
$ terraform workspace new ProjectA
or, if we use workspaces to manage multiple environments:
% terraform workspace new prod
Created and switched to workspace "prod"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state for this configuration.
After this, if we use s3 bucket for state backend, we'll see that state file is now in the s3 bucket at path env:/prod/apps/my_app/terraform.tfstate.
Our prod.s3.tfbackend might look like this:
bucket = "terraform-states"
key = "apps/my_app/terraform.tfstate"
region = "us-east-1"
profile = "local_aws_profile"
Q: If we create a new workspace e.g. staging, we can see that in s3 state backend bucket a new .tfstate file is created in env:/staging/ path. Do we locally need to execute terraform init again?
A: No - terraform init is tied to the backend configuration, not the workspace. Since staging uses the same S3 bucket/region/profile as prod, you don't need to re-init.
terraform workspace new staging (or select staging) is sufficient - Terraform automatically uses the new state path in the existing backend. You only need to re-run init if you change the backend config itself (different bucket, region, etc.) or add/update providers/modules.
To list all workspaces:
$ terraform workspace list
default
* ProjectA
ProjectB
Asterisk indicates the currently active workspace.
To switch to another workspace we need to use select command:
$ terraform workspace select default
Switched to workspace "default".
$ terraform workspace select ProjectB
Switched to workspace "ProjectB".
terraform.workspace variable contains the name of the current workspace and it can be used in configuration files:
variables.tf:
variable region {
default = "eu-west-1"
}
variable instance_type {
default = "t2.micro"
}
variable ami {
type = map
default = {
"ProjectA" = "ami-0123456789"
"ProjectB" = "ami-9876543210"
}
}
main.tf:
resource "aws_instance" "my-server" {
ami = lookup(var.ami, terraform.workspace)
instance_type = var.instance_type
tags = {
Name = "terraform.workspace"
}
}
Terraform creates one state file for each workspace. They are stored in a directory named terraform.tfstate.d:
$ tree terraform.tfstate.d/
terraform.tfstate.d/
|--ProjectA
| `-- terraform.tfstate
`--ProjectB
`-- terraform.tfstate
---
No comments:
Post a Comment