Refactoring
You may need to move resources between stacks as your CDK for Terraform (CDKTF) application grows in size and complexity. This guide demonstrates how to refactor your stacks. In general you can change the names of stacks freely without an effect on the synthesized code. If you change the name of a resource this might lead to a re-creation of the resource, especially if you move the resource from one stack to another.
Moving & Renaming Resources Within a Stack
You may want to rename a deployed resource in a stack, like the S3Bucket
in the following example.
When you run a cdktf plan
, the CLI may display the following output:
Terraform plans to destroy the old bucket and create a new one to replace it. The replacement can be harmful if there is already state in the resource, such as files in the bucket or data in the database.
To avoid this recreation behavior, use one of the move instance functions (moveTo
, moveToId
, moveFromId
) available on the resource.
Performing Resource Moves
The moveTo
function is available on all resources and is used for relocating a resource to the location specified by the string target moveTarget
. To set a resource's moveTarget
, use the addMoveTarget
function that is present on the resource to move to. You can specify an arbitrary string for the moveTarget
, but it must be unique within your stack.
After deployment, both the resource being moved and the move target on the destination resource can be removed.
Move Targets
A moveTarget
is accessible anywhere within the context of the stack where it is created, including the root of the stack and within a nested construct. This workflow does not support moving resources to a different stack.
Enabling foreach
on a Resource
To incorporate a deployed resource into a foreach
composition without destroying the resource, specify an index as a second argument in the moveTo
function. The index should correspond to the key in the TerraformIterator
named iterator
.
This allows you to efficiently integrate existing resources into a foreach
composition without destroying the existing deployed resource.
Move By Resource Address
In instances where the move target workflow does not easily fit your use case, resource moves can be performed by directly specifying the full resource address to be moved to/from.
Move To
Move From
Note that in moving from a specified resource address, the original resource being moved from must be removed.
Nested Constructs
Resource addresses in the context of nested constructs will not simply be the specified id given to the resource. When dealing with moving resources by their address to/from nested constructs, run cdktf synth
and refer to cdktf.out/stacks/'your stack name'
to find the exact address to move to/from.
Moving or renaming modules
To change the id of a module without losing its state use the terraform state mv
command. This command needs to be run in the output directory of the stack that contains the module. Commonly this is cdktf.out/stacks/<stack-name>
. The command takes two arguments, the first is the current id of the module, the second is the new id of the module.
For further details on the terraform state mv
command refer to the Terraform documentation.
Moving Resources From One Stack To Another
You may want to move a resource from one stack to another, like the following example aws S3Bucket
resource.
When you run a cdktf deploy '*'
, the CLI displays the following output.
To preserve the state of the resource, you must move it from one stack to another. You can use terraform import
and terraform state rm
to move the resource's state. First we need to find the Terraform name of the Resource in the old stack.
Now we need to find the name of the resource in the new stack to understand where to move the resource to.
We need to find the id of the resource, we can use the terraform state show
command to find it. The id is depenendent on the resource being imported, see the import docs for more details. We need to run these commands in the directory of the stack we are importing the resource from.
Now that we have the id ("my-bucket20221208141249058600000001"
) we can import it. This command needs to be run in the directory of the stack we are importing the resource to.
We have imported the resource in the new stack, but we still need to remove it from the old stack. This command needs to be run in the directory of the stack we are removing the resource from.
We can verify everything worked as expected by running a cdktf deploy '*'
again. We should now see no changes.
Why Do I Need To Find The Terraform Name Of The Resource?
If you use Constructs to organize your code, you might have a level between the generated provider constructs and the TerraformStack
construct to organize your code.
This extra level adds a prefix to the name of the resource to ensure uniqueness. Refer to Constructs for more details.