<?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>terraform Archives - Tailored Cloud</title>
	<atom:link href="https://tailored.cloud/tag/terraform/feed/" rel="self" type="application/rss+xml" />
	<link>https://tailored.cloud/tag/terraform/</link>
	<description>Kubernetes, devops and everything cloud</description>
	<lastBuildDate>Tue, 03 Jul 2018 20:41:14 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6</generator>
	<item>
		<title>Cache your Terraform providers to save space and time</title>
		<link>https://tailored.cloud/devops/cache-terraform-providers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cache-terraform-providers</link>
					<comments>https://tailored.cloud/devops/cache-terraform-providers/#respond</comments>
		
		<dc:creator><![CDATA[tc-admin]]></dc:creator>
		<pubDate>Tue, 03 Jul 2018 20:41:14 +0000</pubDate>
				<category><![CDATA[devops]]></category>
		<category><![CDATA[terraform]]></category>
		<guid isPermaLink="false">http://localhost:8080/?p=320</guid>

					<description><![CDATA[<p>TL;DR: Set &#8220;TF_PLUGIN_CACHE_DIR&#8221;  environment variable to an empty dir, then rerun &#8220;terraform init&#8221; to switch to a shared providers directory. This <a class="more-link" href="https://tailored.cloud/devops/cache-terraform-providers/">Continue Reading</a></p>
<p>The post <a href="https://tailored.cloud/devops/cache-terraform-providers/">Cache your Terraform providers to save space and time</a> appeared first on <a href="https://tailored.cloud">Tailored Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2><img decoding="async" class="alignleft wp-image-311 size-thumbnail" title="Terraform Logo" src="https://localhost:8080/wp-content/uploads/2018/04/tf-150x150.png" alt="Terraform Logo" width="150" height="150" srcset="https://tailored.cloud/wp-content/uploads/2018/04/tf-150x150.png 150w, https://tailored.cloud/wp-content/uploads/2018/04/tf-300x300.png 300w, https://tailored.cloud/wp-content/uploads/2018/04/tf.png 400w" sizes="(max-width: 150px) 100vw, 150px" />TL;DR:</h2>
<ul>
<li>Set &#8220;TF_PLUGIN_CACHE_DIR&#8221;  environment variable to an empty dir, then rerun &#8220;terraform init&#8221; to switch to a shared providers directory. This allows to cache Terraform providers.</li>
</ul>
<h2>Dynamic Terraform providers</h2>
<p>Have you noticed, that when you run &#8220;terraform init&#8221;, Terraform fetches additional binaries from the Internet? These binaries are called &#8220;dynamic providers&#8221; and they are (mainly) interfaces to the infrastructure operators you&#8217;re using in your Terraform code.</p>
<p>So, for example, when you&#8217;re using AWS as an infrastructure provider, and you also use some templating to <a href="http://localhost:8080/devops/terraform_confg_files_changed_resources/">generate config files</a>, you might run &#8220;terraform version&#8221; and see something like this:</p>
<pre class="brush: plain; title: ; notranslate">
$ terraform version
Terraform v0.11.7
+ provider.aws v1.20.0
+ provider.null v1.0.0
+ provider.template v1.0.0
</pre>
<p>In the example above, we have 3 providers being used: the &#8220;null&#8221; and &#8220;template&#8221; provider and a specialized provider for talking with AWS API. You can find a list of projects developing these providers on <a href="https://github.com/terraform-providers">Github</a>. But where does Terraform keep these additional provider binaries? Well, each directory that is used as a root of Terraform project (where you run &#8220;terraform init&#8221;) has a hidden &#8220;.terraform&#8221; directory. There you can find the downloaded providers:</p>
<pre class="brush: bash; title: ; notranslate">
ll -h .terraform/plugins/linux_amd64
-rwxrwxr-x 1 piontec piontec 239 May 24 06:28 lock.json
-rwxr-xr-x 1 piontec piontec 71M May 24 06:28 terraform-provider-aws_v1.20.0_x4
-rwxr-xr-x 1 piontec piontec 12M Apr 19 07:29 terraform-provider-null_v1.0.0_x4
-rwxr-xr-x 1 piontec piontec 12M Apr 19 07:29 terraform-provider-template_v1.0.0_x4
</pre>
<p>This approach is nice, as all your projects are independent and self-contained: you can copy the whole directory to some other place or even machine and everything will still work. However, this approach has also a drawback. If you have multiple Terraform working directories, you have to download and store your providers for every one of them. As you can see, the basic set of providers listed above takes around 100MB &#8211; not much for today standards, but still. This gets even worse when you have multiple Terraform projects used by a group of people.  And when every one of them runs &#8220;terraform init&#8221;, he or she needs to wait for the binaries to be downloaded.</p>
<h2>A cache directory for providers to the rescue</h2>
<p>The solution to the above problem is actually very simple and already included in Terraform, although a little bit hard to find. You can create a single directory for storing your dynamic providers&#8217; binaries, then set the environment variable &#8220;TF_PLUGIN_CACHE_DIR&#8221; and you&#8217;re done! All Terraform commands run when this variable is set will use a shared directory to lookup and download dynamic providers. That way you can share them across projects and users, if only they have sufficient access permissions to that directory.</p>
<p>Let&#8217;s see how it works.</p>
<pre class="brush: bash; title: ; notranslate">
$ rm -rf .terraform
$ export TF_PLUGIN_CACHE_DIR=/opt/terraform-plugin-dir
$ terraform init -upgrade=true
$ ll -h /opt/terraform-plugin-dir/linux_amd64
-rwxr-xr-x 1 piontec piontec 71M May 24 06:28 terraform-provider-aws_v1.20.0_x4
-rwxr-xr-x 1 piontec piontec 12M Apr 19 07:29 terraform-provider-null_v1.0.0_x4
-rwxr-xr-x 1 piontec piontec 12M Apr 19 07:29 terraform-provider-template_v1.0.0_x4
$ ll .terraform/plugins/linux_amd64
-rwxrwxr-x 1 piontec piontec 239 May 24 06:28 lock.json
lrwxrwxrwx 1 piontec piontec 71 May 24 06:28 terraform-provider-aws_v1.20.0_x4 -&amp;amp;gt; /opt/terraform-plugin-dir/linux_amd64/terraform-provider-aws_v1.20.0_x4
lrwxrwxrwx 1 piontec piontec 71 May 24 06:28 terraform-provider-null_v1.0.0_x4 -&amp;amp;gt; /opt/terraform-plugin-dir/linux_amd64/terraform-provider-null_v1.0.0_x4
lrwxrwxrwx 1 piontec piontec 75 May 24 06:28 terraform-provider-template_v1.0.0_x4 -&amp;amp;gt; /opt/terraform-plugin-dir/linux_amd64/terraform-provider-template_v1.0.0_x4
$ du -hs .terraform
336K .terraform
</pre>
<p>So, after setting the &#8220;TF_PLUGIN_CACHE_DIR&#8221; variable, Terraform downloads providers to that directory and just links from your project&#8217;s &#8220;.terraform&#8221; directory to the shared directory. And that&#8217;s it! Now you can have just a single copy of each provider for the given provider version.</p>
<p>Please keep in mind, that each project still selects the providers&#8217; versions on its own: the fact that one Terraform directory downloaded a new provider version to the cache directory doesn&#8217;t mean that all other projects will use the new version as well. So, normal <a href="https://www.terraform.io/docs/configuration/providers.html#provider-versions">versioning restrictions</a> apply. If you want to be sure which version is locked for use with your current project, you can inspect SHA256 of files saved in one of the files in the &#8220;.terraform&#8221; directory:</p>
<pre class="brush: bash; title: ; notranslate">
$ cat .terraform/plugins/linux_amd64/lock.json
{
&quot;aws&quot;: &quot;3c78df7e116ed60bf917e4cd5cda5999ada163ebffd9142ea41aa7992252cda8&quot;,
&quot;null&quot;: &quot;d45c0f02cbc08b3915e143434e575298d4c638a2c93598c12f4ea551cd821abd&quot;,
&quot;template&quot;: &quot;f1d8e373d9f89d21fade8858a562bed75b463c814a2cf8fb750eb017083f1e88&quot;
}

$ ll /opt/terraform-plugin-dir/linux_amd64/
-rwxr-xr-x 1 piontec piontec 72686016 Apr 19 07:29 terraform-provider-aws_v1.15.0_x4
-rwxr-xr-x 1 piontec piontec 73263584 May 7 08:52 terraform-provider-aws_v1.17.0_x4
-rwxr-xr-x 1 piontec piontec 74119744 May 21 14:05 terraform-provider-aws_v1.19.0_x4
-rwxr-xr-x 1 piontec piontec 74242624 May 24 06:28 terraform-provider-aws_v1.20.0_x4
-rwxr-xr-x 1 piontec piontec 11621440 Apr 19 07:29 terraform-provider-null_v1.0.0_x4
-rwxr-xr-x 1 piontec piontec 11711744 Apr 19 07:29 terraform-provider-template_v1.0.0_x4

$ sha256sum /opt/terraform-plugin-dir/linux_amd64/terraform-provider-aws_v1.20.0_x4
3c78df7e116ed60bf917e4cd5cda5999ada163ebffd9142ea41aa7992252cda8 /opt/terraform-plugin-dir/linux_amd64/terraform-provider-aws_v1.20.0_x4
</pre>
<p>As you can see, the SHA256 hash for AWS provider saved in the &#8220;lock.json&#8221; file matches the hash of  AWS provider v1.20 saved in the cache directory.</p>
<p>The post <a href="https://tailored.cloud/devops/cache-terraform-providers/">Cache your Terraform providers to save space and time</a> appeared first on <a href="https://tailored.cloud">Tailored Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tailored.cloud/devops/cache-terraform-providers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Generating arbitrary configuration files from Terraform; modules and &#8220;always changed&#8221; resources.</title>
		<link>https://tailored.cloud/devops/terraform_confg_files_changed_resources/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=terraform_confg_files_changed_resources</link>
					<comments>https://tailored.cloud/devops/terraform_confg_files_changed_resources/#respond</comments>
		
		<dc:creator><![CDATA[tc-admin]]></dc:creator>
		<pubDate>Thu, 12 Apr 2018 19:48:37 +0000</pubDate>
				<category><![CDATA[devops]]></category>
		<category><![CDATA[config files]]></category>
		<category><![CDATA[problems]]></category>
		<category><![CDATA[terraform]]></category>
		<guid isPermaLink="false">http://localhost:8080/?p=301</guid>

					<description><![CDATA[<p>TL;DR: use Terraform&#8217;s &#8220;null_resource&#8221; and optionally &#8220;template_file&#8221; to easily create config files for other software (like Ansible) be careful when you <a class="more-link" href="https://tailored.cloud/devops/terraform_confg_files_changed_resources/">Continue Reading</a></p>
<p>The post <a href="https://tailored.cloud/devops/terraform_confg_files_changed_resources/">Generating arbitrary configuration files from Terraform; modules and &#8220;always changed&#8221; resources.</a> appeared first on <a href="https://tailored.cloud">Tailored Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>TL;DR:</h2>
<ul>
<li>use Terraform&#8217;s &#8220;<a href="https://www.terraform.io/docs/provisioners/null_resource.html">null_resource</a>&#8221; and optionally &#8220;<a href="https://www.terraform.io/docs/providers/template/d/file.html">template_file</a>&#8221; to easily create config files for other software (like Ansible)</li>
<li>be careful when you add explicit &#8220;depends_on&#8221; attribute, as it might result in reporting submodule data as always &#8220;changed&#8221;, even if they weren&#8217;t</li>
</ul>
<h2>1. Introduction</h2>
<p><img decoding="async" class="alignleft wp-image-311" src="https://localhost:8080/wp-content/uploads/2018/04/tf.png" alt="Terraform Logo" width="216" height="216" srcset="https://tailored.cloud/wp-content/uploads/2018/04/tf.png 400w, https://tailored.cloud/wp-content/uploads/2018/04/tf-150x150.png 150w, https://tailored.cloud/wp-content/uploads/2018/04/tf-300x300.png 300w" sizes="(max-width: 216px) 100vw, 216px" />Recently, I had a strange problem with <a href="https://www.terraform.io/">Terraform</a> (all the code below was tested with Terraform 0.11.2). In our company, we use it to manage all our IaaS resources in AWS, but also to generate some configuration files for Ansible. Such configuration files need to be based on data that only Terraform has, so we use &#8220;<a href="https://www.terraform.io/docs/provisioners/null_resource.html">null_resource</a>&#8221; to generate them. But in some cases, our &#8220;null&#8221; type resources were always reported as changed, no matter if the source variables used in the resource changed or not. This quickly became a problem. When you read Terraform plan you really want to know which parts of your infrastructure are going to be changed, including Ansible config files. So, in this blog post, I&#8217;m trying to address two things: the former is a simple example of how to generate configuration files for other tools from Terraform. The latter is about nailing down the &#8220;always changed null_resource&#8221; issue.</p>
<h2>2. Working example &#8211; generating configuration files</h2>
<p>Let&#8217;s start to dig into the problem using a simple Terraform code, which allows us to generate an arbitrary configuration file based on Terraform&#8217;s configuration and resources. To do that, we combine &#8220;<a href="https://www.terraform.io/docs/providers/template/d/file.html">template_file</a>&#8221; data provider with a <a href="https://www.terraform.io/docs/provisioners/null_resource.html#triggers">&#8220;null_resource&#8221;  and its &#8220;trigger&#8221; and &#8220;provisioner&#8221;</a> properties. In the example below, we have a variable &#8220;names&#8221;, which contains a comma-separated list of values. For each value, we want to run a template using the values as the template parameter. Next, using &#8220;null_resource&#8221; and &#8220;local-exec&#8221; provisioner, we use simple &#8220;echo&#8221; shell command to output the result of rendering the template into any file we want. That way we can easily generate a whole bunch of config files, although in this example I&#8217;m putting all outputs into a single &#8220;out.txt&#8221; to keep it simpler. Here&#8217;s the Terraform code that does just that:</p>
<pre class="brush: plain; title: ; notranslate">
variable &quot;names&quot; {
  default = &quot;joe,jimmy&quot;
}

data &quot;template_file&quot; &quot;init&quot; {
  count = &quot;${length(split(&quot;,&quot;, var.names))}&quot;
  template = &quot;${file(&quot;templates/test.template&quot;)}&quot;
  vars {
    test = &quot;${jsonencode(element(split(&quot;,&quot;, var.names), count.index))}&quot;
  }
}

resource &quot;null_resource&quot; &quot;web&quot; {
  count = &quot;${length(split(&quot;,&quot;, var.names))}&quot;
  triggers {
    template_rendered = &quot;${join(&quot;,&quot;, data.template_file.init.*.rendered)}&quot;
  }

  provisioner &quot;local-exec&quot; {
    command = &quot;echo \&quot;${join(&quot;,&quot;, data.template_file.init.*.rendered)}\&quot; &gt;&gt; out.txt&quot;
  }
}
</pre>
<p>and the &#8220;templates/test.template&#8221;:</p>
<pre class="brush: plain; title: ; notranslate">
Hello ${test}
</pre>
<p>Now we start with typical Terraform bootstrap commands:</p>
<pre class="brush: plain; title: ; notranslate">
$ terraform init
$ terraform apply
</pre>
<p>which should produce the following output:</p>
<pre class="brush: plain; title: ; notranslate">
data.template_file.init&#x5B;1]: Refreshing state...
data.template_file.init&#x5B;0]: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

+ null_resource.web&#x5B;0]
id: &lt;computed&gt;
triggers.%: &quot;1&quot;
triggers.template_rendered: &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;

+ null_resource.web&#x5B;1]
id: &lt;computed&gt;
triggers.%: &quot;1&quot;
triggers.template_rendered: &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;


Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

null_resource.web&#x5B;1]: Creating...
triggers.%: &quot;&quot; =&gt; &quot;1&quot;
triggers.template_rendered: &quot;&quot; =&gt; &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;
null_resource.web&#x5B;0]: Creating...
triggers.%: &quot;&quot; =&gt; &quot;1&quot;
triggers.template_rendered: &quot;&quot; =&gt; &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;
null_resource.web&#x5B;1]: Provisioning with 'local-exec'...
null_resource.web&#x5B;0]: Provisioning with 'local-exec'...
null_resource.web&#x5B;0] (local-exec): Executing: &#x5B;&quot;/bin/sh&quot; &quot;-c&quot; &quot;echo \&quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n\&quot; &gt;&gt; out.txt&quot;]
null_resource.web&#x5B;1] (local-exec): Executing: &#x5B;&quot;/bin/sh&quot; &quot;-c&quot; &quot;echo \&quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n\&quot; &gt;&gt; out.txt&quot;]
null_resource.web&#x5B;1]: Creation complete after 0s (ID: 4859977991312868035)
null_resource.web&#x5B;0]: Creation complete after 0s (ID: 2379833441165791621)

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
</pre>
<p>This looks perfectly valid. Let&#8217;s check the plan again with &#8220;terraform plan&#8221;:</p>
<pre class="brush: plain; title: ; notranslate">
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.template_file.init&#x5B;1]: Refreshing state...
data.template_file.init&#x5B;0]: Refreshing state...
null_resource.web&#x5B;1]: Refreshing state... (ID: 4859977991312868035)
null_resource.web&#x5B;0]: Refreshing state... (ID: 2379833441165791621)

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
</pre>
<p>No changes detected, as can be expected. Perfect. Just to confirm, our &#8220;out.txt&#8221; file contains now:</p>
<pre class="brush: plain; title: ; notranslate">
Hello joe
,Hello jimmy
Hello joe
,Hello jimmy
</pre>
<h2>3. Refactoring: creating a module</h2>
<p>In real life, TerraForm code needs to be organized into modules to keep it more structured and manageable. So let&#8217;s start creating a very simple and minimalistic module, that just returns a constant variable for us. We create &#8220;modules/dummy/main.tf&#8221; file with the following content:</p>
<pre class="brush: plain; title: ; notranslate">
output &quot;file_path&quot; {
  value = &quot;out.txt&quot;
}
</pre>
<p>We also include this module in our &#8220;test.tf&#8221; file by adding the following lines:</p>
<pre class="brush: plain; title: ; notranslate">
module &quot;dummy-1&quot; {
  source = &quot;./modules/dummy&quot;
}
</pre>
<p>Just for testing, let&#8217;s remove the configuration file &#8220;out.txt&#8221; and the state file. Now, let&#8217;s run &#8220;apply&#8221;:</p>
<pre class="brush: plain; title: ; notranslate">
data.template_file.init&#x5B;1]: Refreshing state...
data.template_file.init&#x5B;0]: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

+ null_resource.web&#x5B;0]
id: &lt;computed&gt;
triggers.%: &quot;1&quot;
triggers.template_rendered: &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;

+ null_resource.web&#x5B;1]
id: &lt;computed&gt;
triggers.%: &quot;1&quot;
triggers.template_rendered: &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

null_resource.web&#x5B;0]: Creating...
triggers.%: &quot;&quot; =&gt; &quot;1&quot;
triggers.template_rendered: &quot;&quot; =&gt; &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;
null_resource.web&#x5B;1]: Creating...
triggers.%: &quot;&quot; =&gt; &quot;1&quot;
triggers.template_rendered: &quot;&quot; =&gt; &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot;
null_resource.web&#x5B;1]: Provisioning with 'local-exec'...
null_resource.web&#x5B;0]: Provisioning with 'local-exec'...
null_resource.web&#x5B;0] (local-exec): Executing: &#x5B;&quot;/bin/sh&quot; &quot;-c&quot; &quot;echo \&quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n\&quot; &gt;&gt; out.txt&quot;]
null_resource.web&#x5B;1] (local-exec): Executing: &#x5B;&quot;/bin/sh&quot; &quot;-c&quot; &quot;echo \&quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n\&quot; &gt;&gt; out.txt&quot;]
null_resource.web&#x5B;1]: Creation complete after 0s (ID: 6827055886347134598)
null_resource.web&#x5B;0]: Creation complete after 0s (ID: 7071338054223239370)

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
</pre>
<p>OK, works as expected. Let&#8217;s confirm the state by running &#8220;plan&#8221; again:</p>
<pre class="brush: plain; title: ; notranslate">
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.template_file.init&#x5B;0]: Refreshing state...
data.template_file.init&#x5B;1]: Refreshing state...
null_resource.web&#x5B;1]: Refreshing state... (ID: 6827055886347134598)
null_resource.web&#x5B;0]: Refreshing state... (ID: 7071338054223239370)

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
</pre>
<p>So far so good.</p>
<h2>4. Module dependency and the &#8220;always changed&#8221; problem</h2>
<p>In real life, modules frequently depend on values returned by other modules. Normally, Terraform does a good job at detecting these dependencies automatically. If it misses such dependency and still one module relies on results of the other, you should manually add the dependency information by adding &#8220;depends_on&#8221; attribute. You might even put it in your code just in case, to be sure the execution order is correct. So, to demonstrate that, let&#8217;s add an explicit dependency between our &#8220;init&#8221; template_file resource and our module. We need to add the line:</p>
<pre class="brush: plain; title: ; notranslate">
depends_on = &#x5B;&quot;module.dummy-1&quot;]
</pre>
<p>in our &#8220;init&#8221; resource section. Let&#8217;s ask Terraform what it thinks about this change by running &#8220;plan&#8221;:</p>
<pre class="brush: plain; title: ; notranslate">
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

null_resource.web&#x5B;1]: Refreshing state... (ID: 6827055886347134598)
null_resource.web&#x5B;0]: Refreshing state... (ID: 7071338054223239370)

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
&lt;= read (data resources)

Terraform will perform the following actions:

&lt;= data.template_file.init&#x5B;0]
id: &lt;computed&gt;
rendered: &lt;computed&gt;
template: &quot;Hello ${test}\n&quot;
vars.%: &quot;1&quot;
vars.test: &quot;\&quot;joe\&quot;&quot;

&lt;= data.template_file.init&#x5B;1]
id: &lt;computed&gt;
rendered: &lt;computed&gt;
template: &quot;Hello ${test}\n&quot;
vars.%: &quot;1&quot;
vars.test: &quot;\&quot;jimmy\&quot;&quot;

-/+ null_resource.web&#x5B;0] (new resource required)
id: &quot;7071338054223239370&quot; =&gt; &lt;computed&gt; (forces new resource)
triggers.%: &quot;1&quot;=&gt; &lt;computed&gt; (forces new resource)
triggers.template_rendered: &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot; =&gt; &quot;&quot; (forces new resource)

-/+ null_resource.web&#x5B;1] (new resource required)
id: &quot;6827055886347134598&quot; =&gt; &lt;computed&gt; (forces new resource)
triggers.%: &quot;1&quot; =&gt; &lt;computed&gt; (forces new resource)
triggers.template_rendered: &quot;Hello \&quot;joe\&quot;\n,Hello \&quot;jimmy\&quot;\n&quot; =&gt; &quot;&quot; (forces new resource)

Plan: 2 to add, 0 to change, 2 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an &quot;-out&quot; parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
&quot;terraform apply&quot; is subsequently run.
</pre>
<p>That&#8217;s a bummer. From now on, every &#8220;plan&#8221; or &#8220;apply&#8221; run will report both our &#8220;init&#8221; file resources as changed and they will be regenerated on every Terraform run.</p>
<h2>5. Summary</h2>
<p>You can definitely use null resource to generate config files for another software. Still, it seems there&#8217;s a bug in the current (0.11.2) version of Terraform. It&#8217;s present also in few previous versions I checked. So, be careful when you add explicit dependencies between modules and other resources, as this might result in your &#8220;null&#8221; type resources to be always reported as changed.</p>
<p>The post <a href="https://tailored.cloud/devops/terraform_confg_files_changed_resources/">Generating arbitrary configuration files from Terraform; modules and &#8220;always changed&#8221; resources.</a> appeared first on <a href="https://tailored.cloud">Tailored Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tailored.cloud/devops/terraform_confg_files_changed_resources/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
