Here is some information about this architecture.
Here are the steps you can follow to build this solution on your own.
As you have learned in previous lessons, Terraform manages infrastructures using states and state files. By default, you always have just one state file that binds the configurations in your Terraform project with the infrastructure it defines.
When working in an environment with infrastructures that serve users in real-time, there is often a need to test how code behaves before shipping it to a production environment. In such cases, you need to create multiple independent environments with similar infrastructure for testing purposes.
For example, we want to provision similar cloud infrastructure for 2 different environments: development and production, using Terraform.
Normally, you can achieve this by:
Creating 2 different Terraform projects.
Writing a configuration file for each project.
This approach not only wastes time; it also causes unnecessary code repetition. That is where Terraform workspaces come in.
Workspaces are isolated environments in a Terraform project that can be configured using a single file.
When you create a project, Terraform stores the state file in a workspace named "default
," which is the workspace you normally work with.
To achieve the aim of provisioning similar infrastructure for different environments, we can use the alternative approach of using workspaces.
To do that, we will:
Create a terraform project.
Create a single configuration file.
Create multiple workspaces, one for each environment.
Specify the intended workspace when applying the configuration.
This approach saves time and is easier to manage. Since each workspace has its own state file, it provides isolation between the configurations it manages. When you are working in one workspace, you do not have to worry about the changes or configurations in another workspace. That is, we can modify the development environment without tampering with the production environment and vice versa.
The purpose of a workspace is to isolate a state file for multiple environments that are using the same configuration file(s).
It is common practice for organizations to have different environments for developing, testing, and deploying software services. Such environments often contain similar architecture—since the reason for multiple environments is to simulate how the software will behave in a live environment. In such a scenario, the purpose of Terraform workspaces is to allow you to easily create these three independent environments using the same configuration file.
Workspaces are a great way to separate resources by stage and are often used in multiple environments.
If you are using the same architecture for multiple environments, such as dev, staging, and production, you can use workspaces to manage the infrastructure easily.
The separation of resource configuration states is really helpful when managing large deployments. Instead of working with many configuration files in different directories, you can achieve this separation using one configuration file and multiple workspaces.
The lab section in this lesson will give you hands-on experience and a better understanding of workspaces.
The terraform workspace
command provides different parameters that allow you to create, navigate, and manage workspaces. Let’s learn about the different commands that you will use when dealing with workspaces.
The command for creating a new workspace in a Terraform project is terraform workspace new <workspace name>
.
The command below will create a new workspace with the given name. The state of the workspace will be empty—since we do not have any configurations in it yet.
# create the workspace named "dev"
$ terraform workspace new dev
# create the workspace named "uat"
$ terraform workspace new uat
Note: You cannot have two workspaces with the same name.
You can list all existing workspaces in a Terraform project using the following command:
$ terraform workspace list
The command will display a list of all available workspaces—an asterisk (*
) is used to identify the current workspace.
After creating multiple workspaces, if you need to switch to a workspace other than the current one, you can use the following command: terraform workspace select <workspace-name>
.
#assume that we are currently in the dev workspace
$ terraform workspace select uat
The CLI will switch to the uat
workspace.
If you need to know the current workspace that you’re working in, you can use the following command:
$ terraform workspace show
This command will output the current workspace.
The command to delete a workspace is:
$ terraform workspace delete <workspace-name>
There are a few conditions that need to be fulfilled before Terraform can delete a workspace.
You cannot delete your current.
The given workspace must already exist.
The state file of the workspace must be empty.
Let's get some hands-on experience with workspaces. In this lab, you will create multiple Terraform workspaces, navigate through workspaces, and modify each workspace independently. Let's get started!
You will use the same directory and main.tf
file for all the steps in this lab. Create the directory now. Then, create the main.tf
file in the folder and include the following code:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
profile = "default"
region = "us-west-2"
}
If you're using the Skillmix Labs feature, open the lab settings (the beaker icon) on the right side of the code editor. Then, click the Start Lab button to start hte lab environment.
Wait for the credentials to load. Then run this in the terminal.
Be sure to enter in your own access key and secret key and name your profile 'smx-lab'.
$ aws configure --profile smx-lab
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: us-west-2
Default output format [None]:
Note: If you're using your own AWS account you'll need to ensure that you've created and configured a named AWS CLI profile named smx-lab.
You will create three workspaces:
dev
staging, and
production
On your CLI, run the following command, one after the other, to create the three workspaces:
#Create a "dev" workspace
$ terraform workspace new dev
#Create a "staging" workspace
$ terraform workspace new staging
#Create a "production" workspace
$ terraform workspace new production
When you create a new workspace, Terraform automatically switches to the new workspace. After creating the 3 workspaces type:
$ terraform workspace list
You’ll see the list of workspace you now have in your project. Remember, the workspace denoted with an asterisk (*
) is the workspace you're currently working in.
Additionally, you can run terraform show
to specifically view your current workspace.
Notice that as soon as you create the workspace, Terraform creates a new terraform.tfstate.d
folder in the project directory. This folder contains subfolders with the name of your workspaces. The state file for each workspace is stored independently in these folders.
Since the aim of this lab is to experience Terraform workspaces in action, you will create a simple resource, a virtual private network (VPC). Append the code below to you r main.tf
file and save it.
#Store the name of the workspace in a local
locals {
vpc_name = "${terraform.workspace}-vpc"
}
#Create the VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "local.vpc_name"
}
}
Code Review
The locals
block allows you to tap into the name of the workspace that provisions the instance, thereby allowing you to differentiate between each environment by denoting the name as dev-vpc
, staging-vpc
, or production-vpc
.
Next, you will create the variable files to define the variables you used in the code above.
Since you are working across three independent environments (dev, staging, and production) using a single configuration file, best practice demands that you don't hard-code the values of your resources. Hence, you will declare them through variables.
Create a variables.tf
file and declare the region variable.
Add the following code to the file and save it.
variable "region" {
type = string
}
There are different ways you can set the value of the variables through the -var
flag on the command line. But, to keep your variable values secure (when setting sensitive credentials) and organized, we will use variable (.tfvars
) files.
Create three variable files:
dev.tfvars
staging.tfvars
production.tfvars
Tip: use this command:
touch dev,tfvars staginig,tfvars production.tf vars
In each of the variable files above, you will make the value of the region variable different by environment. This will help you differentiate between the dev, staging, and production environments when inspecting through the AWS console.
Open the dev.tfvars
file and input the following code:
region = "us-west-2"
Input the following code in the staging.tfvars
file:
region = "us-east-1"
And finally, in the production.tfvars
file, input the following code:
region = "us-west-1"
Ensure that you save each of the files.
Now, you will apply the configuration to the dev
workspace and observe how it affects others.
On the CLI, run:
$ terraform workspace show
To see your current workspace. If it's not the dev workspace, run:
$ terraform workspace select dev
Initialize Terraform by running:
$ terraform init
Running terraform plan will prompt you to enter a value for the region variable on the CLI. We do not want to do this, so, skip it.
Notice that the dev
workspace now has a terraform.tfstate
file.
Inspect the staging and production state folders and you’ll see that they are still empty—since we have not created a resource in them yet.
Now, you will create the VPC resources in the dev environment only. To do that, we will inform terraform to use the dev workspace variable file:
$ terraform apply -var-file dev.tfvars
Type yes
on the prompt and Terraform will create the resources on AWS.
After the successful creation of the resources, it's time to head over to your AWS console and check if the VPC you created is there.
Navigate to your VPC dashboard from the AWS console.
Click on VPC.
Remember that in your dev workspace variable file (dev.tfvars
), the region you specified is us-west-2.
Ensure that your AWS is in the right region. You should see the VPC instance with the name "dev-vpc
"
Change your AWS region to us-west-1, then us-east-1, you should not find any VPC instances there.
This is possible because, even though the 3 environments are making use of the same configuration file, the workspaces store their state file independently.
You can create another resource in a different workspace and inspect your AWS environment by switching across the regions.
You have successfully created and explored terraform workspace. Now, you will migrate the workspace state file to a remote backend to explore the workspace state files in remote S3 storage.
You can create the S3 bucket using Terraform, but you must not create it in the same project as the backend you want to store in it.
To avoid confusion and to make it easier, you will create the S3 bucket manually.
Navigate to the S3 dashboard from the AWS console and manually create a new S3 bucket in your preferred availability zone.
Note the bucket name you use in this step because you will use it in the subsequent step.
After creating an S3 bucket, you will update your Terraform configuration file to use a remote backend. Open your main.tf
and include the backend resource block.
#...other code above
terraform {
backend "s3" {
bucket = "my-workspace-state-bucket"
key = "path/to/my/workspace_state.tfstate"
region = "us-west-2"
}
}
Replace "my-workspace-state-bucket
" with the name of the S3 bucket you created.
You can use any key name you desire, but we recommend that you keep it descriptive as above.
Save the main.tf
file.
Next, use the Terraform CLI commands to migrate the local state file to the remote S3 repository.
Run terraform init
Enter yes
to the prompt
Run terraform plan
, then terraform apply
to successfully migrate the local backend to the remote S3 bucket.
Head over to your AWS console to inspect the S3 bucket. You should find a new object in your S3 bucket in the directory you defined in the key argument of the backend block (path/to/my/workspace_state.tfstate
). When you navigate through the folder, you'll find the state files of our Terraform project in a similar hierarchy to want we have in the local directory.
Once you complete this lab, run terraform destroy
to remove all the resources you created.