"I’ve recently come across an interesting scenario in our Azure-based infrastructure using Terraform Cloud. We’ve updated our AzureRM provider on multiple workspaces and also updated the Terraform runtime version. We have both health checks and drift detection turned on.
What we’ve noticed is that when we run a standard plan, even if the infrastructure hasn’t changed, the plan comes back with no changes and auto-applies. However, when we run a ‘terraform refresh-only’ command, we see that there are missing Arguments in the state file, but they seem to be new optional Arguments and the values in the refresh-only plan is their default values.
I was under the impression that when Terraform Cloud does a plan, it uses the state file to compare the current resources, but I’ve read elsewhere that in the cloud, Terraform Plan checks your code against the real infrastructure while the ‘refresh-only’ command checks the state file against the infrastructure.
Can anyone clarify this for me? Does the ‘terraform plan’ command only compare the code and real infrastructure while the ‘refresh-only’ command compares the state and real infrastructure?
References:
Understanding ‘terraform plan/apply -refresh-only’, the myths and fixing drift | by Soon Hin Khor, Ph.D. | Code Oil | Jan, 2023 | Medium"
Command: plan | Terraform | HashiCorp Developer
when doing a ‘terraform plan’, no matter if is run from terreform cloud, it is a three-way-reconcile, between what you want(code), what terraform remembers(state) and the reality(cloud).
when you have refresh-only flag, it becomes a one way sync from the reality(cloud) to what terraform remembers(state).
1 Like
Hi @john.ward,
I think the inconsistency you have noticed is caused by the fact that current Terraform CLI versions hide the “Note: Objects changed outside of Terraform” section unless the changes that would be reported there seem related to other actions Terraform is proposing.
We made that change in response to very loud feedback that the “Objects changed outside of Terraform” was not something folks found useful in typical use. The compromise was to show it only based on a heuristic that tries to detect whether each change detected outside of Terraform can be associated with at least one planned change that it appears to have been the cause of, by tracking inter-resource relationships based on expression references.
When you run Terraform in the refresh-only planning mode, the “objects changed outside of Terraform” part of the plan is the only part Terraform generates, because refresh-only mode disables planning any potential changes to the infrastructure. Therefore in that case Terraform CLI will show the full set of changes outside of Terraform unconditionally, thereby revealing some differences that were hidden when you created a normal plan.
Terraform is still performing that refresh step during normal planning, but the CLI layer ignores that part of the generated plan unless the heuristic matches. Applying a normal plan will also commit the same updates that a refresh-only plan would detect.
1 Like