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:
- Separation of Concerns: By defining environment-specific values in separate
tfvarsfiles, you can keep your core infrastructure code generic and reusable. - Ease of Use:
tfvarsfiles provide a straightforward way to manage variables for different environments, making it easy to switch between environments without modifying the main configuration files. - Version Control: Environment-specific
tfvarsfiles 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
- Consistency: By centralizing your environment-specific configurations in
tfvarsfiles, you ensure that all environments are consistently configured, reducing the risk of configuration drift. - Scalability: As your project grows, adding new environments is as simple as creating a new
tfvarsfile. You don’t need to modify your core Terraform configuration, making it easier to manage multiple environments. - Security: Sensitive information, such as credentials or secrets, can also be managed through
tfvarsfiles, although it’s recommended to use a secure method such as Terraform’s native support for environment variables or secret management tools. - 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
tfvarsfiles 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