(Cross-posted to Stack Overflow for better answer-ranking.)
I have a Catch-22 situation with Terraform:
- If I don’t define a default AWS provider (that I don’t actually need) I get errors about the default provider not being defined
- If I then define a default AWS provider, it breaks the use of the default AWS provider in modules, that have been overridden with aliased region-specific providers as they are passed in to the module
Versions
The problems happen with both of these Terraform versions:
Terraform v1.7.1
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v5.31.0
Terraform v1.6.0
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v5.31.0
Scenarios
(All instances of <AWS_REGION>
are actually replaced with a real AWS region identifier, such as us-east-1
or otherwise.)
Scenario #1: No default AWS provider specified:
There are several per-AWS-region aliased AWS providers defined in the root module
provider "aws" {
alias = "<AWS_REGION>"
region = "<AWS_REGION>"
}
# Note: There is no default AWS provider, only aliased ones
There are also several per-AWS-region modules with an overridden AWS provider passed in:
# ./modules.tf
module "provider_<AWS_REGION>" {
source = "./<AWS_REGION>"
# AWS per-region provider is passed in to the module, replacing its default provider
providers = {
aws = aws.<AWS_REGION>
}
}
Each module has all of the per-AWS-region configuration, here is an example:
# Should use the default AWS provider `aws`, which has been replaced
# ./<AWS_REGION>/vpc.tf
resource "aws_vpc" "name_of_vpc" {
# (configuration)
}
The local Terraform state has module
and provider
specified:
# ./terraform.tfstate
{
"version": 4,
"terraform_version": "1.7.0",
"serial": 1459,
"lineage": "<SOME_GUID>",
"outputs": {},
"resources": [
{
"module": "module.provider_<AWS_REGION>",
"mode": "managed",
"type": "<TERRAFORM_RESOURCE_TYPE>",
"name": "<TERRAFORM_RESOURCE_NAME>",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
# ...
}
When running terraform plan
(after a clean init
), the following errors are emitted:
Error: When no default provider is specified:
(When this doesn’t exist: provider "aws" { region = "<REGION>" }
)
│ Error: Invalid provider configuration
│
│ Provider "registry.terraform.io/hashicorp/aws" requires explicit configuration. Add a provider block to the root module and
│ configure the provider's required arguments as described in the provider documentation.
╷
│ Error: Invalid AWS Region:
│
│ with provider["registry.terraform.io/hashicorp/aws"],
│ on <empty> line 0:
│ (source code not available)
Scenario #2: Default provider is added:
This default provider is added:
./provider.tf
provider "aws" {
region = "<ARBITRARY_AWS_REGION>"
}
Result:
There are no actual errors, but each region-specific module just thinks its AWS provider is for the arbitrary AWS region of the default AWS provider, when it seems like it should actually be whatever AWS-region-specific provider has been passed in to the module.
Scenario #3: Adding .<AWS_REGION>
to the end of the provider
value in terraform.tfstate
:
This error is emitted:
│ │ To work with
│ module.provider_<AWS_REGION>.<TERRAFORM_RESOURCE_TYPE>.<TERRAFORM_RESOURCE_NAME> │ its original provider configuration at module.provider_us-east-1.provider["registry.terraform.io/hashicorp/aws"].<AWS_REGION>
│ is required, but it has been removed. This occurs when a provider configuration is removed while objects created by that
│ provider still exist in the state. Re-add the provider configuration to destroy
│ module.provider_us-east-1.<AWS_REGION>.<TERRAFORM_RESOURCE_TYPE>.<TERRAFORM_RESOURCE_NAME>, │ after which you can remove the provider configuration again.
Scenario #4: Manually specifying provider = aws.<AWS_REGION>
to the body of every resource in the AWS-region-specific modules
Doesn’t help: It emits the Error: Provider configuration not present
error.
Scenario #5: Combining Scenario #3 and #4
Doesn’t help: It emits the Error: Provider configuration not present
error.