Terraform tfvars for Environment specific Deployments

When managing infrastructure as code (IaC) with Terraform, one of the challenges that often arises is how to create environment-agnostic deployments. This means writing Terraform configurations that can be easily reused across multiple environments, such as development, staging, and production, without requiring significant modifications. Terraform’s .tfvars files are an excellent tool for achieving this goal.

In this blog, we’ll explore how to use Terraform tfvars files to manage environment-specific configurations in a way that keeps your Terraform codebase clean, maintainable, and adaptable. We’ll also walk through a practical example of deploying resources on Microsoft Azure using this approach.

Why Use tfvars Files?

Terraform variables allow you to parameterize your Terraform configurations. While you can define these variables directly in your .tf files or pass them at runtime, using .tfvars files offers several advantages:

  1. Separation of Concerns: By defining environment-specific values in separate tfvars files, you can keep your core infrastructure code generic and reusable.
  2. Ease of Use: tfvars files provide a straightforward way to manage variables for different environments, making it easy to switch between environments without modifying the main configuration files.
  3. Version Control: Environment-specific tfvars files can be versioned alongside your Terraform configurations, ensuring consistency and traceability across deployments.

Setting Up Your Terraform Project

Let’s assume you’re working on a Terraform project where you need to deploy an Azure Resource Group and a Storage Account across multiple environments: development, staging, and production. Here’s how you can structure your project to use tfvars for environment-agnostic deployments.

Step 1: Define Variables in a .tf File

First, define the variables that will be used in your Terraform configuration. Create a file named variables.tf:

# variables.tf

variable "resource_group_name" {
  description = "The name of the resource group"
  type        = string
}

variable "location" {
  description = "The Azure region to deploy resources in"
  type        = string
  default     = "East US"
}

variable "storage_account_name" {
  description = "The name of the storage account"
  type        = string
}

variable "environment" {
  description = "The environment in which to deploy resources"
  type        = string
}

Step 2: Write the Terraform Configuration

Next, create the Terraform configuration file main.tf that uses these variables:

# main.tf

provider "azurerm" {
  features = {}
}

resource "azurerm_resource_group" "rg" {
  name     = var.resource_group_name
  location = var.location
}

resource "azurerm_storage_account" "storage" {
  name                     = var.storage_account_name
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = azurerm_resource_group.rg.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  tags = {
    environment = var.environment
  }
}

This configuration file is generic and does not contain any hardcoded values specific to a particular environment.

Step 3: Create Environment-Specific tfvars Files

Now, create separate tfvars files for each environment. For example:

dev.tfvars:

resource_group_name   = "myapp-dev-rg"
storage_account_name  = "myappdevstorage"
environment           = "development"
location              = "East US"

staging.tfvars:

resource_group_name   = "myapp-staging-rg"
storage_account_name  = "myappstagingstorage"
environment           = "staging"
location              = "West Europe"

prod.tfvars:

resource_group_name   = "myapp-prod-rg"
storage_account_name  = "myappprodstorage"
environment           = "production"
location              = "East US 2"

Each of these tfvars files contains values tailored for a specific environment.

Step 4: Deploying to Different Environments

To deploy your Terraform configuration to a specific environment, you simply specify the corresponding tfvars file using the -var-file flag. For example:

# Deploy to the development environment
terraform apply -var-file="dev.tfvars"

# Deploy to the staging environment
terraform apply -var-file="staging.tfvars"

# Deploy to the production environment
terraform apply -var-file="prod.tfvars"

This command tells Terraform to use the variables defined in the specified tfvars file, allowing you to deploy the same infrastructure code to different environments without any modifications.

Benefits of This Approach

  1. Consistency: By centralizing your environment-specific configurations in tfvars files, you ensure that all environments are consistently configured, reducing the risk of configuration drift.
  2. Scalability: As your project grows, adding new environments is as simple as creating a new tfvars file. You don’t need to modify your core Terraform configuration, making it easier to manage multiple environments.
  3. Security: Sensitive information, such as credentials or secrets, can also be managed through tfvars files, although it’s recommended to use a secure method such as Terraform’s native support for environment variables or secret management tools.
  4. Collaboration: Teams can work more effectively when environment configurations are clearly separated and versioned. Developers can focus on the Terraform code, while operations teams can manage the tfvars files to adjust deployments for different environments.

Using Terraform tfvars files for environment-agnostic deployments is a powerful approach that enhances the flexibility, maintainability, and scalability of your infrastructure as code. By separating environment-specific configurations from your core Terraform files, you can manage deployments across multiple environments with ease.

Whether you’re deploying to Azure, AWS, or any other cloud provider, this method helps keep your Terraform configurations clean and reusable, ultimately streamlining the process of managing infrastructure in complex, multi-environment setups.

Note: This code is tested only in LAB environment. Test this before you use in production