Sling Academy
Home/DevOps/Terraform: Managing multiple environments (dev, staging, production)

Terraform: Managing multiple environments (dev, staging, production)

Last updated: February 03, 2024

Overview

Managing infrastructure as code (IaC) has become a best practice for deploying and scaling cloud resources swiftly and reliably. Terraform, a tool by HashiCorp, stands at the forefront of IaC, allowing teams to manage cloud services across diverse providers with ease. This guide dives into how to utilize Terraform for managing multiple environments such as development (dev), staging, and production. By segregating environments, you ensure that testing and development activities don’t impact your live user-facing applications.

Understanding the Basics

Before diving deeper into multi-environment management, it’s crucial to understand some Terraform basics. Terraform uses .tf files to describe the desired state of your cloud resources in a declarative manner. When you apply a Terraform plan, it automatically figures out the most efficient way to reach that desired state.

Workspace Strategy

In Terraform, workspaces allow you to manage multiple states with the same configuration. You can use workspaces to differentiate your environments. Let’s start with creating workspaces for dev, staging, and production environments.

terraform workspace new dev
terraform workspace new staging
terraform workspace new production

Switch between workspaces to apply changes specific to that environment:

terraform workspace select dev

Environment-specific Configuration

Using variables and workspaces, you can customize your Terraform configuration for each environment. You can define environment-specific variables in separate files, e.g., dev.tfvars, staging.tfvars, and production.tfvars.

variable "environment" {}

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "example" {
  ami           = var.ami
  instance_type = "t2.micro"
  tags = {
    Environment = var.environment
  }
}

Apply your configuration with the corresponding variable file:

terraform apply -var-file=dev.tfvars

Advanced Configuration: Module Approach

To further refine management of environments, it’s beneficial to use Terraform modules. Modules allow you to encapsulate a collection of resources into a single block, which can then be reused across different environments. You might define a module for your network setup, another for your database configuration, etc.

module "network" {
  source = "./modules/network"
  environment = terraform.workspace
}

This approach enables you to maintain a DRY (Don’t Repeat Yourself) codebase and simplifies updates across all environments.

State Management

State management is pivotal in maintaining consistency across your environments. Terraform stores state information about your resources in state files. For multiple environments, it’s crucial to isolate state files to prevent accidents like applying staging configurations to production. Utilizing remote backends such as AWS S3 with state locking can offer a robust solution here.

terraform {
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "path/to/my/statefile"
    region = "us-east-1"
    encrypt = true
    lock_table = "my-lock-table"
  }
}

CI/CD Integration

Integrating Terraform with your continuous integration and deployment (CI/CD) pipeline can automate the application of configurations, reducing manual errors and speeding up deployment cycles. Tools like Jenkins, GitLab CI, and GitHub Actions can be configured to apply Terraform changes based on git workflows.

Best Practices

  • Use version control for your Terraform configurations to track changes and revert if necessary.
  • Regularly run terraform plan to preview changes before applying them.
  • Keep secret keys and sensitive data out of your Terraform files. Use environment variables or secret management tools like AWS Secrets Manager.
  • Review and tighten IAM policies to ensure minimal necessary permissions for Terraform actions.

Conclusion

Terraform provides a powerful, flexible toolset for managing infrastructure across multiple cloud environments. By utilizing workspaces, environment-specific configurations, and modules, you can maintain a clean, organized, and efficient IaC workflow. Adopting best practices and integrating with CI/CD pipelines further enhances the security, reliability, and speed of your deployments. In the end, mastery over Terraform not only streamlines infrastructure management but also empowers your teams to deliver superior products to your users faster.

Next Article: Terraform: Store and retrieve secrets the right way (4 approaches)

Previous Article: Terraform: How to add alias to a provider

Series: Terraform Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide