10

I am attempting to create new resources on GCP with a remote backend After doing terraform init plan -out=tfplan and then terraform apply tfplan I get the following error:

Error: Inconsistent dependency lock file
│ 
│ The following dependency selections recorded in the lock file are
│ inconsistent with the configuration in the saved plan:
│ Terraform 0.13 and earlier allowed provider version constraints inside the
│ provider configuration block, but that is now deprecated and will be
│ removed in a future version of Terraform. To silence this warning, move the
│ provider version constraint into the required_providers block.
│ 
│ (and 22 more similar warnings elsewhere)
╵
│   - provider registry.terraform.io/hashicorp/aws: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/external: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/google-beta: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/google: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/local: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/null: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/random: required by this configuration but no version is selected
│ 
│ A saved plan can be applied only to the same configuration it was created
│ from. Create a new plan from the updated configuration.
╵
╷
│ Error: Inconsistent dependency lock file
│ 
│ The given plan file was created with a different set of external dependency
│ selections than the current configuration. A saved plan can be applied only
│ to the same configuration it was created from.
│ 
│ Create a new plan from the updated configuration. 

On the other hand when I do it terraform init plan and apply -auto-approve its working with no issues

Shay Pinchasi
  • 131
  • 1
  • 1
  • 6

3 Answers3

15

Part of the work of terraform init is to install all of the required providers into a temporary directory .terraform/providers so that other Terraform commands can run them. For entirely new providers, it will also update the dependency lock file to record which versions it selected so that future terraform init can guarantee to make the same decisions.

If you are running terraform apply tfplan in a different directory than where you ran terraform plan -out=tfplan then that local cache of the needed provider plugins won't be available and thus the apply will fail.

Separately from that, it also seems that when you ran terraform init prior to creating the plan, Terraform had to install some new providers that were not previously recorded in the dependency lock file, and so it updated the dependency lock file. However, when you ran terraform apply tfplan later those changes to the lock file were not visible and so Terraform reported that the current locks are inconsistent with what the plan was created from.

The Running Terraform in Automation guide has a section Plan and Apply on Different Machines which discusses some of the special concerns that come into play when you're trying to apply somewhere other than where you created the plan. However, I'll try to summarize the parts which seem most relevant to your situation, based on this error message.


Firstly, an up-to-date dependency lock file should be recorded in your version control system so that your automation is only reinstalling previously-selected providers and never making entirely new provider selections. That will then ensure that all of your runs use the same provider versions, and upgrades will always happen under your control.

You can make your automation detect this situation by adding the -lockfile=readonly option to terraform init, which makes that command fail if it would need to change the dependency lock file in order to perform its work:

terraform init -lockfile=readonly

If you see that fail in your automation, then the appropriate fix would be to run terraform init without -lockfile=readonly inside your development environment, and then check the updated lock file into your version control system.

If you cannot initialize the remote backend in your development environment, you can skip that step but still install the needed providers by adding -backend=false, like this:

terraform init -backend=false

Getting the same providers reinstalled again prior to the apply step is the other part of the problem here.

The guide I linked above suggests to achieve this by archiving up the entire working directory after planning as an artifact and then re-extracting it at the same path in the apply step. That is the most thorough solution, and in particular is what Terraform Cloud does in order to ensure that any other files created on disk during planning (such as using the archive_file data source from the hashicorp/archive provider) will survive into the apply phase.

However, if you know that your configuration itself doesn't modify the filesystem during planning (which is a best practice, where possible) then it can also be valid to just re-run terraform init -lockfile=readonly before running terraform apply tfplan, which will therefore reinstall the previously-selected providers, along with all of the other working directory initialization work that terraform init usually does.


As a final note, tangential to the rest of this, it seems like Terraform was also printing a warning about a deprecated language feature and on your system the warning output became interleaved with the error output, making the first message confusing because it includes a paragraph from the warning inside of it.

I believe the intended error message text, without the errant extra content from the warning, is as follows:

Error: Inconsistent dependency lock file
│ 
│ The following dependency selections recorded in the lock file are
│ inconsistent with the configuration in the saved plan:
│   - provider registry.terraform.io/hashicorp/aws: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/external: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/google-beta: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/google: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/local: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/null: required by this configuration but no version is selected
│   - provider registry.terraform.io/hashicorp/random: required by this configuration but no version is selected
│ 
│ A saved plan can be applied only to the same configuration it was created
│ from. Create a new plan from the updated configuration.
╵
Martin Atkins
  • 62,420
  • 8
  • 120
  • 138
3

There could be various reasons but main reason is you might update your template and you might use some plugins in my case i updated my template and added random module solution to that problem is to upgrade lockfile with below command

terraform init -upgrade

it will install new modules and make lock file consistent automatically

Mansur Ul Hasan
  • 2,898
  • 27
  • 24
  • this was a life saver, after a corrupted tfstate file on s3 (I am using terragrunt). Note that this will work with terragrunt init --upgrade per module directory (as I had that problem) – Gorkem Feb 17 '23 at 18:28
1

When you do terraform init, it generates a file called .terraform.lock.hcl. Make sure you have this file in the directory where you are running terraform apply. If you are using CICD to run terraform, make sure the file is available too when running terraform apply.

For example, in a GitLab CICD pipeline, you can add these files in the cache:

cache:
  paths:
    - .terraform
    - .terraform.lock.hcl