Skip to main content

Optimizing Terraform Performance

1. Using Parallelism

Terraform supports parallel execution to speed up operations when managing multiple resources. By default, Terraform runs operations in parallel but with limits to avoid overwhelming the system or external services.

Setting Default Value Description
max_parallelism 10 Maximum number of concurrent operations (applies to all resources)
parallelism 10 Alias for max_parallelism, deprecated in favor of max_parallelism

Example: Setting Max Parallelism in Configuration

terraform {
  required_version = ">= 1.0"
  parallelism      = 20
}
Note: Increasing max_parallelism can lead to resource contention or API throttling if external providers (like AWS, GCP) have rate limits. Monitor system performance and adjust accordingly.

2. Implementing Resource Targeting

Resource targeting allows you to limit Terraform's operations to specific resources or sets of resources, which can significantly improve performance during development and testing.

Command Description Usage Example
terraform plan -target Plan only the specified resource(s) terraform plan -target=aws_instance.web
terraform apply -target Apply only the specified resource(s) terraform apply -target=aws_s3_bucket.my_bucket
terraform destroy -target Destroy only the specified resource(s) terraform destroy -target=aws_elasticache_cluster.my_cache

Example: Targeting a Specific Resource

terraform plan -target=aws_instance.web

Example: Targeting Multiple Resources

terraform apply -target=aws_s3_bucket.my_bucket -target=aws_cloudfront_distribution.my_dist
Note: Targeting does not remove dependencies from the state file. If a targeted resource depends on another resource that isn't targeted, Terraform will still attempt to manage it.
Warning: Using -target can lead to inconsistent states if dependencies are not properly managed. Always ensure that all necessary resources are included in your plan or apply.

3. Disabling Refresh

By default, Terraform performs a refresh operation before executing any plan or apply. This ensures that the state file is up-to-date with the actual infrastructure. However, in some cases, you may want to disable this behavior to improve performance or avoid unintended side effects.

Option Values Description
-refresh=false false Disables the refresh operation during plan and apply commands.

Example: Disabling Refresh in Plan

terraform plan -refresh=false
Note: Disabling refresh can lead to outdated state information, which might cause unexpected behavior if the infrastructure has changed since the last refresh.

4. Splitting Large Configurations

Large Terraform configurations can lead to performance issues and longer execution times. Splitting configurations into smaller, manageable modules improves performance and maintainability.

Approach Description Benefits
Module-based Splitting Break configuration into reusable modules using module blocks. Improves reusability, readability, and reduces complexity.
Backend Configuration Use remote backends (e.g., remote, s3) to store state efficiently. Enables shared state, better collaboration, and performance scaling.
Resource Grouping Group related resources into separate configuration files. Reduces configuration size and improves deployment speed.

Example: Module-Based Splitting

module "vpc" {
  source = "./modules/vpc"
  cidr_block = "10.0.0.0/16"
}

module "ec2_instances" {
  source = "./modules/ec2"
  vpc_id = module.vpc.vpc_id
}
Note: Ensure that modules are well-defined and have clear interfaces to avoid tight coupling.

Best Practices for Splitting Configurations

  • Use module blocks to encapsulate logic and resources.
  • Store state in remote backends for better performance and collaboration.
  • Group related resources into separate files to reduce configuration size.

5. Using Remote State Caching

Option Values Notes
backend "s3" Remote state backend to use for caching
bucket "my-terraform-state" S3 bucket name for state storage
key "prod/terraform.tfstate" Path to the state file in the bucket
region "us-west-2" AWS region for the S3 bucket
dynamodb_table "terraform-locks" DynamoDB table for state locking

Example: Configuring S3 Backend with Caching

terraform {
  backend "s3" {
    bucket = "my-terraform-state"
    key    = "prod/terraform.tfstate"
    region = "us-west-2"
    dynamodb_table = "terraform-locks"
  }
}
Note: Enabling remote state caching significantly reduces the latency of state operations by storing a local copy of the state file.
Warning: Ensure that the local state file is not committed to version control.
Feature Description Status
Local State Cache Stores a local copy of the remote state for faster access NEW
State Locking Prevents concurrent state modifications with DynamoDB STABLE

6. Minimizing Provider API Calls

Approach Description Benefits
Use data sources efficiently data "aws_instance" "example" { filter { name = "instance-id" value = "i-1234567890abcdef0" } } Reduce API calls by fetching only required data
Avoid repeated resource lookups resource "aws_instance" "example" { ami = data.aws_ami.ubuntu.id } Cache results to prevent redundant API queries
Batch operations where possible resource "aws_lb_target_group" "example" { count = 3 name = "tg-${count.index}" } Reduce API round trips by grouping resources

Example: Reducing API Calls with Data Sources

data "aws_ami" "latest" {
  most_recent = true
  owners      = ["123456789012"]
  filters {
    name   = "name"
    values = ["ubuntu/images/ubuntu-focal-20.04-amd64-server-*"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.latest.id
  instance_type = "t3.micro"
}
Note: Using data blocks allows Terraform to cache results and avoid repeated API calls during plan/apply phases.
Warning: Avoid using count or for_each on resources that make external API calls without caching.

7. Using Local Caching

Cache Type Description Configuration Notes
local Stores state and module downloads locally backend "local" Default behavior for local development
remote Stores state in a remote backend (e.g., S3, GCS) backend "s3" Recommended for team collaboration

Example: Enabling Local Caching for Modules

terraform {
  required_version = "1.9.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.0.0"
    }
  }
}

provider "aws" {
  region = "us-west-2"
}

module "vpc" {
  source = "./modules/vpc"
  vpc_cidr_block = "10.0.0.0/16"
}
Note: Terraform automatically caches modules and providers in .terraform directory. For performance, ensure this directory is not version-controlled.
Warning: Avoid using terraform init in CI/CD without caching. It can significantly slow down builds.

8. Optimizing Module Structure

Aspect Description Best Practice
Module Nesting Depth How deeply modules are nested Keep nesting under 3 levels to avoid complexity and performance overhead
Module Reusability Ability to reuse modules across different configurations Design modules with parameters to make them adaptable to various use cases
Resource Cohesion How closely related resources are within a module Group logically related resources in the same module to reduce inter-module dependencies
State Management How module state is handled and managed Use local state where possible; avoid excessive remote state dependencies

Example: Efficient Module Structure

# modules/vpc/main.tf
resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
}

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id
  cidr_block = var.public_subnet_cidr
}

# modules/vpc/variables.tf
variable "vpc_cidr" {
  type = string
}

variable "public_subnet_cidr" {
  type = string
}
Note: Avoid deeply nested modules as they can increase plan and apply times. Keep modules focused on a single responsibility.

Key Tips for Module Optimization

  • Minimize the number of modules to reduce complexity
  • Use variables and locals to make modules flexible
  • Avoid circular dependencies between modules
  • Use count and for_each to handle repetition efficiently

9. Reducing Plan Time

Strategy Description Impact
Use `terraform plan -target` Limit planning to specific resources or modules Significant reduction in plan time for large configurations
Avoid `count` and `for_each` in large loops Use `dynamic` blocks or external data sources instead Moderate to high reduction in plan time
Use `terraform state list` to identify slow resources Identify and optimize problematic resources High impact for configurations with many resources

Example: Using -target to reduce plan time

terraform plan -target=aws_instance.web_server
Note: Using -target limits the scope of the plan, which can be useful for faster iteration during development.

Best Practices to Reduce Plan Time

  • Use -target for focused planning
  • Avoid unnecessary resource loops
  • Use terraform state list to identify bottlenecks

10. Monitoring Apply Duration

Metric Description Collection Method Threshold
apply_duration_seconds Time taken to complete the apply operation in seconds Using Terraform Cloud/Enterprise metrics or custom logging Alert if > 300 seconds
plan_duration_seconds Time taken to complete the plan operation in seconds Same as above Alert if > 120 seconds

Example: Logging Apply Duration

terraform apply -auto-approve 2>&1 | grep "Apply complete"
Note: Use terraform plan and terraform apply with -json flag to capture detailed timing information for analysis.
Warning: Long apply durations may indicate resource dependencies or inefficient configurations.

Was this article helpful?