<?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: Ashutosh Shukla</title>
    <description>The latest articles on DEV Community by Ashutosh Shukla (@ashutosh_shukla_devt).</description>
    <link>https://dev.to/ashutosh_shukla_devt</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4101800%2F80df4213-e857-4ac6-948f-67f9c3c5b1d9.png</url>
      <title>DEV Community: Ashutosh Shukla</title>
      <link>https://dev.to/ashutosh_shukla_devt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ashutosh_shukla_devt"/>
    <language>en</language>
    <item>
      <title>Why your Docker Build time is more than it should ?</title>
      <dc:creator>Ashutosh Shukla</dc:creator>
      <pubDate>Sat, 10 Oct 2026 16:40:50 +0000</pubDate>
      <link>https://dev.to/ashutosh_shukla_devt/why-your-docker-build-time-is-more-than-it-should--38ea</link>
      <guid>https://dev.to/ashutosh_shukla_devt/why-your-docker-build-time-is-more-than-it-should--38ea</guid>
      <description>&lt;p&gt;If you have ever worked with Docker &amp;amp; written any Dockerfile for any backend service that includes some language &amp;amp; its packages &amp;amp; an image. chances are you have faced this problem of high Dockerfile build time already.&lt;/p&gt;

&lt;p&gt;You might not have noticed it because for a self-paced project, these delays are in seconds which don't matter much to us. But when our hands are messing with 100s of containers using kubernets pods. These delay becomes the reason of large containers which takes more time to rebuild.&lt;/p&gt;

&lt;p&gt;Hence it becomes necessary to grab the depth of this Idea early stage. &lt;/p&gt;

&lt;p&gt;Today we will see with live example from one of my production style project where I tried to containerize a Go service. &amp;amp; understand -&amp;gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;why certain steps come  in top &amp;amp; why some in bottom of the Dockerfile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Difference between a Good Order &amp;amp; Bad Order Dockerfile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thumb Rule of Writing efficient Dockerfiles.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;1) go service from otel-demo (an open source project) &lt;/p&gt;

&lt;p&gt;2) Two Dockerfiles that differ by three moved lines&lt;/p&gt;




&lt;h2&gt;
  
  
  Dockerfile_v1(Good Order)
&lt;/h2&gt;

&lt;p&gt;In this Docker file, {1,2,3} lines are important libraries &amp;amp; checksum files needed to run any go file. This step of downloading the library into the working directory of our image is slow step &amp;amp; takes longer time than the rest of the layers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Therefore, we have something called &lt;code&gt;Layer caching&lt;/code&gt; in Docker. In the first cold build, every step runs one time, but in the next run, every step or layer that is unchanged gets cached, &amp;amp; docker uses that cached data instead of rebuilding the whole layer. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If that layer is changed, then every layer following that layer gets rebuilt, including itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.27.1-bookworm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.mod go.mod   (1)&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.sum go.sum   (2)&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download  &lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&lt;/span&gt;
 &lt;span class="c"&gt;# ~ 30 sec build time, slow step:downloads-libraries&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; genproto/oteldemo genproto/oteldemo  (4)&lt;/span&gt;
 &lt;span class="c"&gt;# source code comes AFTER the download&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; flags flags                          (5)    &lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; *.go ./                              (6)&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build &lt;span class="nt"&gt;-o&lt;/span&gt; /plain-linux-binary
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3550&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["/plain-linux-binary"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't have any Idea what this code block is about, Don't worry - today we are not here to understand what these statement means but to understand  what do we get to see if we change the order of these Instructions.&lt;/p&gt;

&lt;p&gt;Are you ready :)&lt;/p&gt;

&lt;h2&gt;
  
  
  The Experiment
&lt;/h2&gt;

&lt;p&gt;In this experiment we would change the order of good order dockerfile &amp;amp; will see what change we get to see in our build time. Using those numbers we would discern &amp;amp; find out how should we optimize our Dockerfile for minimum build time.&lt;/p&gt;

&lt;p&gt;we are going to swap lines {4,5,6} which copy and downloads the source code and put them just above the {3} &amp;amp; will Observe the changes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;Dockerfile__v2(Bad Order):
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.27.1-bookworm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.mod go.mod   (1)&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.sum go.sum   (2)&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; genproto/oteldemo genproto/oteldemo  (4)&lt;/span&gt;
 &lt;span class="c"&gt;# source code comes Before the download&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; flags flags                          (5)    &lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; *.go ./                              (6)&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download  &lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&lt;/span&gt;
 &lt;span class="c"&gt;# slow step:downloads-libraries&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build &lt;span class="nt"&gt;-o&lt;/span&gt; /plain-linux-binary
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3550&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["/plain-linux-binary"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  what's happening under the hood:
&lt;/h2&gt;

&lt;p&gt;In Good order -&amp;gt;   &lt;/p&gt;

&lt;p&gt;go.mod is copied and stored in /app work directory of an image  by named as go.mod&lt;/p&gt;

&lt;p&gt;go.sum is copied and stored in /app work directory of an image by named as go.sum&lt;/p&gt;

&lt;p&gt;&lt;code&gt;run go mod download&lt;/code&gt; downloads library into the image. &lt;/p&gt;

&lt;p&gt;Then {4,5,6}  steps are there to copy &amp;amp; download the source code.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Time it took for the Good Order build:
&lt;/h3&gt;

&lt;p&gt;1) Cold : 102.6 seconds ; as everything ran for the first time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;time &lt;/span&gt;docker build &lt;span class="nt"&gt;--no-cache&lt;/span&gt; &lt;span class="nt"&gt;--progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;plain &lt;span class="nt"&gt;-f&lt;/span&gt; docker/product-catalog/Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; fincomm/product-catalog:dev application/product-catalog  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Unchange: 3.8 seconds; as nothing in the code changed, so every layer is cached and got reused.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;time &lt;/span&gt;docker build &lt;span class="nt"&gt;--progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;plain &lt;span class="nt"&gt;-f&lt;/span&gt; docker/product-catalog/Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; fincomm/product-catalog:dev application/product-catalog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Change:  28 seconds; Now we change the source code a little by adding a comment in a main.go file in the last . so for the good order, the only step which re-ran were {4,,5,6} because they were copying &amp;amp; downloading source code into our image work directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"// cache test"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; application/product-catalog/main.go

&lt;span class="nb"&gt;time &lt;/span&gt;docker build &lt;span class="nt"&gt;--progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;plain &lt;span class="nt"&gt;-f&lt;/span&gt; docker/product-catalog/Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; fincomm/product-catalog:dev application/product-catalog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Time it took for the Bad Order build:
&lt;/h3&gt;

&lt;p&gt;Swapped:  55 second.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Noticed, How  swapped version of bad order  took more time than changed version of good order ? Any Idea why is that ? Try to build your own hypothesis &amp;amp; that way you can see if we match :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Apparently that happened because of just one mistake we did - shifted the &lt;code&gt;run go mod download&lt;/code&gt; after source code build. &lt;/p&gt;

&lt;p&gt;There is a Thumb rule of a Dockerfile. It says something like &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any layer which is changed, all layers following it including itself will get rebuilt. Docker would cached invalidate every layer after it including that layer itself. And that's why we place layers that rarely change (e.g., downloading dependencies/libraries) near the top (beginning) of the Dockerfile, and layers that change frequently (e.g., application source code) near the bottom (end) of the Dockerfile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now what happened in our bad order dockerfile:&lt;/p&gt;

&lt;p&gt;Docker invalidates the cache of "run go mod download" layer as it comes after the source code which got changed and rebuild &amp;amp; so as a default rule, this layer will get rebuild too. &lt;/p&gt;

&lt;p&gt;And this will increase the build time from what the good order Dockerfile normally take. &lt;/p&gt;

&lt;h2&gt;
  
  
  What you have to do right now:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You have to &lt;a href="https://share.gemini.google/BnAgnNoWRYjM" rel="noopener noreferrer"&gt;Interact with this live artifact to solidify your learning&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Draft a summary of what you have understand from this article &amp;amp; comment it under this Article &amp;amp; I will pinned down the best summary.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Immediately try to replicate this experiment with any  Dockerfile  for any language you could get. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;you just need to change order of source code &amp;amp; libraries or package to replicate the result, you will have your own numbers &amp;amp; your own experiment :) Use "time docker build ..." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Banner Image Credit: Gemini&lt;/strong&gt; &lt;/p&gt;

</description>
      <category>docker</category>
      <category>beginners</category>
      <category>buildinpublic</category>
      <category>devops</category>
    </item>
    <item>
      <title>21 yr old kid explaining terraform in stupid simple language</title>
      <dc:creator>Ashutosh Shukla</dc:creator>
      <pubDate>Fri, 04 Sep 2026 17:34:49 +0000</pubDate>
      <link>https://dev.to/ashutosh_shukla_devt/21-yr-old-kid-explaining-terraform-in-stupid-simple-language-4ppo</link>
      <guid>https://dev.to/ashutosh_shukla_devt/21-yr-old-kid-explaining-terraform-in-stupid-simple-language-4ppo</guid>
      <description>&lt;p&gt;What if I told you that instead of clicking through cloud dashboards, you could describe your entire infrastructure in a file and have it built automatically?&lt;/p&gt;

&lt;p&gt;That is exactly what Terraform does.&lt;/p&gt;

&lt;p&gt;In this blog, I am breaking down everything I have learned so far as a beginner. If you are curious about how companies actually manage cloud infrastructure at scale, keep reading because it gets interesting very quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Terraform?
&lt;/h2&gt;

&lt;p&gt;Terraform is an Infrastructure as Code (IaC) tool created by HashiCorp.&lt;br&gt;
But here is the part that makes it powerful.&lt;br&gt;
It behaves like API as Code.&lt;/p&gt;

&lt;p&gt;Instead of manually creating resources in AWS or Azure through a console, Terraform talks directly to cloud provider APIs and builds everything for you based on code.&lt;/p&gt;

&lt;p&gt;You define infrastructure using HCL (HashiCorp Configuration Language) inside a file called main.tf.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Now imagine this&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;What if your entire cloud setup could be recreated just by running a few commands from a file?&lt;/p&gt;

&lt;p&gt;That is Terraform.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Problem Did Terraform Solve?
&lt;/h2&gt;

&lt;p&gt;Before Terraform became popular, organisations that wanted to migrate infrastructure between cloud providers faced a huge challenge.&lt;/p&gt;

&lt;p&gt;Every cloud provider had its own syntax, tooling, and way of managing infrastructure. Migrating even a portion of infrastructure from one cloud to another often required months of effort, making hybrid and multi-cloud strategies expensive and inefficient.&lt;/p&gt;

&lt;p&gt;HashiCorp solved this problem by introducing Terraform.&lt;/p&gt;

&lt;p&gt;The idea was simple:&lt;/p&gt;

&lt;p&gt;Learn one tool, write your infrastructure as code, and use providers to interact with different cloud platforms instead of learning every provider's unique syntax from scratch.&lt;br&gt;
This made infrastructure much more portable across providers like AWS, Azure, Google Cloud, Oracle Cloud, DigitalOcean, and many others.&lt;/p&gt;
&lt;h2&gt;
  
  
  How Things Work Behind The Scene
&lt;/h2&gt;

&lt;p&gt;Terraform keeps track of everything using a file called &lt;code&gt;terraform.tfstate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Think of it as Terraform’s memory.It remembers what it created, what exists, and what needs to change.&lt;/p&gt;

&lt;p&gt;Now let’s walk through what actually happens when you run Terraform commands.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Step 1: terraform init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is where everything begins.Terraform reads your main.tf file and figures out which provider you are using, like AWS.Then it downloads the required provider plugin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is a simple way to think about it:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The provider plugin is like a translator between Terraform and the cloud.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Step 2: terraform plan&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is where things get interesting.&lt;br&gt;
Terraform builds a map of your infrastructure and compares it with what already exists in the cloud.&lt;/p&gt;

&lt;p&gt;It then shows you exactly what will change before doing anything.&lt;br&gt;
Nothing is created yet.This step is like a preview of your infrastructure changes.&lt;/p&gt;

&lt;p&gt;In technical terms, this mapping is termed as dependency graph. It tells us what resources are Created (+), Modified (~), and Deleted(-).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Step 3: terraform apply&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now the real execution begins. Once you approve the plan, Terraform sends instructions to the provider plugin.&lt;/p&gt;

&lt;p&gt;The plugin converts those instructions into API calls that the cloud provider understands.For example, AWS receives standard API requests and creates the resources.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Step 4: State Update&lt;/code&gt;&lt;br&gt;
After everything is created, the cloud provider returns important details like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Resource IDs
IP addresses
Metadata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terraform stores all of this inside terraform.tfstate.&lt;/p&gt;

&lt;p&gt;This is what allows Terraform to manage updates and changes later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Full Flow&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ main.tf ]
      │
      ▼
[ Terraform Core Engine ]
      │ (RPC)
      ▼
[ Provider Plugin ]
      │ (REST API)
      ▼
[ Cloud Provider ] 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What is RPC Doing Here?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or more appropriate question here can be -&amp;gt; &lt;code&gt;Why does Terraform need RPC?&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;RPC (Remote Procedure Call) acts as the communication bridge between Terraform Core and the Provider Plugin.&lt;/p&gt;

&lt;p&gt;Terraform Core and provider plugins are completely separate programs running on your machine. Since they don't share memory, they cannot communicate directly.&lt;/p&gt;

&lt;p&gt;RPC allows Terraform Core to send instructions to the provider plugin, which then translates them into API requests the cloud provider understands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variables
&lt;/h2&gt;

&lt;p&gt;These help you a lot in writing clean code, so here is what it is-&amp;gt;&lt;/p&gt;

&lt;p&gt;Variables make Terraform configurations reusable and flexible.&lt;/p&gt;

&lt;p&gt;Instead of hardcoding values inside main.tf, you can replace them with variables.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;For example&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance_type&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variable itself can be defined inside variables.tf with a default value.&lt;/p&gt;

&lt;p&gt;When you run terraform apply, Terraform checks whether you've supplied a value.&lt;/p&gt;

&lt;p&gt;If you provide one, Terraform uses it.&lt;br&gt;
If you don't, Terraform automatically falls back to the default value.&lt;/p&gt;

&lt;p&gt;This makes the same configuration reusable across different environments without editing the code every time.&lt;/p&gt;
&lt;h2&gt;
  
  
  Outputs
&lt;/h2&gt;

&lt;p&gt;Outputs are used to extract and display important information after Terraform finishes provisioning infrastructure.&lt;/p&gt;

&lt;p&gt;They are especially useful for developers who don't have direct access to the AWS Console but still need important deployment details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I like to think of it this way:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Its like those print statements we used to write in c, python et cetera. like if main.tf created ec2 instance, we define this outputs.tf file to print its public Ip address so that devs can use it later either to ssh into it or whatever purposes they want it to use for.   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Example:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main.tf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_instance"&lt;/span&gt; &lt;span class="s2"&gt;"web"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ami&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ami-0c55b159cbfafe1f0"&lt;/span&gt;
  &lt;span class="nx"&gt;instance_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"t2.micro"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Example:&lt;/code&gt;&lt;br&gt;
&lt;code&gt;output.tf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"server_ip"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;web&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public_ip&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"The public IP address of the server."&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After running:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;terraform apply&lt;/code&gt;&lt;br&gt;
Terraform immediately prints something similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server_ip = "54.213.42.1" 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This provides several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instant Visibility – View important information like URLs, IP addresses, or database endpoints without opening the AWS Console.&lt;/li&gt;
&lt;li&gt;Data Sharing – Pass resource IDs and outputs from one Terraform module to another.&lt;/li&gt;
&lt;li&gt;Security Masking – Mark outputs as &lt;code&gt;sensitive = true&lt;/code&gt; to prevent passwords and API keys from appearing on screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Terraform Examples&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you'd like to explore more Terraform code, you can visit my GitHub repository &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Ashut2/FinComm-prod-style-aws/tree/main/terraform/local_state" rel="noopener noreferrer"&gt;github-repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;look at the main.tf, outputs.tf &amp;amp; modules&lt;/code&gt; -&amp;gt; I know we haven't discussed modules here yet cause it will defeat the purpose of making it beginners-freindly. but for now just keep in mind they are just some repeatable HCL code which could use by root main.tf file to create &amp;amp; replicate the infra - like creating an simple ec2 instance. &lt;/p&gt;

&lt;p&gt;You can also simply search: &lt;code&gt;terraform example github&lt;/code&gt; on web browser.&lt;br&gt;
You'll find plenty of beginner-friendly repositories that demonstrate different Terraform use cases and infrastructure patterns.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Now If you've reached here, then it means you love this thing &amp;amp; so I want to leave you with a bonus point that most beginners get wrong about terraform. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Is Terraform only use for provisioning the cloud Infrastructure ?&lt;/strong&gt;&lt;br&gt;
Its a very basic question if you look into it, &amp;amp; most of the people never ask it because they are not learning why ? - Most of them are learning What ? &amp;amp; How ?&lt;/p&gt;

&lt;p&gt;So here is the main idea - Terraform uses this advance functionality called &lt;code&gt;API As Code&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So what this means is you can use Hashicorp Corporation Language (HCL) i.e  Terraform syntax language to create &amp;amp; update almost any Infrastructure of any Application until unless it has its API. Or If I'm more direct then-&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;You can use Terraform to manage non-cloud services, SaaS tools, and internal applications by using specialized providers that communicate directly with third-party REST API&lt;/code&gt;   &lt;/p&gt;

&lt;p&gt;So If someone asks you &lt;strong&gt;Is Terraform only use to provision cloud Infrastructure&lt;/strong&gt; - Now you know the answer!&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Beleive it or not-I tried my best to hand you over with the simplified knowledge of terraform and I hope you could use this to become familiar with the terraform so that Its documentation doesn't scare you anymore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; This article is a recreation of the article I published on my linkedin:&lt;a href="https://www.linkedin.com/pulse/how-i-would-like-learn-terraform-ashutosh-s--9xlof/" rel="noopener noreferrer"&gt;Linkedin Article Link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>beginners</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
