The duplicate resource error occurs when Terraform detects two or more resources with the same resource address (type and name combination) in your configuration. This prevents Terraform from planning or applying your infrastructure changes.
Terraform tracks all infrastructure resources using a unique address that combines the resource type and name, like aws_instance.web_server. When you define the same resource address twice in your configuration, Terraform cannot determine which one should be managed and throws a duplicate resource error. This is a configuration-level error that Terraform detects during the validation phase. The duplicate can exist in multiple places: directly in your configuration files, across different modules, or when using modules multiple times without proper unique naming.
First, identify where the duplicate resource is defined. Use grep to search your configuration files for the resource type and name:
# Search for all instances of the duplicated resource
grep -r "resource \"aws_instance\" \"example\"" .
# Or for a specific resource type
grep -r "aws_instance" . | grep "example"Look through the output and note all files where this resource is defined. Most often you'll find it in two or more separate .tf files or modules.
Once you've located all instances, remove the duplicate or rename one to use a different name:
# If you have two identical blocks:
resource "aws_instance" "example" {
# configuration A
}
resource "aws_instance" "example" {
# configuration B (duplicate - DELETE THIS ONE)
}
# Rename one instead:
resource "aws_instance" "example" {
# configuration A
}
resource "aws_instance" "example_secondary" {
# configuration B (RENAMED)
}Keep only the resource you actually need, or rename one to have a unique name suffix like _secondary, _backup, _prod, etc.
If you're using modules multiple times and they create resources with the same names, use unique module names or pass variables to make resource names unique:
# Problem: Both module instances create aws_instance "default"
module "web" {
source = "./modules/instance"
}
module "db" {
source = "./modules/instance" # Same module, same resource names!
}
# Solution 1: Use different module names (not ideal)
module "web_instance" {
source = "./modules/instance"
}
module "db_instance" {
source = "./modules/instance"
}
# Solution 2: Pass a variable for unique naming
module "web" {
source = "./modules/instance"
instance_name = "web"
}
module "db" {
source = "./modules/instance"
instance_name = "db"
}
# Then in module, construct the name:
resource "aws_instance" "server" {
tags = {
Name = "${var.instance_name}-server"
}
}If using count or for_each, ensure no duplicate keys are generated:
# Problem: for_each with duplicate keys
locals {
servers = {
web = { instance_type = "t2.micro" }
db = { instance_type = "t2.small" }
web = { instance_type = "t2.medium" } # DUPLICATE KEY "web"!
}
}
resource "aws_instance" "servers" {
for_each = local.servers
instance_type = each.value.instance_type
}
# Solution: Rename to have unique keys
locals {
servers = {
web = { instance_type = "t2.micro" }
db = { instance_type = "t2.small" }
web_v2 = { instance_type = "t2.medium" } # RENAMED
}
}When combining count and for_each, avoid creating overlapping resource addresses.
After making changes, run terraform plan to verify no duplicate resources remain:
terraform planThe plan should show no duplicate resource errors. Review the output to ensure:
- All resources have unique addresses
- No "duplicate resource" error is present
- Expected resources will be created/modified/destroyed
If the error persists, check that you saved your changes and repeat the search step.
When using workspaces, all workspaces share the same configuration files but maintain separate state. To avoid duplicate resource names across workspaces, use the terraform.workspace variable in resource names:
resource "aws_instance" "web" {
tags = {
Name = "web-${terraform.workspace}"
}
}This ensures each workspace has uniquely named resources. Additionally, Terraform does not always catch duplicates during the plan phase—sometimes they only appear during apply. Always review plan output carefully, especially when refactoring or using modules.
For modules being used multiple times, the best practice is to pass in a prefix or namespace variable that gets incorporated into all resource names, preventing collisions when the module is instantiated multiple times.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform