<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IaC &#8211; My Shitty Code</title>
	<atom:link href="https://myshittycode.com/tag/iac/feed/" rel="self" type="application/rss+xml" />
	<link>https://myshittycode.com</link>
	<description>Embracing the Messiness in Search of Epic Solutions</description>
	<lastBuildDate>Fri, 28 Jul 2023 12:57:27 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://myshittycode.com/wp-content/uploads/2022/04/cropped-icon-32x32.png</url>
	<title>IaC &#8211; My Shitty Code</title>
	<link>https://myshittycode.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">205304208</site>	<item>
		<title>Terraform: Updating State Using &#8220;Moved&#8221; Block</title>
		<link>https://myshittycode.com/2022/04/30/terraform-updating-state-using-moved-block/</link>
					<comments>https://myshittycode.com/2022/04/30/terraform-updating-state-using-moved-block/#respond</comments>
		
		<dc:creator><![CDATA[Shitty Author]]></dc:creator>
		<pubDate>Sat, 30 Apr 2022 16:11:10 +0000</pubDate>
				<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Programming Language]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Terraform]]></category>
		<guid isPermaLink="false">https://myshittycode.com/?p=1926</guid>

					<description><![CDATA[<p>This post illustrates how you can rename existing resources or restructure the Terraform codebase without destroying and recreating the resources using moved block introduced in Terraform 1.1. It also explains some limitations using this new construct. PROBLEM: MODIFYING EXISTING RESOURCE NAME Using a simple resource block below as an example… On apply, one resource is [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2022/04/30/terraform-updating-state-using-moved-block/">Terraform: Updating State Using &#8220;Moved&#8221; Block</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>This post illustrates how you can rename existing resources or restructure the Terraform codebase without destroying and recreating the resources using <strong>moved</strong> block introduced in Terraform 1.1. It also explains some limitations using this new construct.</p>



<h2 class="wp-block-heading">PROBLEM: MODIFYING EXISTING RESOURCE NAME</h2>



<p>Using a simple resource block below as an example…</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
resource &quot;random_pet&quot; &quot;current&quot; {}
</pre></div>


<p>On apply, one resource is created and the state now tracks that resource.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state list
random_pet.current
</pre></div>


<p>When changing the resource name from <strong>current</strong> to <strong>new</strong>…</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
resource &quot;random_pet&quot; &quot;new&quot; {}
</pre></div>


<p>The generated plan indicates the resource will be destroyed and recreated, which may cause potential data loss (ex: if the resource is a database) or unintended ripple effects (because the resource ID has changed). </p>



<p>In this case, congratulations! We have become pet killers.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
# random_pet.current will be destroyed
# (because random_pet.current is not in configuration)
- resource &quot;random_pet&quot; &quot;current&quot; {
    - id        = &quot;willing-fowl&quot; -&gt; null
    - length    = 2 -&gt; null
    - separator = &quot;-&quot; -&gt; null
  }

# random_pet.new will be created
+ resource &quot;random_pet&quot; &quot;new&quot; {
    + id        = (known after apply)
    + length    = 2
    + separator = &quot;-&quot;
  }

Plan: 1 to add, 0 to change, 1 to destroy.
</pre></div>


<h3 class="wp-block-heading">Solving With Terraform Earlier Than 1.1</h3>



<p>Before Terraform 1.1, the only way to change the resource name without recreating the resource is to use <strong>terraform state mv</strong>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state mv random_pet.current random_pet.new
Move &quot;random_pet.current&quot; to &quot;random_pet.new&quot;
Successfully moved 1 object(s).
</pre></div>


<p>We can also verify that the resource name has changed in the state.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state list
random_pet.new
</pre></div>


<h3 class="wp-block-heading">Solving With Terraform 1.1</h3>



<p>Terraform 1.1 introduced <strong>moved</strong> block where the state change process can be done directly in Terraform source code without using <strong>terraform state mv</strong>.</p>



<p>To pull this off, we changed the resource name from <strong>current</strong> to <strong>new</strong>. Then, a <strong>moved</strong> block is added to facilitate the state change without affecting the provisioned resource.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
resource &quot;random_pet&quot; &quot;new&quot; {}

moved {
  from = random_pet.current
  to   = random_pet.new
}
</pre></div>


<p>Now, we can verify the generated plan to ensure the provisioned resource does not get destroyed and recreated before applying the move.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; highlight: [7]; title: ; notranslate">
# random_pet.current has moved to random_pet.new
resource &quot;random_pet&quot; &quot;new&quot; {
  id = &quot;willing-fowl&quot;
  # (2 unchanged attributes hidden)
}

Plan: 0 to add, 0 to change, 0 to destroy.
</pre></div>


<p>The state should have the updated resource name.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state list
random_pet.new
</pre></div>


<p>So, what if the <strong>moved</strong> block is left in the codebase, and we do another plan or apply?</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform apply
random_pet.new: Refreshing state... &#x5B;id=willing-fowl]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
</pre></div>


<p>As you can see, leaving the <strong>moved</strong> block in the codebase does not affect the state or the resource, and Terraform is smart enough to ignore it. In another word, once the &#8220;move&#8221; has occurred, we can safely remove the <strong>moved</strong> block.</p>



<h2 class="wp-block-heading">PROBLEM: RESTRUCTURING CODEBASE USING &#8220;FOR_EACH&#8221;</h2>



<p>Let&#8217;s try something a little more complicated. </p>



<p>Let&#8217;s assume we have 3 random pets where we call the resource block 3 times. Perhaps, you inherited the old codebase from pre v0.13 days where <strong>for_each</strong> construct was not introduced yet.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
resource &quot;random_pet&quot; &quot;a&quot; {}
resource &quot;random_pet&quot; &quot;b&quot; {}
resource &quot;random_pet&quot; &quot;c&quot; {}
</pre></div>


<p>Here&#8217;s how the state looks like.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state list
random_pet.a
random_pet.b
random_pet.c
</pre></div>


<p>Let&#8217;s assume we want to refactor the existing codebase to leverage the <strong>for_each</strong> construct.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
resource &quot;random_pet&quot; &quot;main&quot; {
  for_each = toset(&#x5B;&quot;a&quot;, &quot;b&quot;, &quot;c&quot;])
}
</pre></div>


<h3 class="wp-block-heading">Solving With Terraform Earlier Than 1.1</h3>



<p>With older version of Terraform, we have to perform the following <strong>terraform state mv</strong> 3 times.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state mv random_pet.a &#039;random_pet.main&#x5B;&quot;a&quot;]&#039; 
Move &quot;random_pet.a&quot; to &quot;random_pet.main&#x5B;\&quot;a\&quot;]&quot;
Successfully moved 1 object(s).

$ terraform state mv random_pet.b &#039;random_pet.main&#x5B;&quot;b&quot;]&#039; 
Move &quot;random_pet.b&quot; to &quot;random_pet.main&#x5B;\&quot;b\&quot;]&quot;
Successfully moved 1 object(s).

$ terraform state mv random_pet.c &#039;random_pet.main&#x5B;&quot;c&quot;]&#039; 
Move &quot;random_pet.c&quot; to &quot;random_pet.main&#x5B;\&quot;c\&quot;]&quot;
Successfully moved 1 object(s).
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state list 
random_pet.main&#x5B;&quot;a&quot;]
random_pet.main&#x5B;&quot;b&quot;]
random_pet.main&#x5B;&quot;c&quot;]
</pre></div>


<h3 class="wp-block-heading">Solving With Terraform 1.1</h3>



<p>To pull this off with Terraform 1.1, we call the <strong>moved</strong> block 3 times.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
resource &quot;random_pet&quot; &quot;main&quot; {
  for_each = toset(&#x5B;&quot;a&quot;, &quot;b&quot;, &quot;c&quot;])
}

moved {
  from = random_pet.a
  to   = random_pet.main&#x5B;&quot;a&quot;]
}

moved {
  from = random_pet.b
  to   = random_pet.main&#x5B;&quot;b&quot;]
}

moved {
  from = random_pet.c
  to   = random_pet.main&#x5B;&quot;c&quot;]
}
</pre></div>


<p>In the generated plan, we want to verify that there are no changes made to the provisioned resources before applying changing the state.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; highlight: [19]; title: ; notranslate">
# random_pet.a has moved to random_pet.main&#x5B;&quot;a&quot;]
resource &quot;random_pet&quot; &quot;main&quot; {
  id = &quot;poetic-collie&quot;
  # (2 unchanged attributes hidden)
}

# random_pet.b has moved to random_pet.main&#x5B;&quot;b&quot;]
resource &quot;random_pet&quot; &quot;main&quot; {
  id = &quot;glad-lobster&quot;
  # (2 unchanged attributes hidden)
}

# random_pet.c has moved to random_pet.main&#x5B;&quot;c&quot;]
resource &quot;random_pet&quot; &quot;main&quot; {
  id = &quot;suited-fly&quot;
  # (2 unchanged attributes hidden)
}

Plan: 0 to add, 0 to change, 0 to destroy.
</pre></div>


<p>As you can see, we end up with the same outcome.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state list
random_pet.main&#x5B;&quot;a&quot;]
random_pet.main&#x5B;&quot;b&quot;]
random_pet.main&#x5B;&quot;c&quot;]
</pre></div>


<p>The upside is we can still stick with our <strong>terraform apply</strong> to adjust the state without using <strong>terraform state mv</strong>.</p>



<h2 class="wp-block-heading">LIMITATIONS</h2>



<p>It&#8217;s worth pointing out that it&#8217;s not all sunshine and rainbows here. </p>



<p>The <strong>moved</strong> block solves just part of the state manipulation problems, and you may still need to use <strong>terraform state [action]</strong> for other use cases (at least with Terraform 1.1.x).</p>



<h3 class="wp-block-heading">Limitation #1: Removing Resources(s) from State</h3>



<p>In rare cases, you may want Terraform to stop tracking a resource in its state file. Perhaps, you run into a race condition problem when attempting to destroy the resources, which prevents Terraform from completing the process successfully. As a result, all resources are fully destroyed (via &#8220;eventual consistency&#8221;) but unfortunately, a few non-existent resources are still being tracked in the Terraform&#8217;s state file.</p>



<p>In this case, you can&#8217;t remove the resource from the state by assigning an empty string…</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; highlight: [3]; title: ; notranslate">
moved {
  from = random_pet.current
  to   = &quot;&quot;
}
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform apply
╷
│ Error: Invalid expression
│
│   on main.tf line 21, in moved:
│   21:   to   = &quot;&quot;
│
│ A single static variable reference is required: only attribute access and indexing with constant keys. No calculations, function calls, template expressions, etc are
│ allowed here.
</pre></div>


<p>… or to <strong>null</strong>…</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; highlight: [3]; title: ; notranslate">
moved {
  from = random_pet.current
  to   = null
}
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform apply
╷
│ Error: Invalid address
│
│   on main.tf line 21, in moved:
│   21:   to   = null
│
│ Resource specification must include a resource type and name.
╵
</pre></div>


<p>The only way to pull this off is to use <strong>terraform state rm</strong>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
$ terraform state rm random_pet.current
Removed random_pet.current
Successfully removed 1 resource instance(s).
</pre></div>


<h3 class="wp-block-heading">Limitation #2: Moving Resource(s) Between State Files</h3>



<p>The <strong>moved</strong> block allows us to rename resource or restructure our codebase all within the same state file. However, it is not possible to move resources from one state file to another state file.</p>



<p>For example, let&#8217;s assume we have one Terraform workspace that manages the following 3 resources.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
# workspace A

resource &quot;google_folder&quot; &quot;a&quot; {
  parent       = &quot;folders/123456789012&quot;
  display_name = &quot;a&quot;
}

resource &quot;google_folder&quot; &quot;b&quot; {
  parent       = &quot;folders/123456789012&quot;
  display_name = &quot;b&quot;
}

resource &quot;google_folder&quot; &quot;c&quot; {
  parent       = &quot;folders/123456789012&quot;
  display_name = &quot;c&quot;
}
</pre></div>


<p>… and we want to move resource <strong>c</strong> to another workspace.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
# Workspace A

resource &quot;google_folder&quot; &quot;a&quot; {
  parent       = &quot;folders/123456789012&quot;
  display_name = &quot;a&quot;
}

resource &quot;google_folder&quot; &quot;b&quot; {
  parent       = &quot;folders/123456789012&quot;
  display_name = &quot;b&quot;
}
</pre></div>

<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
# Workspace B

resource &quot;google_folder&quot; &quot;c&quot; {
  parent       = &quot;folders/123456789012&quot;
  display_name = &quot;c&quot;
}
</pre></div>


<p>The only way to pull this off is to identify the resource ID for <strong>c</strong> in workspace A first…</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; highlight: [9]; title: ; notranslate">
# Workspace A

$ terraform state show google_folder.c
# google_folder.c:
resource &quot;google_folder&quot; &quot;c&quot; {
  create_time     = &quot;2022-04-30T15:00:29.114Z&quot;
  display_name    = &quot;c&quot;
  folder_id       = &quot;999999999999&quot;
  id              = &quot;folders/999999999999&quot;
  lifecycle_state = &quot;ACTIVE&quot;
  name            = &quot;folders/999999999999&quot;
  parent          = &quot;folders/123456789012&quot;
}
</pre></div>


<p>Then, remove that resource from workspace A&#8217;s state.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
# Workspace A

$ terraform state rm google_folder.c
Removed google_folder.c
Successfully removed 1 resource instance(s).
</pre></div>


<p>Finally, import the resource in workspace B&#8217;s state.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
# Workspace B

$ terraform import google_folder.c folders/999999999999
google_folder.c: Importing from ID &quot;folders/999999999999&quot;...
google_folder.c: Import prepared!
  Prepared google_folder for import
google_folder.c: Refreshing state... &#x5B;id=folders/999999999999]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
</pre></div><p>The post <a rel="nofollow" href="https://myshittycode.com/2022/04/30/terraform-updating-state-using-moved-block/">Terraform: Updating State Using &#8220;Moved&#8221; Block</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myshittycode.com/2022/04/30/terraform-updating-state-using-moved-block/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1926</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)
Database Caching using Disk

Served from: myshittycode.com @ 2026-02-20 10:09:26 by W3 Total Cache
-->