Quick Answer
# Find the duplicate
grep -rn 'resource "aws_instance" "web"' *.tf
# Rename one of them to a unique name
The Error
Error: Duplicate resource "aws_instance" configuration
on ec2.tf line 15:
15: resource "aws_instance" "web" {
A aws_instance resource named "web" was already declared at main.tf:10,1-32.
Resource names must be unique per type in a module.
What Causes This
- Same resource name in multiple files —
main.tfandec2.tfboth haveresource "aws_instance" "web" - Copy-paste error — duplicated a block and forgot to rename
- Merge conflict — both branches added the same resource
- Moved to module — resource exists both in root and in a module call
Solution 1: Find All Duplicates
# Search across all .tf files
grep -rn 'resource "aws_instance" "web"' .
# Find ALL duplicate resource declarations
grep -rh 'resource "' *.tf | sort | uniq -d
./main.tf:10:resource "aws_instance" "web" {
./ec2.tf:15:resource "aws_instance" "web" { ← Duplicate!
Solution 2: Rename to Unique Names
# main.tf
resource "aws_instance" "web_primary" {
# ...
}
# ec2.tf
resource "aws_instance" "web_secondary" {
# ...
}
If the resource already exists in state, use terraform state mv:
terraform state mv aws_instance.web aws_instance.web_primary
Solution 3: Use count or for_each
If you need multiple identical resources:
# Instead of two separate blocks:
resource "aws_instance" "web" {
count = 2
ami = var.ami_id
instance_type = "t3.micro"
tags = {
Name = "web-${count.index}"
}
}
Or with for_each for named instances:
resource "aws_instance" "web" {
for_each = toset(["primary", "secondary"])
ami = var.ami_id
instance_type = "t3.micro"
tags = {
Name = "web-${each.key}"
}
}
Solution 4: Organize Into Modules
If resources grew organically across files:
# Before (messy, prone to duplicates)
main.tf ← has aws_instance "web"
ec2.tf ← also has aws_instance "web" 💥
# After (organized)
modules/web/
├── main.tf ← aws_instance "this"
└── variables.tf
main.tf ← module "web" { source = "./modules/web" }
Prevention
# Validate catches duplicates
terraform validate
# Format and check before commit
terraform fmt -check -recursive
# Pre-commit hook
#!/bin/bash
terraform validate || exit 1
terraform fmt -check -recursive || exit 1
Hands-On Courses
- Terraform for Beginners on CopyPasteLearn
- Terraform By Example — practical code examples
Conclusion
Duplicate resource names must be unique per type within a module. Find duplicates with grep, rename one, and use terraform state mv if the resource already exists. For multiple similar resources, use count or for_each instead of separate blocks.