Skip to main content

Terraform State Walkthrough

Author by Michael Dugan

This blog post appears as part of a Terraform Classroom walkthrough that can be found here.

Let’s talk about state management. Terraform provides the state command as a means of manipulating resources that it knows about. Typically, something about your environment configuration must be updated if you’re planning on using these CLI commands and luckily these commands are easy to use! Terraform does the heavy lifting for you that will assess whether a push, move, or any other request can be done and will carefully do so. In fact, it intentionally creates a backup state file so a simple mistake could be reversible by re-uploading the previous state file. It is important to note that this situation applies to both a local state file as well as a remote state file in a backend configuration since Terraform requires initialization of a state file before working on any code.

Here’s the usage syntax, if you aren’t familiar already: terraform state <subcommand> [options] [args]

Let’s start out by showing what we currently have in the state file via the CLI. Run the following command:

terraform state list



Notice that all these resources do not have a module specified at the beginning of their configuration name. Declaring resources in a static file means that you are expecting these resources to live forever and are essentially running constants. This makes sense for Azure Resource Groups, but not for the other resources that should belong in a networking module for reusable code. Let’s run the following command to move the subnet into a new module:

terraform state mv azurerm_subnet.appgate_sn module.networking



The previous command is basically saying let’s move a terraform resource into a different state, and let’s name it “networking”. Now, let’s repeat this process for the other virtual networks along with the peerings and check against our updated configuration in the file. Here’s the output:


Here’s what the updated state list looks like now:


Now, let’s see what we get when we run a plan. Terraform should expect 0 changes needed and should be happy. Run a plan command and target a specific variable file if you aren’t loading variables automatically (e.g.: terraform plan -var-file=".\variable_inputs\non_production.tfvars"). Here’s the output:


Perfect! Let’s make sure this is the case by applying the updated local configuration and ensure that state is updated (e.g.: terraform apply -var-file=”.\variable_inputs\non_production.tfvars”). Here’s the output:


There you have it – a state file that has been updated with resources in a new module. What this allows for is repeatability, as we are placing resources in a different file that can be referenced in other parts of Terraform infrastructure. This will help save time when creating other resources and can help with design concepts for other “toolsets” that might be needed in the future.

Thanks for reading!


Michael Dugan

Senior Systems Engineer