<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sam Myers</title>
    <description>The latest articles on DEV Community by Sam Myers (@sammyers).</description>
    <link>https://dev.to/sammyers</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F97642%2F9ed5fbc3-e9e3-4052-b8fe-5f3bab7e0ee7.jpeg</url>
      <title>DEV Community: Sam Myers</title>
      <link>https://dev.to/sammyers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sammyers"/>
    <language>en</language>
    <item>
      <title>How To Move Individual Resources Across Terraform Backends</title>
      <dc:creator>Sam Myers</dc:creator>
      <pubDate>Mon, 01 Apr 2019 22:40:29 +0000</pubDate>
      <link>https://dev.to/sammyers/how-to-move-individual-resources-across-terraform-backends-52ol</link>
      <guid>https://dev.to/sammyers/how-to-move-individual-resources-across-terraform-backends-52ol</guid>
      <description>

&lt;p&gt;Terraform has some fabulous built-in abilities to change where its configuration is stored, but sometimes there's no getting around the need to do state surgery.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Scenario
&lt;/h1&gt;

&lt;p&gt;In this case, I have a repo with some Terraform configuration. Later, that repo became a module rather than an independent repo.&lt;/p&gt;

&lt;p&gt;The straightforward path is to &lt;code&gt;terraform destroy&lt;/code&gt; the old resources and &lt;code&gt;terraform apply&lt;/code&gt; the new module.&lt;/p&gt;

&lt;p&gt;However, there are resources that I want to preserve (S3 buckets, KMS keys...)&lt;/p&gt;

&lt;h2&gt;
  
  
  Lifecycle Rules
&lt;/h2&gt;

&lt;p&gt;Before we proceed, make absolutely sure that the resources you want to move can't be deleted by accident.&lt;/p&gt;

&lt;p&gt;Add the following to any resource to prevent Terraform from deleting it.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lifecycle {
  prevent_destroy = true
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you issue a &lt;code&gt;terraform destroy&lt;/code&gt; while those resources are tracked, Terraform will not allow you to proceed.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Move
&lt;/h1&gt;

&lt;p&gt;The basic plan of attack is to make the source Terraform stop tracking the resource with &lt;code&gt;terraform state rm&lt;/code&gt; and get the destination Terraform to start with &lt;code&gt;terraform import&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Open a terminal in both the source and destination Terraform repos.&lt;/p&gt;

&lt;p&gt;In this example, we're moving a KMS key.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_kms_key" "foo" {
  lifecycle {
    prevent_destroy = true
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is known in the source Terraform as &lt;code&gt;aws_kms_key.foo&lt;/code&gt; and the destination as &lt;code&gt;module.example-module.aws_kms_key.foo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that since the repo is a module in the destination that its name is prefixed with &lt;code&gt;module.${MODULE_NAME}.&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get its state from the source
&lt;/h2&gt;

&lt;p&gt;In the source repo&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source&amp;gt; terraform state show aws_kms_key.foo

id                  = aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
arn                 = arn:aws:kms:us-west-2:REDACTED:key/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
enable_key_rotation = false
is_enabled          = true
key_id              = aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
key_usage           = ENCRYPT_DECRYPT
policy              = ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Specifically what we are looking for is the first line, the &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Or for simplicity, &lt;code&gt;terraform state show aws_kms_key.foo | head -n1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We could tell Terraform to stop tracking it at this point, but let's do so after the import to be safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import it into the destination
&lt;/h2&gt;

&lt;p&gt;In your destination repo&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;destination&amp;gt; terraform import module.example-module.aws_kms_key.foo aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee

module.example-module.aws_kms_key.foo: Importing from ID "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"...
module.example-module.aws_kms_key.foo: Import complete!
  Imported aws_kms_key (ID: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)
module.example-module.aws_kms_key.foo: Refreshing state... (ID: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)

Import successful!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If this step gives you any trouble, the Terraform docs always give an example of how to import something.&lt;/p&gt;

&lt;h2&gt;
  
  
  Remove state from the source
&lt;/h2&gt;

&lt;p&gt;Back in your source repo, &lt;code&gt;rm&lt;/code&gt; the resource from the state. This will preserve it from any future &lt;code&gt;destroy&lt;/code&gt; operations.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source&amp;gt; terraform state rm aws_kms_key.foo

1 items removed.
Item removal successful.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Wrap-up
&lt;/h1&gt;

&lt;p&gt;That's it. Repeat for all your critical resources.&lt;/p&gt;

&lt;p&gt;At the end you get to &lt;code&gt;terraform destroy&lt;/code&gt; your old repo and &lt;code&gt;terraform apply&lt;/code&gt; your new one.&lt;/p&gt;


</description>
      <category>terraform</category>
      <category>hashicorp</category>
      <category>devops</category>
      <category>infrastructureascode</category>
    </item>
  </channel>
</rss>
