<?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: David Lu</title>
    <description>The latest articles on DEV Community by David Lu (@davidlu1001).</description>
    <link>https://dev.to/davidlu1001</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3726869%2F242d4e7f-6501-4890-8923-5c723135d20d.jpg</url>
      <title>DEV Community: David Lu</title>
      <link>https://dev.to/davidlu1001</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/davidlu1001"/>
    <language>en</language>
    <item>
      <title>Two Terraform Traps That Burned Me: Hidden Defaults &amp; Circular Dependencies</title>
      <dc:creator>David Lu</dc:creator>
      <pubDate>Thu, 22 Jan 2026 18:57:37 +0000</pubDate>
      <link>https://dev.to/davidlu1001/two-terraform-traps-that-burned-me-hidden-defaults-circular-dependencies-4n74</link>
      <guid>https://dev.to/davidlu1001/two-terraform-traps-that-burned-me-hidden-defaults-circular-dependencies-4n74</guid>
      <description>&lt;p&gt;Bringing unmanaged AWS infrastructure under Terraform control—the classic &lt;strong&gt;'Brownfield Migration'&lt;/strong&gt;—is one of the most deceptive challenges in DevOps.&lt;/p&gt;

&lt;p&gt;On the surface, it looks like a simple scripting task: just wrap &lt;code&gt;terraform import&lt;/code&gt; and loop through resources. However, based on my experience navigating these migrations in complex environments, this naive approach almost always fails.&lt;/p&gt;

&lt;p&gt;The impedance mismatch between AWS and Terraform creates two distinct classes of problems that standard tools miss: &lt;strong&gt;Hidden API Defaults&lt;/strong&gt; and &lt;strong&gt;Graph Cycles&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is a technical breakdown of what went wrong and how we solved it using graph theory and strict schema mapping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trap 1: The &lt;code&gt;root_block_device&lt;/code&gt; &amp;amp; The "Silent" Replacement
&lt;/h2&gt;

&lt;p&gt;The task was simple: Import 34 production EC2 instances.&lt;br&gt;
After generating the HCL code and running &lt;code&gt;terraform plan&lt;/code&gt;, I expected a clean state.&lt;/p&gt;

&lt;p&gt;Instead, I got this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Plan: 34 to add, 0 to change, 34 to destroy.

# aws_instance.prod_web_01 must be replaced

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

&lt;/div&gt;


&lt;p&gt;Every single production instance was flagged for &lt;strong&gt;replacement&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Investigation
&lt;/h3&gt;

&lt;p&gt;Rule #1 of IaC is "Always read the plan." But when the plan says "replace," you need to know &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The diff looked like this:&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;-&lt;/span&gt;&lt;span class="err"&gt;/+&lt;/span&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;"prod_web_01"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="err"&gt;~&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"i-0abc123def456"&lt;/span&gt; &lt;span class="nx"&gt;-&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;known&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="nx"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;root_block_device&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;volume_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;    &lt;span class="c1"&gt;# Actual Prod State&lt;/span&gt;
          &lt;span class="nx"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;volume_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gp3"&lt;/span&gt;
          &lt;span class="nx"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;device_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/dev/xvda"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;root_block_device&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;volume_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;      &lt;span class="c1"&gt;# AMI Default&lt;/span&gt;
          &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;volume_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gp2"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  The Root Cause: Read-Only vs. Writable Attributes
&lt;/h3&gt;

&lt;p&gt;The issue wasn't just "I forgot to declare values." It was a conflict between the &lt;strong&gt;AWS API&lt;/strong&gt; and the &lt;strong&gt;Terraform Schema&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AWS API Reality&lt;/strong&gt;: When you query an instance, AWS returns &lt;em&gt;everything&lt;/em&gt;, including the &lt;code&gt;DeviceName&lt;/code&gt; (e.g., &lt;code&gt;/dev/xvda&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terraform Schema&lt;/strong&gt;: The &lt;code&gt;device_name&lt;/code&gt; inside &lt;code&gt;root_block_device&lt;/code&gt; is a &lt;strong&gt;Computed (Read-Only)&lt;/strong&gt; attribute. You cannot set it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you blindly map the API response to HCL, Terraform errors out because you're trying to set a read-only field.&lt;br&gt;
If you &lt;em&gt;omit&lt;/em&gt; the block entirely (thinking "it already exists"), Terraform assumes you want the &lt;strong&gt;AMI defaults&lt;/strong&gt; (often 8GB gp2).&lt;/p&gt;

&lt;p&gt;Because AWS cannot shrink a 100GB volume to 8GB in-place, Terraform's only option is to &lt;strong&gt;destroy and recreate the instance&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Fix: Surgical Mapping
&lt;/h3&gt;

&lt;p&gt;You can't just dump the API response. You have to filter it through a logic layer that understands the Terraform provider's quirks:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Pseudo-code for the fix
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transform_root_block_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ebs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Ebs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;volume_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ebs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VolumeType&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gp2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;# Keep writable attributes
&lt;/span&gt;        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;volume_size&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ebs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VolumeSize&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;volume_type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;volume_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delete_on_termination&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ebs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DeleteOnTermination&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;encrypted&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ebs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Encrypted&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Filter out Read-Only attributes that cause errors
&lt;/span&gt;    &lt;span class="c1"&gt;# - device_name
&lt;/span&gt;    &lt;span class="c1"&gt;# - volume_id
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;This ensures the generated code matches the &lt;em&gt;actual&lt;/em&gt; state of the disk without triggering schema violations.&lt;/p&gt;


&lt;h2&gt;
  
  
  Trap 2: The Cycle (Graph Theory vs. AWS Reality)
&lt;/h2&gt;

&lt;p&gt;If the first trap was a configuration error, the second was a fundamental structural conflict.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform requires a Directed Acyclic Graph (DAG). AWS allows cycles.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The Deadlock
&lt;/h3&gt;

&lt;p&gt;The most common culprit is Security Groups. Imagine two microservices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SG-App&lt;/code&gt; allows outbound traffic to &lt;code&gt;SG-DB&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SG-DB&lt;/code&gt; allows inbound traffic from &lt;code&gt;SG-App&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you write this with inline rules (which is what &lt;code&gt;terraform import&lt;/code&gt; generates by default), you create a cycle:&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_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"app"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;egress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;security_groups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Needs DB's ID&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"db"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;security_groups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Needs App's ID&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;Terraform cannot apply this. It can't create &lt;code&gt;app&lt;/code&gt; without &lt;code&gt;db&lt;/code&gt;'s ID, and vice versa.&lt;/p&gt;
&lt;h3&gt;
  
  
  Visualizing the Problem
&lt;/h3&gt;

&lt;p&gt;In a healthy Terraform config, dependencies flow one way:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[VPC] --&amp;gt; [Subnet] --&amp;gt; [EC2]

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

&lt;/div&gt;


&lt;p&gt;But Security Groups often form cycles (Strongly Connected Components):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     ┌──────────────┐
     ▼              │
  [SG-App]       [SG-DB]
     │              ▲
     └──────────────┘

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  The Solution: Tarjan's Algorithm &amp;amp; "Shell &amp;amp; Fill"
&lt;/h3&gt;

&lt;p&gt;When building &lt;a href="https://github.com/RepliMap/replimap-community" rel="noopener noreferrer"&gt;RepliMap&lt;/a&gt; (the tool I wrote to automate this), I realized we couldn't just export resources one by one. We had to model the entire AWS account as a graph using &lt;strong&gt;NetworkX&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We use &lt;strong&gt;Tarjan's algorithm&lt;/strong&gt; to detect Strongly Connected Components (SCCs)—the "knots" in the graph.&lt;/p&gt;

&lt;p&gt;Once a cycle is detected, we use a &lt;strong&gt;"Shell &amp;amp; Fill"&lt;/strong&gt; strategy to break it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create Empty Shells&lt;/strong&gt;: Generate the Security Groups with &lt;em&gt;no rules&lt;/em&gt;. Terraform can create these instantly because they have no dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fill with Rules&lt;/strong&gt;: Extract the rules into separate &lt;code&gt;aws_security_group_rule&lt;/code&gt; resources. These reference the IDs of the shells created in step 1.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Create Shells (No Dependencies)
  [SG-App (empty)]      [SG-DB (empty)]

Step 2: Create Rules (Reference Shells)
        ▲                     ▲
        │                     │
  [Rule: egress-&amp;gt;DB]    [Rule: ingress&amp;lt;-App]

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

&lt;/div&gt;


&lt;p&gt;The graph is now acyclic, and Terraform is happy.&lt;/p&gt;


&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Tools like &lt;code&gt;terraform import&lt;/code&gt; or &lt;code&gt;Terraformer&lt;/code&gt; are great starting points, but they often act as simple API-to-HCL dumpers. They don't always account for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Implicit Defaults&lt;/strong&gt;: Where missing config != existing state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph Topology&lt;/strong&gt;: Where valid AWS states are invalid Terraform states.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For small projects, you can fix these manually. For brownfield migrations with 2,000+ resources, you need a deterministic engine to handle the translation.&lt;/p&gt;

&lt;p&gt;I've open-sourced the documentation and the read-only IAM policies for the engine we built to solve this. If you're interested in the edge cases of AWS imports, check it out:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/RepliMap" rel="noopener noreferrer"&gt;
        RepliMap
      &lt;/a&gt; / &lt;a href="https://github.com/RepliMap/replimap-community" rel="noopener noreferrer"&gt;
        replimap-community
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Reverse-engineer AWS infrastructure into production-ready Terraform. Visualize dependencies, detect drift, estimate costs.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;RepliMap&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;strong&gt;AWS Infrastructure Intelligence Engine&lt;/strong&gt;
&lt;/p&gt;

&lt;p&gt;
  Reverse-engineer any AWS account. Visualize dependencies. Generate Terraform. Optimize costs
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://github.com/RepliMap/replimap-community#quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt; •
  &lt;a href="https://github.com/RepliMap/replimap-community#features" rel="noopener noreferrer"&gt;Features&lt;/a&gt; •
  &lt;a href="https://github.com/RepliMap/replimap-community#use-cases" rel="noopener noreferrer"&gt;Use Cases&lt;/a&gt; •
  &lt;a href="https://github.com/RepliMap/replimap-community#-limitations--scope" rel="noopener noreferrer"&gt;Limitations&lt;/a&gt; •
  &lt;a href="https://github.com/RepliMap/replimap-community#-frequently-asked-questions" rel="noopener noreferrer"&gt;FAQ&lt;/a&gt; •
  &lt;a href="https://github.com/RepliMap/replimap-community#documentation" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://pypi.org/project/replimap/" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/c64db7771f4f02cb98a02163cca5351ea3f39ce065b81daca23e69b40954852b/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f7265706c696d61703f636f6c6f723d626c7565266c6162656c3d50795049" alt="PyPI"&gt;
  &lt;/a&gt;
  &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/93a33cfc2339ec3fa9be792576576fbaafc42b0c7031285662b02f3aca1e1c59/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302b2d626c75652e737667"&gt;&lt;img src="https://camo.githubusercontent.com/93a33cfc2339ec3fa9be792576576fbaafc42b0c7031285662b02f3aca1e1c59/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302b2d626c75652e737667" alt="Python 3.10+"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/RepliMap/replimap-community/LICENSE" rel="noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/7b96c7e036e4fe4b35b9e6788460ba9668e307bf2481a95ddec2ede3ebe706ee/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d42534c2d2d312e312d677265656e2e737667" alt="License"&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://dev.to/davidlu1001/two-terraform-traps-that-burned-me-hidden-defaults-circular-dependencies-4n74" rel="nofollow"&gt;
    &lt;img src="https://camo.githubusercontent.com/6e9d8af494854cbd05e6215e8066aade7be78730b9974a8c4778ce5d385d2281/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4465762e746f2d546563686e6963616c25323044656570253230446976652d3041304130413f7374796c653d666c61742d737175617265266c6f676f3d6465762e746f266c6f676f436f6c6f723d7768697465" alt="Dev.to"&gt;
  &lt;/a&gt;
  &lt;a href="https://news.ycombinator.com/item?id=46720620" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/15e3f613bedbdeebce974e9c5b5e3a027f96eb2c1d03de7885532b3666b0ed49/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4861636b65722532304e6577732d4a6f696e25323044697363757373696f6e2d4646363630303f7374796c653d666c61742d737175617265266c6f676f3d79636f6d62696e61746f72266c6f676f436f6c6f723d7768697465" alt="Hacker News"&gt;
  &lt;/a&gt;
  &lt;a href="https://twitter.com/davidlu1001" rel="nofollow noopener noreferrer"&gt;
    &lt;img src="https://camo.githubusercontent.com/410c8a27c30f90a8f674fba87e948a81bcc43f33a777c51d2c85108b242dd711/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547769747465722d466f6c6c6f77253230557064617465732d3144413146323f7374796c653d666c61742d737175617265266c6f676f3d74776974746572266c6f676f436f6c6f723d7768697465" alt="Twitter"&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/RepliMap/replimap-community/assets/demo-scan.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FRepliMap%2Freplimap-community%2Fassets%2Fdemo-scan.png" alt="RepliMap Demo" width="700"&gt;&lt;/a&gt;
&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;👋 About This Repository&lt;/strong&gt;
RepliMap is a &lt;strong&gt;commercial tool&lt;/strong&gt; built with a &lt;strong&gt;"Local-First"&lt;/strong&gt; architecture
This repository (&lt;code&gt;replimap-community&lt;/code&gt;) hosts &lt;strong&gt;documentation&lt;/strong&gt;, &lt;strong&gt;issue tracking&lt;/strong&gt;, and &lt;strong&gt;examples&lt;/strong&gt;.
The core engine is distributed via &lt;a href="https://pypi.org/project/replimap/" rel="nofollow noopener noreferrer"&gt;PyPI&lt;/a&gt;.
Your AWS credentials and data &lt;strong&gt;never leave your machine&lt;/strong&gt; — the only network call is license key validation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RepliMap&lt;/strong&gt; is an &lt;strong&gt;AWS Infrastructure Intelligence Engine&lt;/strong&gt; for DevOps and SRE teams.
&lt;em&gt;Not to be confused with RepliMap HD mapping software for autonomous vehicles.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;💡 TL;DR&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;RepliMap&lt;/strong&gt; is a read-only CLI tool that reverse-engineers existing AWS infrastructure into production-ready Terraform code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core capabilities:&lt;/strong&gt;&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;strong&gt;Graph Engine&lt;/strong&gt;: Uses Tarjan's algorithm to detect Strongly Connected Components (SCCs) and automatically resolve circular dependencies (e.g., Security Groups referencing each other)&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Smart Sanitization&lt;/strong&gt;…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/RepliMap/replimap-community" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;








&lt;h3&gt;
  
  
  💬 Join the discussion
&lt;/h3&gt;

&lt;p&gt;Interested in the graph theory aspect? We're discussing the Tarjan implementation and edge cases over on &lt;a href="https://news.ycombinator.com/item?id=46720620" rel="noopener noreferrer"&gt;Hacker News&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>aws</category>
      <category>sre</category>
    </item>
  </channel>
</rss>
