If you have just removed a module declaration from your Terraform configuration and now get a ‘Provider configuration not present’ error when running apply:
Error: Provider configuration not present To work with module.mymodule_legacysyntax.null_resource.test_rs (orphan) its original provider configuration at module.mymodule_legacysyntax.provider["registry.terraform.io/hashicorp/null"] 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.mymodule_legacysyntax.null_resource.test_rs (orphan), after which you can remove the provider configuration again.
Then the module is using a legacy method of including provider blocks directly in its module definition. Either you have:
- [Scenario #1] Removed the declaration of the module completely
- [Scenario #2] Removed a single direct provider from inside the module itself
Download Example
In order to recreate the issue and provide a resolution, I’ve created a sample project on github. It uses only local providers (time and null) and local file state to avoid any cloud infrastructure charges.
git clone https://github.com/fabianlee/tf-example-modules-legacy-and-newer-syntax cd tf-example-modules-legacy-and-newer-syntax terraform init terraform apply
If you look at main.tf, you can see it includes a module.
module mymodule_legacysyntax { source = "./module-legacy-syntax" }
And this module definition, module-legacy-syntax/main.tf, uses a legacy method of directly including its own provider blocks.
# legacy syntax (< v0.10) of provider blocks directly inside module provider null { } provider time { }
Scenario 1: Recreate issue with entire module removal
Comment out the module definition in main.tf to simulate our attempt to remove this module from management.
#module mymodule_legacysyntax { # source = "./module-legacy-syntax" #}
Run “terraform apply”, and you will now see the “Error: Provider configuration not present” error.
Resolve issue with entire module removal
Reinclude the module back in main.tf
Remove the pound sign comments to re-include the module definition.
module mymodule_legacysyntax { source = "./module-legacy-syntax" }
Rerun “terraform init”
terraform init
In a more complex configuration, you may have to use “terraform init −−upgrade”.
Remove the module from Terraform state
# terraform remove −−target module.<moduleName> terraform destroy --auto-approve --target module.mymodule_legacysyntax
Remove the module definition from main.tf
Only now that the module is removed from state should you remove the module definition. We will comment it out again.
#module mymodule_legacysyntax { # source = "./module-legacy-syntax" #}
Rerun “terraform apply”
With the module removed from Terraform state and now also the main.tf definition, apply should run without errors.
terraform apply
Scenario 2: Recreate issue with removal of provider block inside legacy module
There is another scenario to consider where we own and control the legacy module code, and we do not remove the entire module (like first example). Instead we remove a single legacy provider block in the module.
Consider the code in module-legacy-syntax/main.tf where we have a “null” and “time” provider. If we comment out the null provider and its resources like below.
# commenting out null provider #provider null { } provider time { } # commenting out use of null provider #resource null_resource test_rs {} #resource null_resource test_rs2 {} #data null_data_source test_ds {}
Then ran “terraform apply”, we would get the “Error: Provider configuration not present” message for the same reason we got it when removing the entire module.
Resolve issue with removal of single legacy provider block
Reinclude the provider definition back in module-legacy-syntax/main.tf
# reinclude 'null' provider and its resources provider null { } provider time { } # commenting out use of null provider resource null_resource test_rs {} resource null_resource test_rs2 {} data null_data_source test_ds {}
Re-run “terraform init”
terraform init
In a more complex configuration, you may have to use “terraform init −−upgrade”.
Remove all the associated resources from Terraform state
This is the most complex step, because you will need to remove each of the resources associated with this single provider from the Terraform state. The command will be in the syntax below:
terraform remove −−target module.<moduleName>.<resourceType>.<resourceName>
The best way to identify these is to parse the Terraform state file with a yaml/json parser. If your Terraform state is remote, then temporarily pull it down for parsing.
[[ -f terraform.tfstate ]] || terraform state pull > terraform.tfstate
Then run the Terraform state file through a json parser to identify all the resources associated with the single provider.
# make sure jq json parser utility is installed sudo apt install -y jq # variables defining module and provider we want to remove my_module="module.mymodule_legacysyntax" my_module_source="hashicorp/null" # jq expression that prints terraform destroy commands that need to be run # you MUST run each of these manually jq -r ".resources[] | select(.module == \"$my_module\" and .mode == \"managed\" and (.provider | contains(\"$my_module_source\")) ) | [.module,.type,.name] | @csv" terraform.tfstate | sed 's/\"//g; s/,/\./g' | xargs printf "terraform destroy --auto-approve --target %s\n"
With all the resources associated with this provider now removed from the Terraform state, we can remove the provider and its resources from the configuration.
Remove the provider definition and it resources from module-legacy-syntax/main.tf
# commenting out null provider #provider null { } provider time { } # commenting out use of null provider #resource null_resource test_rs {} #resource null_resource test_rs2 {} #data null_data_source test_ds {}
Rerun “terraform apply”
With the resources associated with this single provider removed from Terraform state, apply should run without errors.
terraform apply
REFERENCES
Terraform docs, legacy shared modules with provider configurations
github fabianlee, example project for this article, tf-example-modules-legacy-and-newer-syntax
github issue, showing steps how to resolve error
NOTES
yq equivalent command to identify resources
yq e ".resources[] | select(.module == \"$my_module\" and .mode == \"managed\" and (.provider | contains(\"$my_module_source\")) ) | [.module,.type,.name]" terraform.tfstate -o=csv | sed 's/,/\./g' | xargs printf "terraform destroy --auto-approve --target %s\n"