In this lecture,
we will learn about workspaces in Terraform
and how to use them.
Earlier in the course, we learned about state
and its use when running Terraform operations.
Whether stored locally
or in remote backend such as S3 and Terraform Cloud,
state is essential in mapping the real-world infrastructure,
allowing Terraform to model what changes it needs to apply
based on the configuration defined in the state files.
Irrespective of whether the state is stored locally or remotely,
all the examples that we have seen so far has one-to-one mapping
between the configuration directory and the state file.
This means that we have had
one Terraform state file per configuration directory so far.
Let us consider a scenario
where we want to create an EC2 instance in the AWS ca-central-1 region
for a new project called ProjectA.
This can be done by making use of a simple configuration file
in a configuration directory called ProjectA,
which is inside the Terraform projects directory
like this.
If we run terraform apply now inside this configuration directory,
Terraform will create the EC2 instance as expected.
It will also create a state file.
Now,
what if we want to replicate the same configuration
for another project, say, ProjectB,
but with a different AMI ID and a server name as compared to ProjectA.
How do we go about that?
The logical way would be to create a new directory called ProjectB,
copy the configuration files from ProjectA directory,
change the AMI ID and the tags as needed,
and repeat the steps that we did for setting up the ProjectA instance.
However,
the goal of using Terraform or any IaC tool for that matter
is to eliminate repeatable steps and efficiently make use of existing code
as we saw in the module section.
With that in mind,
Terraform offers a feature that allows configuration files within a directory
to be reused multiple times for different use cases,
such as creating a ProjectA
and a ProjectB environment within the same configuration directory.
This feature is called workspace.
With workspaces,
we can use the same configuration directory
to create multiple infrastructure environments
such as the ProjectA and the ProjectB environment.
To create a workspace, we use the terraform workspace command.
This is followed by the new subcommand
and the name of the workspace that we want to create.
We will first create the ProjectA workspace.
Once the workspace is created by this command,
Terraform will immediately switch to it as well.
To list the workspace that was created, use the terraform workspace list command.
In this example, this command lists two workspaces.
The default workspace is the one that is created by default.
The new workspace that we just created is called ProjectA
and has got a star preceding it,
which means that that is the current workspace that we are on.
Now that we have created workspaces,
let us see how to use it within configuration files
to create EC2 instances based on the workspace that we are in.
Let us go over our requirements again.
Without duplicating the configuration files,
we want to create EC2 instances
for two projects in the ca-central-1 region,
ProjectA with the AMI ID ending with 279,
instance type of t2.micro,
and the name of ProjectA,
and another instance for ProjectB
with the AMI ID
that ends with f4d and the same instance type
but with the name tag of ProjectB.
To have a single configuration that can achieve this,
we have to update
our configuration file that we initially used.
We have the variables.tf file
with the variable region set to ca-central-1.
We now remove all the hard-coded values from the main.tf file
and configure them as variables in the variable.tf file.
We add an instance type with a default value of t2.micro.
We then add a new variable called AMI of type map.
Here, we have two key-value pairs.
The first key is ProjectA,
and to this,
we have assigned a value of the AMI ID that we want to use for ProjectA,
and that ends with 279.
Similarly, for the second key, which is ProjectB,
we have assigned the AMI ID that ends with f4d.
In the main.tf file,
we have set the value of instance type to use the variable called instance_type
which is defined in the variables.tf file.
Let us know update the value of the AMI and the tags
to make use of the values associated with the workspace
called ProjectA that we created.
Let's start with the tags first.
Here,
we need the name of the workspace that we are currently in,
but how do we get that?
How do we get the name of the workspace that we are currently in
within the configuration file?
To do this, we'll make use of terraform.workspace,
which provides the value of the current workspace that we are in.
To test this,
let's make use of the terraform console command again.
If we type in terraform.workspace,
it should return the workspace that we are currently in,
which in this case is ProjectA.
This is something we can make use of in the main.tf file.
We add this as the value [?] with the key called Name.
Next, for the AMI argument,
let's use a lookup function that we have used in the previous lecture.
Remember,
the lookup function is used to look up the value of a specific key from a map.
Let us make use of the terraform console command again
and test the value that is returned by the lookup function
when we use var.ami as the map and terraform.workspace as the key.
This returns the AMI ID ending with 279,
which is associated with the key called ProjectA,
which is the current workspace.
Now, we can update the same lookup function
as a value of our AMI argument in the main.tf file.
With that, our configuration is now complete.
If we run terraform plan now,
we can see that it uses the desired AMI and the tag
for creating the instance in the workspace called ProjectA.
To create the corresponding instance for ProjectB,
all we have to do is create a new workspace called ProjectB
using the terraform workspace new command.
This creates a new workspace and also switches to it.
We are now in workspace ProjectB.
If we run the terraform plan command now,
we can see that the AMI ID and tag for ProjectB is applied.
To switch from one workspace to another,
we can make use of the terraform workspace select command.
For example,
currently, we are in ProjectB,
and to switch to ProjectA, we can run the select command like this.
We have now successfully used the same configuration file
to create resources for two different projects.
When we run terraform apply,
it creates two different state files for each workspace,
but where does it store the state for each of these individual workspaces?
When using workspaces,
instead of using the default terraform.tfstate file
in the configuration directory,
Terraform stores the state file
in a separate directory called terraform.tfstate.d.
Inside this directory,
we can see another directory by the name of each workspace
for which we have at least completed one terraform apply.
Within this directory,
there would be a terraform.tfstate file
associated with the resources created for that specific workspace.
That's it for this lecture.
Now, head over to the Hands-on Labs
and practice working with workspaces in Terraform.