
Getting Out of Tricky Terraform Situations
Learn how to troubleshoot common Terraform issues on AWS, including state drift, provider errors, timeouts, and upgrade failures in multi-environment setups.
Automated infrastructure configuration is an important ingredient when building a robust application. We’ve used Terraform for several recent projects, and my current project relies on it to maintain a significant and growing AWS deployment.
We use Terraform to manage all of our deployed environments, including around twenty feature environments that developers use to build, test, and coordinate business stakeholder review before merging back to our mainline development branch (our version of Heroku’s review apps for feature branches).
While it works great most of the time, there are times that Terraform gets twisted into digital knots, especially on those feature environments where we tend to play a bit rough with the infrastructure. Here are some situations I’ve encountered and some tools and tips to get through them.
ResourceAlreadyExistsException
We’ll start on the simpler end of the spectrum. While attempting to run a
terraform apply for one of our environments, we saw an error message stating that a resource already exists, something like this:1
2
3
4
Error: creating Transfer User (s-****************/sftp_user_1): operation error Transfer: CreateUser, https response error StatusCode: 400, RequestID: ******-****-****-****-************, ResourceExistsException: User already exists
with aws_transfer_user.transfer_user["sftp_user_1"],
on sftp-user.tf line 1, in resource "aws_transfer_user" "transfer_user":
1: resource "aws_transfer_user" "transfer_user" {
This error occurs when Terraform tries to create a resource that already exists in AWS. In this case, it's trying to create a Transfer User that has already been created. This can happen if the resource was created outside of Terraform or if there was a previous failed attempt to create it.
To resolve this issue, you have a few options:
- Import the existing resource into Terraform state using the
terraform importcommand. - If the resource is not needed, manually delete it from the AWS console and then run Terraform again.
- If the resource should be managed by Terraform, update your Terraform configuration to match the existing resource's settings.
In our case, we decided to manually delete the conflicting Transfer User from the AWS console. After deletion, we were able to run our Terraform commands successfully. While we generally avoid manual changes to Terraform-managed infrastructure, sometimes it's necessary to resolve conflicts like this. Also, I’ve worked through a similar situation with API Gateway Stages that wasn’t as easy. There were other dependencies that had to be traced and deleted before I could delete the Stage itself, but in the end, deleting the conflicting resources let us run the Terraform commands we needed.
Error: Provider Configuration Not Present
I am trying to refactor some terraform module that we build earlier and it went to update a feature environment and ran into a problem. Terraform complained that the provider configuration was missing for some resources that needed to be destroyed — the same resources that weren’t in the configuration anymore.
1
2
3
4
5
6
7
8
9
10
11
Error: Provider configuration not present
To work with
module.my_module.some_resource.resource_name its
original provider configuration at
module.my_module.provider.some_provider.provider_name 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.my_module.some_resource.resource_name, after
which you can remove the provider configuration again.
It turns out that this can happen after removing a module that had a module-local provider configuration, which we had in our configuration. Per the Terraform docs on Providers Within Modules :
For backward compatibility with configurations targeting Terraform v0.10 and earlier, Terraform does not produce an error for a provider block in a shared module if the module block only uses features available in Terraform v0.10, but that is a legacy usage pattern that is no longer recommended.
To get past the problem, we checked out a version of our configuration that still had the module included and ran a targeted destroy against the offending resources. Running a
terraform destroy normally tears down the entire configuration, but you can use the -target option to select specific resources when you need to resolve situations like this one. Read the docs on resource targeting for more information.After removing the resources, we were able to return our git repository to the current state and apply our changes.
Timeout Waiting for a Resource to Be Created
Sometimes when creating or destroying resources in AWS using Terraform, timeouts happen. We’ve seen it happen most with resources like CloudFront distributions, Aurora clusters, and sometimes DNS records and certificates. They can take quite a while to create no matter how you do it.
Most of the time, just waiting a few minutes and then re-running the command is enough to resolve the problem. Or, if you want to watch the paint dry, pull up the resource in the AWS web console and watch until it completes. Then re-run your Terraform command.
Random Dependency Failure
Hmmm. This worked before… Why is it failing now with a dependency problem?
We’ve noticed a few times that our
terraform apply would fail with strange dependency messages, despite having succeeded with the same configuration before. It seems like sometimes there’s a propagation delay in the AWS infrastructure. Terraform knows it finished creating, say, a DNS entry, but when it tries to create a certificate that references it, AWS fails the command saying it doesn’t know about the DNS entry — even though we can see it in the AWS web console.Most of the time, just re-running the command is enough to get past the problem.
Upgrades, Upgrades, Upgrades — Oops!
There are updates to Terraform on a fairly regular basis. While that’s great, I appreciate progress, it needs consideration because mismanaged updates can make it difficult to get caught back up and apply infrastructure changes. Terraform’s documented recommendation for upgrading to v0.13 mentioned this workflow:
When upgrading between major releases, we always recommend ensuring that you can run terraform plan and see no proposed changes on the previous version first, because otherwise pending changes can add additional unknowns into the upgrade process.For this upgrade, in particular, completing the upgrade will require running terraform apply with Terraform 0.13 after upgrading in order to apply some upgrades to the Terraform state, and we recommend doing that with no other changes pending.
Because we have a large collection of feature review environments (around twenty), it’s easy for one to get left behind after an upgrade. We had at least a few instances where that happened. Here are some recommendations to make it easier on yourself:
- Make it easy to identify what version of code and infrastructure is deployed to each environment so that when you need to, it’s easy to go back and follow the proper upgrade steps without infrastructure changes getting in the way.
- Use tfenv to manage installations of Terraform so that your whole team can stay on the same version and can more easily jump back to older versions when needed.
- When you upgrade Terraform, coordinate applying that upgrade to as many environments as you can.
Use Terraform; Avoid the Traps
Terraform is a handy tool, and it helps to know what the rough edges look like every tool has them.
I hope this helps you work through them.
Conclusion
Terraform is a powerful tool for managing complex AWS infrastructure, but as environments scale especially with short-lived or experimental feature environments, edge cases are inevitable. Most issues stem from state drift, provider configuration changes, AWS propagation delays, or unmanaged upgrades rather than from Terraform itself.
By understanding these common failure modes and applying disciplined practices, careful state management, targeted operations, version control with tools like
tfenv, and coordinated upgrades, you can quickly recover from most problems. When used thoughtfully, Terraform continues to deliver reliable, repeatable infrastructure, even in fast-moving and occasionally messy development environments.Frequently Asked Questions (FAQ)
Why does Terraform say a resource already exists in AWS?
- This usually happens when a resource was created manually or Terraform state is out of sync. Importing the resource or deleting it manually resolves the issue.
How do I fix Terraform provider configuration not present errors?
- Re-add the original provider configuration or use a targeted destroy to remove orphaned resources from state.
Why does Terraform fail randomly on AWS?
- AWS has eventual consistency delays. Re-running
terraform applyoften resolves transient dependency failures.
What is the best way to manage Terraform versions across teams?
- Use tools like tfenv and coordinate Terraform upgrades across all environments.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article