Skip to main content

Fix Terraform Error: Duplicate Resource Definition

Key Takeaway

Fix terraform duplicate resource definition errors. Find duplicates across .tf files, rename resources, use count/for_each for multiples, and handle module conflicts.

Table of Contents

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

  1. Same resource name in multiple filesmain.tf and ec2.tf both have resource "aws_instance" "web"
  2. Copy-paste error — duplicated a block and forgot to rename
  3. Merge conflict — both branches added the same resource
  4. 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

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.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.