-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
configuration_aliases in child module terraform validate fails: Provider configuration not present #28490
Comments
Is there any update on this issue? This issue is causing a similar, although much smaller scale, impact as #28803 in terms of cluttering up the plans that we ask engineers to review with warnings that are not material and we cannot do anything to resolve or silence. In our case, we have a repo that contains our shared modules. That repo has a check that runs The preferred solution to the immediate issue would be changing terraform {
required_providers {
aws = {
source = "hashicorp/aws"
configuration_aliases = [ aws.foo ]
}
}
} as it does with provider "aws" {
alias = "foo"
} or at least spit out a warning from validate instead of an error since I'd rather have the warning get spit out on the validate that no one looks at unless if it fails than in the plan that gets run much more frequently and is reviewed by humans. As far as taking a step back and thinking about how Terraform is used in the wild, could we revisit adding a flag to silence all warnings (eg I'm happy to help contribute in any way I can to pushing this along as long as the PR will get reviewed. |
Could we not just add a |
@mkielar, the issue here happens long before For now, the only way to correctly validate a module which can accept providers as a parameter is to wrap it in a root module which defines in the required providers. |
@jbardin, obviously I don't know the internals of terraform too well. However, from a user stand point: If I do following:
I'm basically telling terraform that there will be two providers in this module: If however I add:
Then running It seems to me, that in both cases terraform has all the information required to properly run validation and validate without errors, yet in the first case (with missing |
The provider block is not simply different syntax for the same thing. The Older versions of terraform could treat the empty provider block as a "proxy" for a provider passed in, but there was no way to differentiate that from an actual provider declared within in the module in all cases. It was a confusing syntax overloading the meaning of the The primary reason an empty provider block in a module was not turned into an error was due to timing, with limited releases pending to fully deprecate the behavior before 1.0. In order to test a non-root module in this way, something must always be added; either temporary provider configuration to make it validate as if it was a root module, or call the module from a dummy root module. How to best handle this is what needs to be designed here, while also planning on how to integrate any changes into the experimental |
Just published https://github.com/bendrucker/terraform-configuration-aliases-action to help with this. It generates |
This issue still occurs in terraform |
We're essentially being forced to choose between loud warnings when using Regardless of when this is patched, please update the tests for building the TF CLI to check whether the CLI functions break when using a wide spectrum of child modules. |
This bug is very frustrating. I have just logged a support req with Hashicorp to try and get it moving. |
It took me two weeks to get past the first line support engineer to agree its a bug. I was initially told configuration_aliases was deprecated which clearly is not the case. |
Let's assume I have the following directory structure:
My
This means my My
In this root configuration, I'm explicitly passing both the unaliased At this point in time I can Here are a few points to note. It's not necessary to pass unaliased providers to sub modules because those are implicitly implied. I could remove the line I could pass my unaliased However, if I remove the line
Based on reading this issue multiple times, it seems the core frustration is being unable to James explained the issue fairly well here:
I've always opted for the latter recommendation of creating some root configuration that calls the desired sub module and running |
@sudomateo My root configuration looks like this:
But I have a query regarding child provider configuration. As I'm using S3 bucket for storing state so should I include backend block as well in the child module or not? Or only this much code is enough for child module?
|
@vp393001 Welcome to the discussion! Your specific question is a bit outside the scope of this GitHub issue. In the future, questions like that are better asked in our community Discuss forums or in a separate GitHub issue. This helps keep the discussion on the GitHub issue focused on the actual topic of the GitHub issue. Regardless, here are the answers to your questions.
Backend configuration should be defined in your root module only. It should not be defined in a child module as child modules are meant to be called from a root module.
Child modules should specify the providers it requires and the supported Terraform versions. That way, a root module can be aware of those constraints when calling the child module. |
Root modules in Terraform have unfortunately always been a little different than called modules, and this behavior is a symptom of that since all of Terraform's commands assume that they are dealing with root modules, which should always include any needed provider configurations for themselves and the child modules. I can definitely understand the use-case of wanting to validate a shared module in a way that answers the question about whether the module is valid itself, regardless of the context of where it's used. There's a similar problem for the module testing experiment, where we need a way to give a shared module all of the outside stuff it needs to actually work without modifying the module itself. In that case, we achieve that by writing a root module for each test scenario, which calls into the module under test. As others noted further up the thread, you can follow a similar strategy to create configuration which includes a shared module for validation purposes. If you put it in a directory under To do this, you can use a directory structure something like this:
The terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
# A placeholder provider configuration
provider "aws" {
region = "us-east-1"
}
module "m" {
source = "../.."
# (valid placeholder values for any required arguments)
providers = {
aws.replica = aws
}
} You can then do validation like this:
This gives the validate command a valid, root-module-headed configuration tree to work with, which it will then validate as a whole. I would like to support the validation of partial configuration trees (that is, a tree where the "root module" isn't really a root module) but this would be the first situation where Terraform's configuration loader and models would need to decode and represent such a thing, and so I expect there will be some semi-disruptive restructuring to do before it would be possible. The above is what can work with today's Terraform, and is in essence the same idea as writing a small stub program to exercise a library for testing purposes in a general-purpose language. That is the approach I'd recommend that module maintainers use today, and also consider the possibility of amortizing the work of setting that up by also using it for testing changes to your module during development, whether it be handled in bulk by |
Additional info is when a root module calls the child module as part of a for_each loop, then supplying the aliased provider inside the child module breaks the whole thing
Need a way to define/inject both a main azurerm provider, plus one other alias provider, that can be consumed by the child module as part of a for_each loop. I tried adding See below for code extract:
|
A work around I've used (in the case of just needing to run
Then just add to the CI script / GitHub action to rename it to |
Thanks for this workaround. It helped pass (success) the CI
|
… bug in terraform Workaround for hashicorp/terraform#28490
… bug in terraform Workaround for hashicorp/terraform#28490
… bug in terraform Workaround for hashicorp/terraform#28490
… bug in terraform Workaround for hashicorp/terraform#28490
… bug in terraform Workaround for hashicorp/terraform#28490
… bug in terraform Workaround for hashicorp/terraform#28490
Any new plans for a fix here? This is a frustrating bug. At the very least it would be nice if we could remove the
that comes with adding provider blocks to resolve this |
This comment was marked as off-topic.
This comment was marked as off-topic.
The original error is still there as of terraform v1.5.7 (latest non-alpha, non-beta) and 1.6.0-beta2. |
My earlier comment is the current recommendation. |
Terraform: 1.5.7 We're running a hub and spoke model in aws so we frequently have aliased providers passed into submodules to keep our code dry. However we've started encountering the below error in 1.5.7, which is related. This is a new module and new provider alias that have not been present in the state prior.
Root Config file:
Module Config file:
Code calling module:
When I run
For now I've added a provider config block with the alias to the child module as some people have mentioned and it validates, however that is exactly what the docs say not to do. |
Any chance this will get fixed? |
Due to closing other issues, this issue has broached the top 25 issues list for the first time. There is acknowledgement that the recommended work-around (#28490 (comment)) is not ideal and that this issue is likely to continue to be requested by the community. All that said, no other update at this time. |
We figured out this use case is better served by tools like pre-commit-terraform https://github.com/antonbabenko/pre-commit-terraform?tab=readme-ov-file#terraform_validate which includes more robust handling of terraform's quirks. Given that there are better solutions out there, we think it's best to remove this feature from collie and focus our resources on unique features. Additionally, using "terraform validate" is a bad fit for validating kit modules as it has big problems with configuration_aliases hashicorp/terraform#28490 It seems that it is much better suited to validating platform modules instead.
We figured out this use case is better served by tools like pre-commit-terraform https://github.com/antonbabenko/pre-commit-terraform?tab=readme-ov-file#terraform_validate which includes more robust handling of terraform's quirks. Given that there are better solutions out there, we think it's best to remove this feature from collie and focus our resources on unique features. Additionally, using "terraform validate" is a bad fit for validating kit modules as it has big problems with configuration_aliases hashicorp/terraform#28490 It seems that it is much better suited to validating platform modules instead.
https://github.com/bendrucker/terraform-configuration-aliases-action is a great workaround for this issue when using GitHub Actions to run validation. Thanks, @bendrucker! For anyone who don't want to depend on a third party GitHub Actions you can use the following steps in your workflow: # Support validation with Terraform provider configuration aliases - Cause: https://github.com/hashicorp/terraform/issues/28490
## Install Terraform Config Inspect
- name: "Install Terraform Config Inspect"
run: |
go install github.com/hashicorp/terraform-config-inspect@6714b46f5fe438558e2703a7ac4275e768425081
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
## Extract provider configuration aliases
- name: "Extract provider configuration aliases"
working-directory: ${{ inputs.working_directory }}
run: |
terraform-config-inspect --json . | jq -r '
[.required_providers[].aliases]
| flatten
| del(.[] | select(. == null))
| reduce .[] as $entry (
{};
.provider[$entry.name] //= [] | .provider[$entry.name] += [{"alias": $entry.alias}]
)
' | tee aliased-providers.tf.json |
Terraform Version
Terraform Configuration Files
Expected Behavior
Expected to see valid configuration errors for any resource referencing the alias provider.
Actual Behavior
Errors on all resources using the alias provider. What I find interesting is that it says that the resources are in state, but there's no state, per
terraform show
.Steps to Reproduce
terraform init
terraform validate
Additional Context
This is a child module that I've migrated from v0.14.4. It was originally using proxy provider configuration. I tried running a validate on directly it after adding in the
configuration_aliases
setting. I'm able to run an apply on a main.tf that references it, but just not able to validate the child module.References
The text was updated successfully, but these errors were encountered: