This error occurs when you define multiple provider blocks for the same provider without using distinct aliases. Each provider configuration after the first must have a unique alias to distinguish between them.
Terraform requires each provider configuration to be unique. A default (non-aliased) provider block can only be defined once for each provider type. If you need multiple configurations of the same provider (for example, to deploy to different AWS regions or accounts), each additional configuration must have a distinct alias. The error message will reference the conflicting file and line numbers, showing where the duplicate configuration was declared and where the original was first defined.
First, find all provider blocks in your configuration. The error message will point you to the lines with conflicts:
# WRONG - Two non-aliased aws providers
provider "aws" {
region = "us-east-1"
}
provider "aws" {
region = "us-west-2"
}Review your Terraform files (*.tf) in your working directory and any modules you're using.
The simplest solution is to delete the duplicate provider block if you only need one configuration:
# CORRECT - Single default provider
provider "aws" {
region = "us-east-1"
}If you only need one provider configuration, removing the duplicate should resolve the error.
If you need multiple configurations of the same provider (e.g., for different regions), use the alias meta-argument to distinguish them:
# Default provider (no alias needed for the first one)
provider "aws" {
region = "us-east-1"
}
# Additional provider with a unique alias
provider "aws" {
alias = "west"
region = "us-west-2"
}
# Another provider with a different alias
provider "aws" {
alias = "eu"
region = "eu-west-1"
}Each alias must be unique within the configuration. The first provider doesn't need an alias (it becomes the default).
When using aliased providers, specify which one to use in your resources:
# Use the default provider
resource "aws_instance" "default_region" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
# Uses the default (non-aliased) aws provider
}
# Use the west alias
resource "aws_instance" "west_region" {
provider = aws.west
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
# Uses the "west" provider
}
# Use the eu alias
resource "aws_instance" "eu_region" {
provider = aws.eu
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
# Uses the "eu" provider
}Always prefix aliased provider references with the provider name and a dot: aws.west.
If you're using modules, you must explicitly pass aliased providers to them:
module "network_west" {
source = "./modules/network"
# Pass the west provider to the module
providers = {
aws = aws.west
}
}
module "network_eu" {
source = "./modules/network"
# Pass the eu provider to the module
providers = {
aws = aws.eu
}
}Without the providers block, modules inherit the default (non-aliased) provider. This is crucial when you need different modules to use different provider configurations.
Provider configurations can also exist in modules. If the duplicate is coming from a module, you need to handle it differently:
# BAD - Defining provider in a module
# modules/mymodule/main.tf
provider "aws" {
region = "us-west-2"
}Instead, modules should NOT define provider blocks. Let the parent module pass the provider:
# GOOD - Module receives provider from parent
# modules/mymodule/main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
resource "aws_instance" "example" {
# Will use whichever provider is passed to the module
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}Then in your root module:
provider "aws" {
region = "us-east-1"
}
module "mymodule" {
source = "./modules/mymodule"
providers = {
aws = aws
}
}After making changes, validate your configuration to ensure there are no remaining issues:
terraform validateThis command checks the syntax and structure of your configuration files without accessing any remote resources. If validation passes, you can proceed with initialization and planning:
terraform init
terraform plan### Provider Aliases in Complex Configurations
When managing multi-region or multi-account infrastructure, provider aliases are essential:
1. Multi-Region Deployments: Each region needs a distinct provider configuration with an alias
provider "aws" { region = "us-east-1" }
provider "aws" { alias = "west"; region = "us-west-2" }
provider "aws" { alias = "eu"; region = "eu-west-1" }2. Multi-Account Access: Use aliases to distinguish between different AWS accounts
provider "aws" { profile = "main-account" }
provider "aws" { alias = "prod"; profile = "production-account" }
provider "aws" { alias = "dev"; profile = "development-account" }3. Mixed Providers: Same logic applies to other providers
provider "azure" { subscription_id = "..." }
provider "azure" { alias = "secondary"; subscription_id = "..." }### Module Provider Inheritance
Modules have important provider inheritance rules:
- Modules inherit the default (non-aliased) provider from their parent
- To use an aliased provider in a module, you MUST explicitly declare it in the providers argument
- If a module needs multiple providers, declare all of them in the parent's module block
### Best Practices
1. Keep provider blocks in the root module: Don't define providers in child modules unless absolutely necessary
2. Use consistent naming: Name your aliases clearly (e.g., west, eu, prod) instead of generic names like provider2
3. Document provider usage: Add comments explaining why each provider configuration exists
4. Separate concerns: Consider organizing providers by region or account in dedicated files (e.g., providers-west.tf)
### Common Patterns
Pattern 1: Single region (no aliases needed)
provider "aws" {
region = "us-east-1"
}Pattern 2: Multi-region with modules
# Root module
provider "aws" { region = "us-east-1" }
provider "aws" { alias = "west"; region = "us-west-2" }
module "app_east" {
source = "./modules/app"
providers = { aws = aws }
}
module "app_west" {
source = "./modules/app"
providers = { aws = aws.west }
}Pattern 3: Multi-account access
# Assume role in different account
provider "aws" {
assume_role {
role_arn = "arn:aws:iam::PRIMARY_ACCOUNT_ID:role/terraform"
}
}
provider "aws" {
alias = "prod"
assume_role {
role_arn = "arn:aws:iam::PROD_ACCOUNT_ID:role/terraform"
}
}Error: Error rendering template: template not found
How to fix "template not found" error in Terraform
Error: Error generating private key
How to fix 'Error generating private key' in Terraform
Error creating Kubernetes Service: field is immutable
How to fix "field is immutable" errors in Terraform
Error: Error creating local file: open: permission denied
How to fix "Error creating local file: permission denied" in Terraform
Error: line endings have changed from CRLF to LF
Line endings have changed from CRLF to LF in Terraform