<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA["Day 1: Cloud-Native Terraform on AWS"]]></title><description><![CDATA["Day 1: Cloud-Native Terraform on AWS"]]></description><link>https://terraform-day1.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 21 Sep 2026 22:15:05 GMT</lastBuildDate><atom:link href="https://terraform-day1.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[🏗️ From Chaos to Clarity: Mastering Terraform File Structure]]></title><description><![CDATA[Hello and welcome to the blog! I'm Priyanshu , and I'm excited to share the key takeaways from Day 6 of our 30 Days of AWS Terraform Challenge where we leveled up our Terraform project organization.
If you're writing code (or infrastructure-as-code),...]]></description><link>https://terraform-day1.hashnode.dev/from-chaos-to-clarity-mastering-terraform-file-structure</link><guid isPermaLink="true">https://terraform-day1.hashnode.dev/from-chaos-to-clarity-mastering-terraform-file-structure</guid><category><![CDATA[#Terraform #AWS #DevOps #InfrastructureAsCode #IaC #CloudComputing #PJDevOps #TerraformBestPractices #30DaysOfTerraform]]></category><dc:creator><![CDATA[Priyanshu Gupta]]></dc:creator><pubDate>Sun, 30 Nov 2025 11:18:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764501493561/cfa5baf6-20bc-4215-8989-5c289a90d6af.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello and welcome to the blog! I'm Priyanshu , and I'm excited to share the key takeaways from <strong>Day 6 of our 30 Days of AWS Terraform Challenge</strong> where we leveled up our <strong>Terraform project organization</strong>.</p>
<p>If you're writing code (or infrastructure-as-code), keeping things tidy is <em>essential</em>. Today, we focused on moving beyond a single, crowded file and structuring our project like a pro!</p>
<hr />
<p>Imagine trying to find a single recipe in a cookbook where all the ingredients, instructions, cooking times, and nutritional facts for <em>every</em> dish were mashed together on one giant page. That's what a single-file Terraform project can feel like!</p>
<p>In professional practice, we use a structured file layout to make our infrastructure code <strong>readable, maintainable,</strong> and <strong>efficient</strong>—just like organizing your kitchen cabinets so you can find the spices quickly!</p>
<h3 id="heading-why-we-split-files-the-non-tech-analogy">Why We Split Files (The Non-Tech Analogy)</h3>
<p>We started with everything in one file (<code>main.tf</code>). To improve, we separated different logical parts of the configuration into their own dedicated files.</p>
<table><tbody><tr><td><p><strong>Terraform Concept</strong></p></td><td><p><strong>What It Does</strong></p></td><td><p><strong>Real-World Analogy</strong></p></td></tr><tr><td><p><code>main.tf</code></p></td><td><p>Contains the core <strong>resources</strong> (like servers, databases, or networking components) we want to build.</p></td><td><p>The <strong>main construction blueprint</strong> for your building project.</p></td></tr><tr><td><p><code>variables.tf</code></p></td><td><p>Defines all the <strong>input parameters</strong> (like region name, server size, etc.) that can change between deployments.</p></td><td><p>The <strong>customization options sheet</strong>—do you want a blue car or a red car?</p></td></tr><tr><td><p><code>terraform.tfvars</code></p></td><td><p>Holds the <strong>specific values</strong> for the input variables defined in <code>variables.tf</code>.</p></td><td><p>The <strong>order form</strong> where you write down the <em>exact</em> color and size you want.</p></td></tr><tr><td><p><code>outputs.tf</code></p></td><td><p>Defines the values (like a newly created server's IP address) that are <strong>displayed after deployment</strong> for others to use.</p></td><td><p>The <strong>project completion summary</strong>—here's the new door code and the Wi-Fi password.</p></td></tr><tr><td><p><code>providers.tf</code></p></td><td><p>Configures the <strong>cloud provider</strong> (like AWS, Azure, Google Cloud) we are using.</p></td><td><p>Telling the construction crew which <strong>supplier</strong> (e.g., specific lumber company) to get materials from.</p></td></tr><tr><td><p><code>backend.tf</code></p></td><td><p>Configures where the <strong>state file</strong> (Terraform's memory of your infrastructure) will be stored remotely (e.g., in an S3 bucket).</p></td><td><p>The <strong>safety deposit box</strong> where you store the original, critical list of everything built.</p></td></tr><tr><td><p><code>locals.tf</code></p></td><td><p>Defines local, reusable values to avoid repetition within the code.</p></td><td><p>A <strong>short-hand list</strong> of common phrases or measurements used repeatedly throughout the blueprint.</p></td></tr></tbody></table>

<hr />
<h2 id="heading-the-hands-on-separation-process">🛠️ The Hands-On Separation Process</h2>
<p>In the video, we took our project from a single file to a clean, multi-file structure:</p>
<ol>
<li><p><strong>Backend Configuration:</strong> Moved the <code>backend "s3" { ... }</code> block into a new file: <code>backend.tf</code>. (Remember, this must be inside the <code>terraform { ... }</code> block!).</p>
</li>
<li><p><strong>Provider Definition:</strong> Extracted the AWS provider configuration to <code>providers.tf</code>.</p>
</li>
<li><p><strong>Input Variables:</strong> Moved all <code>variable "..." { ... }</code> definitions into <code>variables.tf</code>.</p>
</li>
<li><p><strong>Local Values:</strong> Moved the <code>locals { ... }</code> block into <code>locals.tf</code>.</p>
</li>
<li><p><strong>Outputs:</strong> Moved the <code>output "..." { ... }</code> definitions into <code>outputs.tf</code>.</p>
</li>
</ol>
<p>This leaves our original <code>main.tf</code> file much cleaner, containing only the <strong>resource blocks</strong> that define what we're actually building (like <code>resource "aws_s3_bucket" "..." { ... }</code>).</p>
<h3 id="heading-best-practice-using-gitignore">🛑 Best Practice: Using <code>.gitignore</code></h3>
<p>A crucial best practice for version control (like Git/GitHub) is using a <code>.gitignore</code> file.</p>
<ul>
<li><p><strong>Why?</strong> Terraform creates local files like:</p>
<ul>
<li><p><code>.terraform/</code> folder: Contains provider plugins and metadata.</p>
</li>
<li><p><code>*.tfstate*</code> files: Contains the current state of your infrastructure.</p>
</li>
</ul>
</li>
<li><p><strong>The Problem:</strong> These are temporary, large, or contain sensitive information that should <strong>not</strong> be uploaded to a public repository like GitHub.</p>
</li>
<li><p><strong>The Solution:</strong> We added entries to <code>.gitignore</code> to ensure these files (and the sensitive <code>terraform.tfvars</code> file) are ignored when committing to Git!</p>
</li>
</ul>
<hr />
<h2 id="heading-advanced-project-structure-the-next-level">🚀 Advanced Project Structure (The Next Level)</h2>
<p>For larger companies and complex infrastructure, even the structure we created today isn't enough. We touched upon two advanced concepts we'll explore later:</p>
<ol>
<li><p><strong>Environment-Based Separation:</strong> Creating separate folders/configurations for different deployment environments like <code>dev</code> (development), <code>staging</code> (testing), and <code>prod</code> (production).</p>
</li>
<li><p><strong>Using Modules:</strong> Breaking down large configuration into reusable, self-contained units (like a "Networking" module or a "Compute" module). This prevents repetition and makes your code truly scalable.</p>
</li>
</ol>
<hr />
<h2 id="heading-key-takeaway">💡 Key Takeaway:</h2>
<p>Good file structure in Terraform is a cornerstone of professional infrastructure-as-code. It helps you, your team, and future you understand the project quickly, making changes safer and more predictable!</p>
<hr />
<h2 id="heading-tl-dr-just-follow-these-visual-representation">TL / DR :- Just follow these visual representation</h2>
<pre><code class="lang-pgsql">                ┌───────────────────────────┐
                │     Terraform Project     │
                └──────────────┬────────────┘
                               │
     ┌─────────────────────────┼───────────────────────────┐
     │                         │                           │
┌────────────┐         ┌──────────────┐           ┌────────────────┐
│ providers.tf│         │ backend.tf   │           │ variables.tf   │
└──────┬──────┘         └──────┬──────┘           └──────┬─────────┘
       │                        │                         │
       ▼                        ▼                         ▼
 AWS provider setup      Remote state config       <span class="hljs-keyword">Input</span> variable definitions


     ┌─────────────────────────┼───────────────────────────┐
     │                         │                           │
┌────────────┐         ┌──────────────┐           ┌────────────────┐
│  locals.tf │         │  main.tf      │           │  outputs.tf    │
└──────┬──────┘         └──────┬──────┘           └──────┬─────────┘
       │                        │                         │
       ▼                        ▼                         ▼
 Reusable <span class="hljs-keyword">values</span>         Actual resources           <span class="hljs-keyword">Values</span> shown <span class="hljs-keyword">after</span>
  (shortcuts)               (S3, EC2, etc.)            apply completes


         ┌───────────────────────────────────────────┐
         │              .gitignore                   │
         └──────────────────┬────────────────────────┘
                            ▼
            Ignores .terraform/, tfstate*, tfvars
           (Sensitive + auto-<span class="hljs-keyword">generated</span> files)
</code></pre>
<h2 id="heading-keep-the-learning-momentum-going">➡️ Keep the Learning Momentum Going!</h2>
<p>You've been doing great learning in public! Make sure to complete the task for Day 6 in the GitHub repository and submit your progress.</p>
<p><strong>Next up: Day 7</strong> where we dive into <strong>Type Constraints</strong> in Terraform variables.</p>
<p>If you enjoyed this write-up, follow along on my journey and connect with me!</p>
<p>Hashtags:</p>
<p>#Terraform #AWS #DevOps #InfrastructureAsCode #IaC #CloudComputing #PJDevOps #TerraformBestPractices #30DaysOfTerraform</p>
<ul>
<li><p><strong>Connect with me on LinkedIn:</strong> <a target="_blank" href="https://www.linkedin.com/in/priyanshu8787">Priyanshu Gupta on LinkedIn</a></p>
</li>
<li><p><strong>Check out my code on GitHub:</strong> <a target="_blank" href="http://github.com/priyanshuprafful">priyanshuprafful's GitHub</a></p>
</li>
<li><p><strong>Join the discussion on Telegram:</strong> <a target="_blank" href="https://t.me/priyanshuprafful">Priyanshu's Telegram</a></p>
</li>
</ul>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Follow this Video <a target="_self" href="https://www.youtube.com/watch?v=QMsJholPkDY">https://www.youtube.com/watch?v=QMsJholPkDY</a></div>
</div>]]></content:encoded></item><item><title><![CDATA[Day 1: Ditching "ClickOps" & Building a Cloud-Native Terraform Setup on AWS]]></title><description><![CDATA[This is a fantastic strategy. Creating a long-form blog on Hashnode allows you to document your technical decisions (like using RHEL 9 and IAM roles) in detail, which is excellent for your portfolio.
Since you are using a "Cloud-Native" setup (develo...]]></description><link>https://terraform-day1.hashnode.dev/day-1-ditching-clickops-and-building-a-cloud-native-terraform-setup-on-aws</link><guid isPermaLink="true">https://terraform-day1.hashnode.dev/day-1-ditching-clickops-and-building-a-cloud-native-terraform-setup-on-aws</guid><category><![CDATA[#Terraform, #AWS, #DevOps, #RHEL, #InfrastructureAsCode]]></category><dc:creator><![CDATA[Priyanshu Gupta]]></dc:creator><pubDate>Wed, 26 Nov 2025 15:07:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764169536305/c8ee1149-108a-4142-80f6-19285197cbd3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is a fantastic strategy. Creating a long-form blog on Hashnode allows you to document your technical decisions (like using RHEL 9 and IAM roles) in detail, which is excellent for your portfolio.</p>
<p>Since you are using a <strong>"Cloud-Native" setup</strong> (developing <em>on</em> the cloud, for the cloud), I have highlighted this as a pro-move in the blog post.</p>
<p>Here is the complete Markdown draft for your Hashnode article. You can copy-paste this directly into the Hashnode editor.</p>
<hr />
<h1 id="heading-day-1-ditching-clickops-amp-building-a-cloud-native-terraform-setup-on-aws">Day 1: Ditching "ClickOps" &amp; Building a Cloud-Native Terraform Setup on AWS</h1>
<h2 id="heading-introduction-the-it-works-on-my-machine-problem">👋 Introduction: The "It Works on My Machine" Problem</h2>
<p>We’ve all been there. You spend 2 hours manually clicking through the AWS Console to set up a 3-tier architecture (Web, App, DB). It works perfectly. Then, your manager asks you to replicate it for the "QA" environment.</p>
<p>Suddenly, you are spending another 2 hours clicking buttons, hoping you don't miss a single checkbox. If you do, you end up with <strong>Configuration Drift</strong>—where your Dev environment works, but QA fails.</p>
<p>Today, I officially started the <strong>AWS Terraform 30-Day Series</strong> by <strong>Piyush Sachdeva</strong> to solve exactly this problem. The goal? To stop "ClickOps" and start treating infrastructure as software.</p>
<hr />
<h2 id="heading-my-cloud-native-lab-setup">🛠️ My "Cloud-Native" Lab Setup</h2>
<p>Most tutorials suggest running Terraform on your local Windows/Mac laptop. However, in a real enterprise environment, you often work from a jump server or a CI/CD runner.</p>
<p>To simulate a real-world scenario, I decided to build a <strong>Cloud-Native Development Environment</strong>.</p>
<h3 id="heading-1-the-workstation-ec2-rhel-9">1. The Workstation (EC2 + RHEL 9)</h3>
<p>Instead of my local machine, I launched an <strong>AWS EC2 instance running Red Hat Enterprise Linux 9 (RHEL 9)</strong>. This serves as my dedicated workstation.</p>
<ul>
<li><p><strong>Why RHEL?</strong> It’s the industry standard for enterprise Linux environments.</p>
</li>
<li><p><strong>Why EC2?</strong> It keeps my development environment consistent, regardless of which computer I access it from.</p>
</li>
</ul>
<h3 id="heading-2-security-best-practice-iam-roles-vs-keys">2. Security Best Practice (IAM Roles vs. Keys)</h3>
<p>This is the most critical part of my setup.</p>
<ul>
<li><p><strong>The Anti-Pattern:</strong> Storing <code>AWS_ACCESS_KEY_ID</code> and <code>AWS_SECRET_ACCESS_KEY</code> in local files or environment variables. This is a security risk.</p>
</li>
<li><p><strong>My Approach:</strong> I created an <strong>IAM Role with Administrator Access</strong> and attached it directly to my EC2 instance.</p>
</li>
<li><p><strong>The Result:</strong> Terraform automatically fetches temporary credentials from the EC2 Instance Metadata Service. No hardcoded secrets! 🔒</p>
</li>
</ul>
<hr />
<h2 id="heading-installing-terraform-on-rhel-9">⚙️ Installing Terraform on RHEL 9</h2>
<p>Since I am using RHEL 9, the installation process is slightly different from Ubuntu/Debian. Here are the commands I used to get up and running:</p>
<p>Bash</p>
<pre><code class="lang-plaintext"># 1. Install yum-utils to manage repositories
sudo yum install -y yum-utils

# 2. Add the official HashiCorp Linux repository
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

# 3. Install Terraform
sudo yum -y install terraform

# 4. Verify installation
terraform -version
</code></pre>
<p><em>Result:</em> <code>Terraform v1.5.x on linux_amd64</code></p>
<hr />
<h2 id="heading-the-terraform-workflow-lifecycle">🔄 The Terraform Workflow (Lifecycle)</h2>
<p>We learned that Terraform doesn't just "run" scripts; it follows a strict lifecycle to ensure safety.</p>
<p>Here is a visual representation of how the workflow interacts with the AWS API:</p>
<p>Code snippet</p>
<pre><code class="lang-plaintext">sequenceDiagram
    participant User as 👨‍💻 DevOps Engineer
    participant TF as 🟣 Terraform CLI
    participant State as 📄 State File
    participant AWS as ☁️ AWS Cloud

    User-&gt;&gt;TF: terraform init
    TF-&gt;&gt;TF: Downloads AWS Provider Plugins

    User-&gt;&gt;TF: terraform plan
    TF-&gt;&gt;State: Reads current state
    TF-&gt;&gt;AWS: Refreshes infrastructure data
    TF-&gt;&gt;User: 📝 Shows "Dry Run" (Proposed Changes)

    User-&gt;&gt;TF: terraform apply
    TF-&gt;&gt;AWS: 🚀 Calls APIs to Create/Update Resources
    AWS--&gt;&gt;TF: Resource IDs &amp; Details
    TF-&gt;&gt;State: Updates State File
</code></pre>
<h3 id="heading-the-4-main-commands">The 4 Main Commands</h3>
<ol>
<li><p><code>terraform init</code>: The "boot up" command. It looks at your configuration and downloads the specific provider plugins (like AWS) needed to talk to the cloud.</p>
</li>
<li><p><code>terraform plan</code>: The "sanity check." It compares what you <em>want</em> (your code) vs. what currently <em>exists</em> (in AWS) and tells you exactly what it will do. <strong>Always run this!</strong></p>
</li>
<li><p><code>terraform apply</code>: The "do it" command. This actually makes the API calls to create resources like VPCs or EC2 instances.</p>
</li>
<li><p><code>terraform destroy</code>: The "cleanup" command. Since I am learning, I run this at the end of the day to ensure I don't get a surprise bill from AWS. 💸</p>
</li>
</ol>
<hr />
<h2 id="heading-next-steps">🚀 Next Steps</h2>
<p>Today was about laying the foundation. I have my RHEL 9 server ready, my VS Code connected via Remote-SSH, and my GitHub repo initialized.</p>
<p>Tomorrow, we dive into <strong>Providers</strong> and understanding how Terraform actually talks to different clouds without getting confused.</p>
<p>🔗 Repository: <a target="_blank" href="https://github.com/priyanshuprafful/AWS-Terraform-">https://github.com/priyanshuprafful/AWS-Terraform-</a></p>
<p>🎥 Series: [AWS Terraform 30 Day Series by Piyush Sachdeva]</p>
<p><a target="_blank" href="https://www.youtube.com/watch?v=s5fwSG_00P8">Day 1 Video link</a></p>
<hr />
<p><em>Are you learning Terraform too? Let me know in the comments if you prefer running it locally or on a cloud instance like me! 👇</em></p>
<hr />
<p><code>#Terraform</code>, <code>#AWS</code>, <code>#DevOps</code>, <code>#RHEL</code>, <code>#InfrastructureAsCode</code></p>
]]></content:encoded></item></channel></rss>