Search code examples
terraformterraform-provider-awsterraform-provider-azure

How Terraform plan and Terraform destroy related to the state file?


How does terraform plan and destroy relate to the state file.

When Terraform performs a plan,

  • How does it know that the desired state in our manifest file is same as the current state of the resource in the azure portal? Is it by checking with the azurerm api directly or by referring to the state file?

  • If it's referring the state file, how does the terraform plan get validated for the first time plan, while it doesn't yet have a state file (as it's only a terraform apply that will generate a state file?

  • Secondly, does the terraform destroy command has any reference to the our manifest file (desired configuration file), or will it just validate the state file with the current state (the resource actual status in the azure portal)


Solution

  • Some basic explanation:

    A terraform plan basically validates your code against the terraform azurerm provider to check whether your code is correct, whether it satisfies the requirement of the Azure API (e.g. using the right attributes, types etc). If everything is good, it does a dry run and shows you what is going to happen when you do a terraform apply. At this point, terraform is not aware of what exists or does not exist in Azure, it only does a dry run to give you an idea. This means that even if your terraform plan successful, your terraform apply will not necessarily be successful.

    Remember that the azurerm provider is more of a wrapper on top of the Azure API. It does its own validation based on the requirements of the Azure API.

    Now to your questions:

    How does it know that the desired state in our manifest file is same as the current state of the resource in the azure portal? Is it by checking with the azurerm api directly or by referring to the state file?

    For any resource created by Terraform, Terraform will always verify against the state file. The only time it checks with the Azure API is when it has to interact with the resources.

    If it's referring the state file, how does the terraform plan get validated for the first time plan, while it doesn't yet have a state file (as it's only a terraform apply that will generate a state file?

    Refer to basic explanation. It goes back to the way a terraform plan works. Because it's an execution plan, it does not need the state file yet. The state file is only holds information of what has been created in Azure, or what has been imported from Azure. It's information about actual existing resources. A terraform plan only does a dry-run/test/simple validation to let you know whether your code is good enough to proceed to the next step: terraform apply.

    Secondly, does the terraform destroy command has any reference to the our manifest file (desired configuration file), or will it just validate the state file with the current state (the resource actual status in the azure portal)

    When Terraform objects are saved in the state file, they are coupled to an Azure Object using the Azure resource ID. A terraform destroy similar to a plan or apply will still use the state file as its understanding of the real world (Current state in Azure). If you remove a Terraform object from your Terraform code, a destroy will crosscheck against the state file and notice that this resource exists in the state file. Since it exists in the state file but is being removed from your code, Terraform will then send a request to destroy that resource.

    Take a look at some scenarios below that you can try, which might help you understand better.

    Scenario 1

    1. Let's say you create a Storage Account with the name ststorageaccount, from the Azure Portal.
    2. Then you proceed to write the Terraform code to create the same Storage Account and do a terraform plan. You will notice that the execution plan is not aware that this Storage Account already exists and the execution plan shows an attempt to create it again.
    3. Since the plan was 'successful', you then proceed to do a terraform apply. You now receive an error saying that the Storage Account ststorageaccount already exist and needs to be imported in the state file. The terraform apply stage is when Terraform's azurerm provider starts interacting with the Azure API to create the resources. The Azure API being aware of the state in Azure, is the one that throws that error to Terraform and subsequently to you.
    4. Since Terraform was not able to successfully create the Storage Account, it does not add it to the state file and asks you to import it manually instead.

    Scenario 2

    1. You write the Terraform code to create a certain resource in South East Asia region.
    2. You perform a terraform plan and again since Terraform only validates your code against Terraform's azurerm provider, it shows you a successful execution plan.
    3. You proceed with the terraform apply but now receive an error saying that the region is wrong it has to be SouthEastAsia (without spaces) instead.
    4. This happens because the Terraform azurerm provider accepts South East Asia while the Azure API for that specific resource requires the region to be written differently.

    So you can see these are two cases that show how terraform plan and terraform apply behave differently because they work on two different 'planes'.