Introduction

In the world of infrastructure as code (IaC), Terraform stands out for its simplicity and flexibility. However, as your infrastructure grows and becomes more complex, so does the need for more sophisticated management techniques. This is where Terraform workspaces and local variables, like environment_config, come into play. In this comprehensive guide, we'll delve into the nuances of both, providing real-world examples and insights to enhance your Terraform projects.

Terraform Workspaces: Isolating Environments

What Are Terraform Workspaces?

Terraform workspaces offer a way to manage multiple, distinct instances of Terraform configurations. Each workspace has its own state file, making them ideal for deploying the same infrastructure with different configurations or in different environments.

Key Features

  • State Isolation: Workspaces isolate their state, ensuring changes in one don't affect another.
  • Environment Management: They are often used to create different environments (like dev, staging, production) using the same code base.
  • Variable Configuration: Workspaces can use different variable files (terraform.tfvars) or environment variables for each instance.

Example Usage

Let's say you have a Terraform configuration for deploying a web application. You want to maintain separate environments for development, staging, and production. Using Terraform workspaces, you can easily manage these environments. Here's a simplified example:


# Initialize a new workspace
terraform workspace new dev

# Switch to the workspace
terraform workspace select dev

# Apply your Terraform configuration
terraform apply -var-file="dev.tfvars"

Local Variables: Dynamic Configuration

The Role of environment_config

The environment_config local variable is a pattern in Terraform that involves reading from an external JSON file and assigning its values to a Terraform map within your code.

Advantages

  • Dynamic Configuration: Allows for configurations based on the contents of an external file.
  • Complex Settings Management: Ideal for managing configurations that are too intricate for simple tfvars files.

Example Usage

Consider a scenario where your infrastructure requires dynamic configuration based on external input. Here's how you might use environment_config:

main.tf


locals {
  environment_config = jsondecode(file("${path.module}/${var.environment_config}")).input_parameters
}

# Using the local variable
resource "azurerm_resource_group" "example" {
  name     = local.environment_config.resource_group_name
  location = local.environment_config.location
}

 

Breakdown of environment_config Local Variable

  1. Expression Components:

    • jsondecode: A Terraform function used to decode a JSON-formatted string into a Terraform map (or other data structure).
    • file: Another Terraform function that reads the contents of a file at the given path and returns its contents as a string.
    • "${path.module}/${var.environment_config}": This is a string interpolation in Terraform. It constructs a file path by concatenating the module path with the value of the variable var.environment_config.
  2. Operational Flow:

    • File Path Construction: The expression starts by constructing the file path. path.module is a built-in Terraform variable that gives the file system path of the module where the expression is placed. var.environment_config is expected to be a user-defined variable that holds the name of a JSON file (or a relative path to it).
    • File Reading: The file function then reads the contents of this JSON file.
    • Decoding JSON: The jsondecode function takes this file content (a JSON-formatted string) and decodes it into a Terraform map.
    • Accessing input_parameters: Finally, the expression accesses the input_parameters key in the resulting map. This assumes that the JSON file has a top-level key named input_parameters.
  3. Result of the Expression:

    • The end result is that environment_config is set to whatever data structure is contained in the input_parameters key of the JSON file.

Practical Example

Suppose you have a JSON file named env-config.json that looks something like this:


{
  "input_parameters": {
    "parameter1": "value1",
    "parameter2": "value2"
    // ... other parameters ...
  }
  // ... maybe other top-level keys ...
}

If var.environment_config is set to "env-config.json", then after Terraform processes the environment_config local variable, it will hold a map containing parameter1 and parameter2.

Usage

  • This local variable (environment_config) can now be used throughout your Terraform configuration to reference the values defined in the input_parameters of your JSON file.
  • This approach is particularly useful for managing configuration parameters that may vary between environments (like dev, staging, production) or need to be updated frequently, without having to hardcode them into the Terraform files.

By externalizing parameters into a JSON file and reading them into a Terraform map, you make your configuration more flexible and easier to maintain.

Json config file example: config.dev.json


{
    "file_purpose": "This file abstracts the input contract to a JSON schema removing the Terraform/variables depencency",
    "input_parameters": {
        "tags": {
            "Environment": "dev",
            "Resource-owner": "Owner",
            "Deployment": "my deployment",
            "Application": "my web application"
        },
        "resource_group": {
            "name": "rg-dev-resource-group-name-01", 
			"location": "australiaeast" 
		} 
} 

By externalizing parameters into a JSON file and reading them into a Terraform map, you make your configuration more flexible and easier to maintain.

Combining Workspaces and Local Variables

Why Combine Them?

Using both workspaces and local variables like environment_config provides the ultimate flexibility. Workspaces manage environmental separation, while local variables handle complex configurations within each environment.

Practical Application

In a real-world application, you might use workspaces to segregate your dev, staging, and production environments. Within each workspace, environment_config can be used to fine-tune settings without altering the core Terraform files.

Best Practices for Optimizing Terraform Projects

1. Clear Workspace Naming Convention:

  • Use meaningful names for your workspaces, like dev, staging, and production.

2. Version Control for Configuration Files:

  • Store your tfvars and JSON configuration files in version control for better tracking and rollback capabilities.

3. Regularly Update State Files:

  • Ensure that your Terraform state files are regularly updated and backed up.

4. Modularize Your Terraform Code:

  • Break down your Terraform code into modules for reusability and easier management.

5. Document Your Configuration:

  • Maintain clear documentation for your Terraform configurations, especially when using complex local variables.

Conclusion

Terraform workspaces and local variables like environment_config are powerful tools in the IaC toolkit. By understanding and effectively using these features, you can manage complex infrastructure setups with ease and confidence. Whether you're isolating environments with workspaces or managing intricate configurations with local variables, Terraform offers the flexibility and control needed for modern infrastructure management.