Why does a plan lock the state file?

(using Terraform v0.11.14)

A question regarding the default behaviour in terraform: why does a terraform plan default to locking the state file? As the locking document says:

If supported by your backend, Terraform will lock your state for all operations that could write state. This prevents others from acquiring the lock and potentially corrupting your state.

Yet the plan operation does not write state (and could not , AFAIK).

Is this an anachronism, left over from when it did write state?

Hey @leg100,

This is a good question! My understanding is for the reason for Terraform locking state during a plan is due to the auto-trigger of terraform refresh as part of the plan.

Terraform will review the existing state and ensure that the resources that are defined in statefile are as explicitly declared in HCL.

For example, I create a vanilla AWS EC2 instance via Terraform. Then I go to the AWS UI and manually add a tag to the instance. On the next plan after than manual change has happened. The refresh part of the plan would state detect the drift (removal of the tag) due to the manual UI change.

Hopefully, that clears things up. Otherwise, as you know - there is always the official documentation.

1 Like

Hi @mpmsimo

Thanks for the response. But I don’t think you’re quite right.

If you run a plan, you’ll immediately see the following message:

Refreshing Terraform state in-memory prior to plan…
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

I believe what you say was once correct, a plan did in effect run terraform refresh, which does persist to state. But, like I said in my original question, a plan no longer does this, instead refreshing the state ‘in-flight’.

So the question still stands…why lock?

@leg100, looks like you suspicions are correct.

As you’ve said the terraform refresh and terraform plan are done in different phases. I had previously referenced the Terraform documentation which didn’t go into the level of detail we wanted. In this case it made sense to review the codebase.

Enforcing a locked statefile is the default behavior when using terraform CLI plan command.

As locking is intentional, explicitly passing in the -lock=false argument to the CLI command is the way to override this behavior…

I know this is the default (it is documented, there is no need to go into the code). There is no reason for it to be offered as an option, AFAICS.

It would be good if someone familiar with the history of terraform or a core contributor could answer this.

I have had locking help prevent interruption if multiple people are accessing the same statefile.

I will leave it up to someone more knowledgeable on this topic to give you an exact answer, since I don’t have that historical context of the codebase.

Is the locking during plan not simply a way to avoid someone else’s writes from corrupting your plan if they happen during the read of the current state?

@Richard-Payne A read is an atomic operation, so no.

There are a dozen backend types, and I haven’t looked into the ACID properties of each and every one, but it’s fair to assume that any database or filesystem worth its salt will guarantee to avoid what you describe.

If what you describe were true, you’d never have confidence reading from anything!