Use configuration to move resources
As your Terraform configuration grows in complexity, updating resources becomes more risky: an update to one resource may cause unintended changes to other parts of your infrastructure. One way to address this is to refactor your existing Terraform code into separate modules. In addition to limiting the scope of potential changes, modules help abstract your resources, making your configuration easier to understand.
When you move existing resources from a parent to a child module, your Terraform resource IDs will change. Because of this, you must let Terraform know that you intend to move resources rather than replace them, or Terraform will destroy and recreate your resources with the new ID.
The moved
configuration block lets you track your resource moves in the
configuration itself. With the moved
configuration block, you can plan,
preview, and validate resource moves, enabling you to safely refactor your
configuration.
In this tutorial, you will create several AWS resources, and then divide them
into compute and security group modules. Then, you will use the moved
block to
refactor your configuration and update resource IDs, and review the
corresponding state changes before you apply the new configuration.
Prerequisites
You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects. It includes features like remote state and execution, structured plan output, workspace resource summaries, and more.
Select the HCP Terraform tab to complete this tutorial using HCP Terraform.
This tutorial assumes that you are familiar with the Terraform workflow. If you are new to Terraform, complete the Get Started tutorials first.
In order to complete this tutorial, you will need the following:
- Terraform v1.3+ installed locally.
- An AWS account with local credentials configured for use with Terraform.
Clone the example configuration
Clone the example repository for this tutorial.
Change to the repository directory.
This configuration contains a VPC module, a security group module that allows
ingress HTTP traffic on port 8080
, and an EC2 instance resource that uses the
security group and VPC. Later in this tutorial, you will move these resources
into modules to make your configuration more manageable.
Initialize and apply the configuration
Initialize this configuration.
After Terraform initializes, apply the configuration and approve the run by
typing yes
at the prompt.
Test your instance availability with the curl
command.
In the next section, you will refactor your configuration into modules.
Refactor your configuration
In this example, you have a small number of resources to manage. However, an operational environment may consist of many more resources and be difficult to manage in a single configuration file. By organizing these resources into modules, your configuration becomes flexible, reusable, and composable.
Create a new compute
subdirectory in the modules
directory.
Create a new variables.tf
file in the modules/compute
directory to capture
your module's input variables. You will use these variables to configure your
module.
Then, create a new main.tf
file in the modules/compute
directory.
Cut and paste the AMI data source and the EC2 instance resource from main.tf
to modules/compute/main.tf
.
After you paste these blocks into modules/compute/main.tf
, update the
configuration to use the variables you defined in
modules/compute/variables.tf
.
Finally, create a new outputs.tf
file with an output value for your instance's
IP address. You will use this output to pass as a variable into another module.
Now modules/compute
contains a modified version of the initial Terraform
configuration for your EC2 instance.
Update configuration to use modules
Replace the EC2 instance resource with the local module you just created, and the security group with the AWS security-group module from the Terraform Registry.
In your main.tf
file, remove the security group module, you will replace it
with a module from the Terraform public registry.
Then, add new module
blocks to the end of your configuration.
Save your changes.
Update the outputs.tf
file in the root directory to use the output value from
the compute module.
Review planned changes
Next, reinitialize your configuration to install the new modules.
Now that Terraform recognizes the new modules, generate a plan to observe the changes.
Your module changes would delete and recreate your resources, which could cause
service interruptions. In the next section, you will use Terraform's moved
block to refactor your configuration to use modules without destroying the
existing resources.
Move your resources with the moved
configuration block
With the moved
configuration block, you can inform Terraform about all
resource address changes in your configuration. Terraform also validates those
changes to provide you with clearer operational output and you can safely review
plans before applying.
In your root main.tf
file, add moved
configuration blocks for the resources
you moved in the previous step.
Re-apply your configuration to move your resources into your new moduless and
update the resource IDs. Confirm your changes with yes
after you verify that
Terraform will move your resources instead of replacing them.
Your instance ID changed, but the resource did not. The security group and its rules were updated in-pace when they moved because the new module includes default values for some attributes that the old module did not.
Rename and move a resource
You can also use the moved
configuration block to rename existing resources.
In the root of your configuration, open the main.tf
file.
Rename your vpc
module, and update the references to it in the rest of your
configuration.
Add the moved
block for your VPC changes at the bottom of the file.
Run terraform init
to update your VPC module's name.
Apply your changes. Confirm your changes with yes
after you verify there are
no resource changes.
Note
We strongly recommend you retain all moved
blocks in your
configuration as a record of your changes. Removing a moved
block plans to
delete that existing resource instead of moving it.
Clean up your resources
Remove the infrastructure you created in this tutorial. Respond to the
confirmation prompt with a yes
.
If you used HCP Terraform for this tutorial, after destroying your resources, delete the learn-terraform-move
workspace from your HCP Terraform organization.
Next steps
In this tutorial, you created an EC2 instance and supporting networking
resources. Then, you refactored your Terraform configuration into modules.
Finally, you used the moved
configuration block to safely update the resource
IDs.
For more information on modules and state, review the following resources:
- Review the Terraform
Documentation
on the
moved
configuration block. Learn to use themoved
configuration block with resources containing thefor_each
orcount
functions. - Follow the Build and Use a Local Module tutorial to review how to create a module.
- Follow the Manage Resources in Terraform State tutorial to learn other methods for updating your state file.
- Follow the Manage Resource Lifecycle tutorial and use the different lifecycle management options available in Terraform to prevent resource deletion.