Terraform manages infrastructure with state files. By default you have a single workspace, default. So when you run
terraform plan and
terraform apply you are working the default workspace prepared by terraform.
But with workspaces we can have multiple states. What this means, we can have different server setup with different state files managing that server setup(keep records of what has been deployed at every time). Also it cuts down the amount of copy and paste you will be doing.
To set up workspaces in terraform is very easy. The command
terraform workspace new <name of workspace> does that. Assuming I needed different workspaces to keep tabs on my deployment for DEV, QA and PROD. This will be simply achieved by running-
terraform workspace new DEV,
terraform workspace new QA and
terraform workspace new PROD. This creates three different sub-folders under the terraform.tfstate.d folder
Workspace created! How do we run our Terraform code in a specific workspace? Simply run
terraform workspace select <name of workspace>. Terraform will throw you a prompt on what workspace you are working in. Go head and run
terraform plan and
This is all well and good if you are building infrastructure alone because you are an amazing engineer. More often than not, tasks are performed in teams and we need some collaboration to get things done effectively. How do we achieve this with workspaces🤔? We should use some backend to store these state files✨😎.
Using AWS as our provider, I'll demonstrate
We create an S3 bucket to store the state files.
Note: bucket name must be unique because the s3 namespace is a shared one. You get an error like
Error: Error creating S3 bucket: BucketAlreadyExists: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.
status code: 409, request id: EMBTK255FN7K3QDT, host id: 20vAPtmPGrMG/2tec=
if the bucket name has been taken.
Now we need some way to lock our file when we are deploying to avoid your team from walking over each other. This way just one person can deploy at a time. We will use AWS DynamoDB to achieve this
The table must have a primary key named "LockID" and type "S" (type string). You get an error if this isn't so. Error below:
Error: Error locking destination state: Error acquiring the state lock: 2 errors occurred:
* ValidationException: One or more parameter values were invalid: Missing the key Locker in the item
status code: 400, request id: 7BRN5V5Q92K0393GO5AEMVJF66Q9ASUAAJG
* ValidationException: The provided key element does not match the schema
status code: 400, request id: KDJ19AI5UB2TJBSQ9ASUAAJG
With all this in place we can now
terraform init ->
terraform plan ->
The final step to achieve our objective will be to declare our backend in terraform.
Again we need to initialize.
Done correctly Terraform will seek permission to make of a copy of your state to the backend.
Initializing the backend... Acquiring state lock. This may take a few moments... Do you want to copy existing state to the new backend? Pre-existing state was found while migrating the previous "local" backend to the newly configured "s3" backend. No existing state was found in the newly configured "s3" backend. Do you want to copy this state to the new "s3" backend? Enter "yes" to copy and "no" to start with an empty state. Enter a value:
Real easy, huh?!🙃
If you go into your S3 bucket you should see a path
env:/ with all your workspaces listed with each it's own state file.
The terraform has good documentation on this.
+++Header Photo credit: Pixabay's mozlase__+++