14-Dec

The Cloud

Show the current Terraform Workspace in Your Terminal Prompt

Managing Terraform configurations efficiently with workspaces is a game-changer for keeping your code DRY (Don't Repeat Yourself). However, when dealing with multiple workspaces, it can be challenging to keep tabs on your current working environment. In this post, we'll explore how to display the active Terraform workspace in your terminal prompt to avoid unintended disasters, such as executing terraform destroy on the wrong setup.

3 min read

·

By Andreas Mosti

·

December 14, 2023

Terraform Workspaces you say?


If you're unfamiliar with them, Terraform workspaces provide a solution for handling multiple environments (e.g., dev, staging, production) within a single Terraform configuration. Before the introduction of workspaces, maintaining separate Terraform configurations for each environment was necessary. This approach was less than ideal due to extensive code duplication, leading to potential errors. With workspaces, a single Terraform configuration suffices, and workspaces help manage the state of each environment independently.

Consider this example: a Terraform configuration creating a VPC, a subnet, and an EC2 instance. By running terraform workspace new staging and terraform workspace new production, you can create distinct workspaces for each environment. Execute `terraform apply` in the desired workspace to deploy the VPC, subnet, and EC2 instance uniquely for that environment, each having its isolated state file.

Here's a code snippet exemplifying interaction with Terraform workspaces. Suppose you wish to create an Azure KeyVault, prefixing the name with the workspace designation:

locals {
  environment = terraform.workspace

  key_vault_name = {
    production = "vault-prod"
    staging    = "vault-staging"
  }
}

resource "azurerm_key_vault" "this" {
  name = lookup(local.key_vault_name, local.environment)

  resource_group_name = var.resource_group_name
  location            = var.location
  tenant_id           = data.azurerm_client_config.current.tenant_id

  sku_name = "standard"

  enabled_for_disk_encryption = false
  soft_delete_retention_days  = 7
  purge_protection_enabled    = false

  tags = var.tags
}

Utilizing the terraform.workspace variable ensures that the KeyVault name is dynamically selected based on the workspace, enabling code reuse across multiple environments while maintaining strict isolation of each environment's state.

For more detailed information on Terraform workspaces, refer to the official documentation.

Displaying the Current Workspace in Your Terminal Prompt


Now that we grasp the concept of workspaces, let's explore how to exhibit the active workspace in our terminal prompt. This proves invaluable when navigating multiple workspaces, ensuring you're in the correct one to avoid unintended operations like applying changes to the wrong environment.
The greatest fear any developer has is to accidentally run `terraform apply` in the wrong workspace and accidentally destroy production. By showing the current workspace in your terminal prompt, you can be sure that you are working in the correct workspace.
For users of zsh with Oh My Zsh, a popular zsh configuration framework, the built-in terraform plugin offers autocompletion and workspace indication in the prompt. Add the following lines to your configuration file:

plugins=(... terraform)

RPROMPT='$(tf_prompt_info)'
RPROMPT='$(tf_version_prompt_info)'

and if you want to add an prefix or suffix to the prompt:

ZSH_THEME_TF_PROMPT_PREFIX="%{$fg[white]%}"
ZSH_THEME_TF_PROMPT_SUFFIX="%{$reset_color%}"
ZSH_THEME_TF_VERSION_PROMPT_PREFIX="%{$fg[white]%}"
ZSH_THEME_TF_VERSION_PROMPT_SUFFIX="%{$reset_color%}"

Full plugin doc can be found here.

But, if you're an old fart like me and still use Bash, you're in luck. Add the following lines to your .bashrc or .bash_profile (with your own edits to the PS1 variable):

terraform_prompt()
{
    if [ -d .terraform ]; then
        workspace="$(command terraform workspace show 2>/dev/null)"
        if [ -n "$workspace" ]; then
            echo " ($workspace)"
        fi
    fi
}

export PS1='\u@\h \[\033[32m\]\w\[\033[33m\]$(parse_git_branch)\[\e[1m\]$(terraform_prompt)\[\033[00m\] $ '

This code will result in the following prompt:

~/Dev/my-terraform-repo/workspace-module (main) (staging) $

Stay safe and happy Terraforming!

Oh, and as a bonus - here is the function making the current git branch show up in your prompt, as seen in the PS1 export above:

parse_git_branch() {
         git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
     }