Skip to content

Added a new "Terraform Imports" tab that generates Terraform 1.5+ import blocks for AWS resources#397

Open
anup2230 wants to merge 1 commit intoiann0036:masterfrom
anup2230:terraform-import-blocks-generation-feature
Open

Added a new "Terraform Imports" tab that generates Terraform 1.5+ import blocks for AWS resources#397
anup2230 wants to merge 1 commit intoiann0036:masterfrom
anup2230:terraform-import-blocks-generation-feature

Conversation

@anup2230
Copy link
Copy Markdown

@anup2230 anup2230 commented Feb 26, 2026

Initial Code and Testing complete. Verified import block work for at least VPC, EC2, RDS, S3, Cloudfront, etc.. There might be some specific resources that need updates to the resource mapping.

Overview
Added a new "Terraform Imports" tab that generates Terraform 1.5+ import blocks for AWS resources selected in Former2, enabling batch imports without CLI commands.

Data Flow:

  1. User clicks "Generate"
  2. performF2Mappings() builds tracked_resources array
  3. compileOutputs() calls generateTerraformImports(tracked_resources)
  4. Returns object with tf_imports property
  5. app.js sets tf_imports_editor.getDoc().setValue(mapped_outputs['tf_imports'])
  6. Import blocks appear in UI

  1. NEW FILE: js/terraformImportMappings.js (606 lines)

Purpose: Maps CloudFormation resource types → Terraform types + identifier property names

Why:

  • Centralized mapping registry for all AWS resource types
  • Separates import logic from main application code
  • Easy to maintain and extend with new resource types
  1. getTerraformImportIdentifier() Function (Lines 418-517)

`function getTerraformImportIdentifier(cfnType, resourceData, trackedResource) {
const mapping = TERRAFORM_IMPORT_MAPPINGS[cfnType] || TERRAFORM_IMPORT_MAPPINGS['default'];

for (const path of mapping.identifierPath) {
    // 1. Check resourceData with exact match
    if (resourceData && resourceData[path]) { ... }
    
    // 2. Check resourceData with case-insensitive match
    if (resourceData) {
        const caseInsensitiveKey = Object.keys(resourceData).find(
            key => key.toLowerCase() === path.toLowerCase()
        );
        if (caseInsensitiveKey) { ... }
    }
    
    // 3-6. Same for trackedResource.options.cfn and trackedResource.obj.data
}

// Final fallback: search for any 'id' property
return null;

}`

Purpose: Property lookup that finds the resource identifier from various data sources

Strategy (6-level fallback cascade):

a. Exact match in resourceData - Direct property lookup (e.g., resourceData['InstanceId'])
b. Case-insensitive match in resourceData - Handles PascalCase vs camelCase variants
c. Exact match in trackedResource.options.cfn - CloudFormation mapped properties
d .Case-insensitive match in options.cfn
e. Exact match in trackedResource.obj.data - Raw AWS SDK data
f. Case-insensitive match in obj.data
g. Final fallback - Search for any property named 'id' or 'Id'

  1. generateTerraformImports() Function (Lines 524-606)
    Purpose: Generates HCL import blocks for all tracked resources

Output Format (Terraform 1.5+ syntax):

import {
  to = aws_instance.EC2Instance
  id = "i-1234567890abcdef0"
}

Error Handling (Lines 540-567):

  • When identifier not found, generates diagnostic output showing:
    • What properties were expected
    • What properties exist in CFN mapping
    • What properties exist in raw data
  • Still creates import block with placeholder
  • Console logging for browser DevTools debugging
  1. MODIFIED: index.html
    Change 1: Navigation Tab (Line 238)
    Why: Adds the tab button to switch to Terraform Imports view

Change 2: Copy Button (Line 661)
Why:

  • Provides one-click copy functionality for the import blocks
  • Initially hidden (display: none) - shown only when Terraform Imports tab is active
  • Uses clipboard.js library (already loaded in Former2)

Change 3: Terraform Imports Section (Lines 1551-1556)
Why:

  • Container for the Terraform imports output
  • Uses <textarea> which will be replaced by CodeMirror editor
  • 30 rows provides good default height

Change 4: Script Include (Line 1637)
<script src="js/terraformImportMappings.js"></script>

  1. MODIFIED: js/app.js
    Change 1: Hide Copy Button Initially (Line 707)
    Why: All output copy buttons are hidden by default, shown only when their tab is active

Change 2: Tab Navigation Event Handler (Lines 828-834)
Why:

  • Triggered when user clicks Terraform Imports tab
  • Hides all other copy buttons, shows Terraform Imports copy button
  • Calls tf_imports_editor.refresh() to re-render CodeMirror editor (fixes display issues)

Change 3: Set Editor Value (Line 917)
Why:

  • Updates the CodeMirror editor content with generated import blocks
  • Called whenever user clicks "Generate" button
  • mapped_outputs object comes from compileOutputs() in mappings.js

Change 4: CodeMirror Editor Initialization (Line 1170)
Why Each Setting:

  • mode: "shell" - Syntax highlighting for HCL (closest mode available; HCL syntax is similar to shell)
  • readOnly: true - Users can't edit (it's generated output)
  • lineNumbers: true - Shows line numbers for easy reference
  • theme: "neat" - Matches other Former2 editors
  • viewportMargin: Infinity - Renders all content (important for copy functionality)

Change 5: Copy Button Event Handler (Line 1181)
Why:

  • Connects copy button to CodeMirror editor
  • setCopyEvent() is a Former2 helper function that configures clipboard.js
  • When clicked, copies entire editor content to clipboard
  1. MODIFIED: js/mappings.js (4974 lines total)
    Change: Add Terraform Imports to Output (Line 4427)
    Why:
  • compileOutputs() generates all output formats
  • Returns object with keys for each format (cfn, terraform, sam, etc.)
  • Adding tf_imports key makes it available in mapped_outputs

@iann0036
Copy link
Copy Markdown
Owner

Appreicate the effort. I don't think the strategy of attempting to map to CFN types is a good idea. We deliberately split TF types out as there are both TF-only and CFN-only types around. Instead of having a mapping in one file, I'd add a ImportTerraform or similar block about here https://github.com/iann0036/former2/blob/master/js/services/ec2.js#L2642 for the aws_ec2_instance example, then process these in the same way all the other outputs are generated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants