Get organized with Terraform Workspaces
Updated: Jul 15
As we know, when we deploy Infrastructure, it’s prevalent that we need many and different environments, like development, testing, staging, or production.
Terraform allows us to write a scalable and sustainable infrastructure in those different environments.
The need that arises with this is, How can I reuse my code efficiently? There are many ways to accomplish this, but today we are going to focus on Terraform Workspaces.
One of the best advantages that we can achieve using Workspaces is handling the state files independently. This file represents a “photo” of our infrastructure and Terraform uses it to detect what resource will change or delete in an execution. By default, Terraform has one workspace called default. It’s probably that if you don’t
know about workspaces, you have always worked with them. When we explore this command and their sub-commands, we found:
• terraform workspace new <WORKSPACE_NAME> Create a new workspace
• terraform workspace select <WORKSPACE_NAME> Select a workspace
• terraform workspace list List available workspaces
• terraform workspace show Show the current workspace
• terraform workspace delete <WORKSPACE_NAME> Delete a workspace
States files separate
When a workspace is created and settings are applied, terraform creates a directory called terraform.tfstate.d and in it a subdirectory for each environment containing the respective tfstate file.
*As a note, remember always save the tfstae file in a backend S3 bucket and block it through the use of DynamoBD tables.
What about the Code reuse?
Regarding to this, we can use conditional structure to create different types and amounts of infrastructure using the same code.
condition ? true_val : false_val
This can be applied as follows, using the count attribute:
resource "aws_eip" "example" {
count = "${var.create_eip ? 1 : 0}"
instance = "aws_instance.example.id"
}
As you can see, the resource “aws_eip” only will be created if the boolean value assigned to “var.create_eip” is set to true (1).
Although Terraform doesn’t support IF statements, this is a very simple way to handle it and shows how to using the count attribute allows us to create a dynamic configuration.
Also, we can define different types of “variable files” as input for the different environments.
terraform plan -var-file="prod.tfvars”
terraform apply -var-file="prod.tfvars”
An example of .tfvars is define variables only used in one of those environments, as the following:
instance_type = "t3.large"
ami = "ami-09d3b3274b6c5d4aa"
cidr_vpc = "10.0.0.0/16"
We can conclude that this is a great way to reuse the infrastructure code, separating their respective state files and accomplishing one of the AWS Well-Architected Framework Pillars, Operational Excellence🙌.
Bonus track
In some cases, maybe you don't want to work with the default workspace. To achieve this, we can trick terraform by defining an environment variable like so:
environment = terraform.workspace == "default" ? "name_main_environment" : terraform.workspace
As you can see, the variable environment takes the value of your main environment (e.g production), if the terraform. workspace is equal to the default value. Otherwise, the value of the environment will be the name of the workspace that you have selected.
Martín Carletti
DevOps
Teracloud
If you want to know more about Terraform, we suggest checking out Importing resources from the Gcloud to IaaC in Terraform. If you want to learn more about our #TeraTips or our blog's content, we invite you to check out more of the blog entries that we created to help you navigate your Cloud journey.