<?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>Infrastructure as Code &#8211; My Shitty Code</title>
	<atom:link href="https://myshittycode.com/infrastructure-as-code/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>Infrastructure as Code &#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>
		<item>
		<title>Terraform: Handling Errors with try(&#8230;)</title>
		<link>https://myshittycode.com/2020/06/11/terraform-handling-errors-with-try/</link>
					<comments>https://myshittycode.com/2020/06/11/terraform-handling-errors-with-try/#respond</comments>
		
		<dc:creator><![CDATA[Shitty Author]]></dc:creator>
		<pubDate>Thu, 11 Jun 2020 18:50:29 +0000</pubDate>
				<category><![CDATA[Programming Language]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Terraform]]></category>
		<guid isPermaLink="false">http://myshittycode.com/?p=1150</guid>

					<description><![CDATA[<p>PROBLEM Given the following output block:- Sometimes, during an apply or destroy, we may get this error:- One way to fix this is to do conditional expressions like this, but it&#8217;s not pretty:- SOLUTION Since Terraform v0.12.20, we can solve this with try and achieve the same outcome:-</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2020/06/11/terraform-handling-errors-with-try/">Terraform: Handling Errors with try(&#8230;)</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">PROBLEM</h2>



<p>Given the following <b>output</b> block:-</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
output &quot;subnet_uc1&quot; {
  description = &quot;Subnets in `us-central1` region for all 3 products&quot;
  value = {
    artifactory = module.subnet_uc1_artifactory.subnets.name
    xray        = module.subnet_uc1_xray.subnets.name
    mc          = module.subnet_uc1_mc.subnets.name
  }
}
</pre></div>


<p>Sometimes, during an <b>apply</b> or <b>destroy</b>, we may get this error:-</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Error: Attempt to get attribute from null value

  on outputs.tf line 40, in output &quot;subnet_uc1&quot;:
  40:     artifactory = module.subnet_uc1_artifactory.subnets.name
    |----------------
    | module.subnet_uc1_artifactory.subnets is null

This value is null, so it does not have any attributes.

Error: Attempt to get attribute from null value

  on outputs.tf line 41, in output &quot;subnet_uc1&quot;:
  41:     xray        = module.subnet_uc1_xray.subnets.name
    |----------------
    | module.subnet_uc1_xray.subnets is null

This value is null, so it does not have any attributes.

Error: Attempt to get attribute from null value

  on outputs.tf line 42, in output &quot;subnet_uc1&quot;:
  42:     mc          = module.subnet_uc1_mc.subnets.name
    |----------------
    | module.subnet_uc1_mc.subnets is null

This value is null, so it does not have any attributes.
</pre></div>


<p>One way to fix this is to do conditional expressions like this, but it&#8217;s not pretty:-</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
output &quot;subnet_uc1&quot; {
  description = &quot;Subnets in `us-central1` region for all 3 products&quot;
  value = {
    artifactory = module.subnet_uc1_artifactory.subnets != null ? module.subnet_uc1_artifactory.subnets.name: &quot;&quot;
    xray        = module.subnet_uc1_xray.subnets != null ?module.subnet_uc1_xray.subnets.name: &quot;&quot;
    mc          = module.subnet_uc1_mc.subnets != null ? module.subnet_uc1_mc.subnets.name: &quot;&quot;
  }
}
</pre></div>


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



<p>Since Terraform <a href="https://github.com/hashicorp/terraform/releases/tag/v0.12.20" target="_blank" rel="noopener">v0.12.20</a>, we can solve this with <b>try</b> and achieve the same outcome:-</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
output &quot;subnet_uc1&quot; {
  description = &quot;Subnets in `us-central1` region for all 3 products&quot;
  value = {
    artifactory = try(module.subnet_uc1_artifactory.subnets.name, &quot;&quot;)
    xray        = try(module.subnet_uc1_xray.subnets.name, &quot;&quot;)
    mc          = try(module.subnet_uc1_mc.subnets.name, &quot;&quot;)
  }
}
</pre></div><p>The post <a rel="nofollow" href="https://myshittycode.com/2020/06/11/terraform-handling-errors-with-try/">Terraform: Handling Errors with try(&#8230;)</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myshittycode.com/2020/06/11/terraform-handling-errors-with-try/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1150</post-id>	</item>
		<item>
		<title>Terraform: Skipping Buggy Provider Version</title>
		<link>https://myshittycode.com/2020/05/10/terraform-skipping-buggy-provider-version/</link>
					<comments>https://myshittycode.com/2020/05/10/terraform-skipping-buggy-provider-version/#respond</comments>
		
		<dc:creator><![CDATA[Shitty Author]]></dc:creator>
		<pubDate>Sun, 10 May 2020 15:08:20 +0000</pubDate>
				<category><![CDATA[Programming Language]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Terraform]]></category>
		<guid isPermaLink="false">http://myshittycode.com/?p=1144</guid>

					<description><![CDATA[<p>PROBLEM Given the following required_providers block&#8230; &#8230; it will allow the following Google provider version: &#62;= 3.8, &#60; 4.0. As of today (May 10), the latest Google provider is 3.20.0. A quick terraform init confirms that. However, sometimes, there&#8217;s a need to skip a buggy version. For example, 3.20.0 breaks google_compute_firewall. SOLUTION To achieve that, [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2020/05/10/terraform-skipping-buggy-provider-version/">Terraform: Skipping Buggy Provider Version</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">PROBLEM</h2>



<p>Given the following <b>required_providers</b> block&#8230;</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
terraform {
  required_providers {
    google = &quot;~&gt; 3.8&quot;
  }
}
</pre></div>


<p>&#8230; it will allow the following Google provider version: &gt;= 3.8, &lt; 4.0.</p>



<p>As of today (May 10), the latest Google provider is 3.20.0. A quick <b>terraform init</b> confirms that.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider &quot;google&quot; (hashicorp/google) 3.20.0...
</pre></div>


<p>However, sometimes, there&#8217;s a need to skip a buggy version. For example, <a href="https://github.com/terraform-providers/terraform-provider-google/issues/6315" target="_blank" rel="noopener">3.20.0 breaks google_compute_firewall</a>.</p>



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



<p>To achieve that, we can do the following&#8230;</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
terraform {
  required_providers {
    google = &quot;~&gt; 3.8, != 3.20.0&quot;
  }
}
</pre></div>


<p>To confirm this works, after deleting .terraform/ dir, <b>terraform init</b> now shows the following result&#8230;</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider &quot;google&quot; (hashicorp/google) 3.19.0...
</pre></div><p>The post <a rel="nofollow" href="https://myshittycode.com/2020/05/10/terraform-skipping-buggy-provider-version/">Terraform: Skipping Buggy Provider Version</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myshittycode.com/2020/05/10/terraform-skipping-buggy-provider-version/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1144</post-id>	</item>
		<item>
		<title>GCP + Terraform: Running Terraform Commands with a Service Account</title>
		<link>https://myshittycode.com/2020/02/06/gcp-terraform-running-terraform-commands-with-a-service-account/</link>
					<comments>https://myshittycode.com/2020/02/06/gcp-terraform-running-terraform-commands-with-a-service-account/#respond</comments>
		
		<dc:creator><![CDATA[Shitty Author]]></dc:creator>
		<pubDate>Thu, 06 Feb 2020 19:24:59 +0000</pubDate>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Programming Language]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Terraform]]></category>
		<guid isPermaLink="false">http://myshittycode.com/?p=1127</guid>

					<description><![CDATA[<p>PROBLEM When running these commands&#8230; &#8230; it allows terraform apply to provision the infrastructure using your credential. However, sometimes there&#8217;s a need to run Terraform using a service account. SOLUTION First, identify the service account you want to use&#8230; for example: my-service-account@my-project.iam.gserviceaccount.com. Then, create and download the private key for the service account. Command: Output: [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2020/02/06/gcp-terraform-running-terraform-commands-with-a-service-account/">GCP + Terraform: Running Terraform Commands with a Service Account</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">PROBLEM</h2>



<p>When running these commands&#8230;</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
gcloud auth login
gcloud auth application-default login
</pre></div>


<p>&#8230; it allows <b>terraform apply</b> to provision the infrastructure using your credential.</p>



<p>However, sometimes there&#8217;s a need to run Terraform using a service account.</p>



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



<p>First, identify the service account you want to use&#8230; for example: <b>my-service-account@my-project.iam.gserviceaccount.com</b>.</p>



<p>Then, create and download the private key for the service account.</p>



<p>Command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
gcloud iam service-accounts keys create --iam-account my-service-account@my-project.iam.gserviceaccount.com  key.json
</pre></div>


<p>Output:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
created key &#x5B;xxxxxxxx] of type &#x5B;json] as &#x5B;key.json] for &#x5B;my-service-account@my-project.iam.gserviceaccount.com]
</pre></div>


<p>With this service account&#8217;s private key, we can now authorize its access to GCP.</p>



<p>Command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
gcloud auth activate-service-account --key-file key.json
</pre></div>


<p>Output:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Activated service account credentials for: &#x5B;my-service-account@my-project.iam.gserviceaccount.com]
</pre></div>


<p>You can verify whether the right account is being used or not.</p>



<p>Command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
gcloud auth list
</pre></div>


<p>Output:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
                      Credentialed Accounts
ACTIVE  ACCOUNT
*       my-service-account@my-project.iam.gserviceaccount.com
        user@myshittycode.com

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
</pre></div>


<p>In this case, the <b>*</b> marks the active account being used.</p>



<p>Now, you can run <b>terraform apply</b> to provision the infrastructure using the selected service account.</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2020/02/06/gcp-terraform-running-terraform-commands-with-a-service-account/">GCP + Terraform: Running Terraform Commands with a Service Account</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myshittycode.com/2020/02/06/gcp-terraform-running-terraform-commands-with-a-service-account/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1127</post-id>	</item>
		<item>
		<title>GCP + Kitchen Terraform: Local Development Workflow</title>
		<link>https://myshittycode.com/2020/01/23/kitchen-terraform-local-development-workflow/</link>
					<comments>https://myshittycode.com/2020/01/23/kitchen-terraform-local-development-workflow/#respond</comments>
		
		<dc:creator><![CDATA[Shitty Author]]></dc:creator>
		<pubDate>Thu, 23 Jan 2020 17:46:38 +0000</pubDate>
				<category><![CDATA[Programming Language]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Infrastructure as Code]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<category><![CDATA[Kitchen Terraform]]></category>
		<category><![CDATA[Terraform]]></category>
		<guid isPermaLink="false">http://myshittycode.com/?p=1123</guid>

					<description><![CDATA[<p>INTRODUCTION Here&#8217;s a typical workflow for implementing and running Kitchen Terraform tests outside of the GCP environment, for example, from an IDE on a Mac laptop. Enable &#8220;gcloud&#8221; Access Command: The first step is to ensure we can interact with GCP using the gcloud command using our user credential. This is needed because the tests [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2020/01/23/kitchen-terraform-local-development-workflow/">GCP + Kitchen Terraform: Local Development Workflow</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">INTRODUCTION</h2>



<p>Here&#8217;s a typical workflow for implementing and running Kitchen Terraform tests outside of the GCP environment, for example, from an IDE on a Mac laptop.</p>



<h2 class="wp-block-heading">Enable &#8220;gcloud&#8221; Access</h2>



<p>Command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
gcloud auth login
</pre></div>


<p>The first step is to ensure we can interact with GCP using the <b>gcloud</b> command using our user credential. This is needed because the tests use the <b>gcloud</b> commands to retrieve GCP resource information in order to do the assertions.</p>



<h2 class="wp-block-heading">Enable SDK Access</h2>



<p>Command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
gcloud auth application-default login
</pre></div>


<p>This ensures our Terraform code can run the GCP SDK successfully without a service account. Instead, it will use our user credential.</p>



<p>Without this command, we may get the following error when running the Terraform code:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Response: {
 &quot;error&quot;: &quot;invalid_grant&quot;,
 &quot;error_description&quot;: &quot;reauth related error (invalid_rapt)&quot;,
 &quot;error_subtype&quot;: &quot;invalid_rapt&quot;
}
</pre></div>


<h2 class="wp-block-heading">Display All Kitchen Test Suites</h2>



<p>Command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
bundle exec kitchen list
</pre></div>


<p>This command displays a list of Kitchen test suites defined in <b>kitchen.yml</b>.</p>



<p>The output looks something like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
Instance                            Driver     Provisioner  Verifier   Transport  Last Action    Last Error
router-all-subnets-ip-ranges-local  Terraform  Terraform    Terraform  Ssh
router-interface-local              Terraform  Terraform    Terraform  Ssh
router-no-bgp-no-nat-local          Terraform  Terraform    Terraform  Ssh
router-with-bgp-local               Terraform  Terraform    Terraform  Ssh
router-with-nat-local               Terraform  Terraform    Terraform  Ssh
</pre></div>


<h2 class="wp-block-heading">Run a Specific Test Suite</h2>



<p>Command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
bundle exec kitchen test &#x5B;INSTANCE_NAME]    

# For example:-
bundle exec kitchen test router-with-nat-local
</pre></div>


<p>This command allows us to run a specific test suite. This will handle the entire Terraform lifecycle&#8230; ie: setting up the infrastructure, running the tests and destroying the infrastructure.</p>



<p>This is helpful especially when we need to run just the test suite that is currently under development. This way, it runs faster because we don&#8217;t have to provision/deprovision the cloud infrastructure for other test suites. At the same time, we will also reduce the incurred cost.</p>



<h2 class="wp-block-heading">Run a Specific Test Suite with Finer Controls</h2>



<p>There are times where running <b>bundle exec kitchen test [INSTANCE_NAME]</b> is still very time consuming and expensive, especially when we try to debug any failed assertions or add a little assertions at a time.</p>



<p>To provision the infrastructure once, run the following command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
bundle exec kitchen converge &#x5B;INSTANCE_NAME]    

# For example:-
bundle exec kitchen converge router-with-nat-local
</pre></div>


<p>To run the assertions, run the following command as many times as possible until all the assertions are implemented successfully:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
bundle exec kitchen verify &#x5B;INSTANCE_NAME]    

# For example:-
bundle exec kitchen verify router-with-nat-local
</pre></div>


<p>Finally, once the test suite is implemented properly, we can now deprovision the infrastructure:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
bundle exec kitchen destroy &#x5B;INSTANCE_NAME]    

# For example:-
bundle exec kitchen destroy router-with-nat-local
</pre></div><p>The post <a rel="nofollow" href="https://myshittycode.com/2020/01/23/kitchen-terraform-local-development-workflow/">GCP + Kitchen Terraform: Local Development Workflow</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myshittycode.com/2020/01/23/kitchen-terraform-local-development-workflow/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1123</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-17 23:30:08 by W3 Total Cache
-->