terraform-landscape icon indicating copy to clipboard operation
terraform-landscape copied to clipboard

Add support for Terraform 1.x+ while maintaining backward compatibility

Open aashari opened this issue 5 months ago • 1 comments

Description

This PR adds support for modern Terraform versions (1.x+) to terraform-landscape while maintaining full backward compatibility with Terraform 0.11.x.

Problem

As noted in issue #101, terraform-landscape was designed for Terraform 0.11.x and fails to parse the output from modern Terraform versions due to significant changes in the plan output format.

Key differences in modern Terraform output:

  • Resource headers use comment syntax: # resource.name will be created
  • Resource blocks use explicit type declaration: resource "type" "name" { ... }
  • Attribute changes use different formatting
  • Nested structures and complex objects have different representations

Solution

This PR enhances the printer module to automatically detect the Terraform version based on output format and apply the appropriate parsing strategy:

  1. Automatic format detection: The parser detects modern format by looking for specific patterns in the output
  2. Dual parsing modes: Maintains original parsing for 0.11.x while adding new logic for 1.x+
  3. Unified output: Both parsing modes produce consistent, beautifully formatted output

Changes Made

lib/terraform_landscape/printer.rb

  • Added format detection logic to identify modern Terraform output
  • Integrated modern parsing directly into process_string method (no separate functions)
  • Added support for all resource actions: create (+), destroy (-), update (~), replace (-/+)
  • Enhanced attribute parsing to handle -> and => operators
  • Added proper handling for nested objects and complex data structures
  • Maintained all original parsing logic for backward compatibility

grammar/terraform_plan.treetop

  • Extended grammar to support modern resource header format
  • Added rules for handling "will be" and "must be" action phrases
  • Enhanced attribute parsing for modern format
  • Preserved all original grammar rules

Testing

Tested with various Terraform operations:

  • ✅ Resource creation
  • ✅ Resource destruction
  • ✅ Resource updates (in-place)
  • ✅ Resource replacement
  • ✅ Complex nested attributes
  • ✅ Multiple resources in single plan
  • ✅ No changes scenario
  • ✅ Backward compatibility with 0.11.x format

Example Output

Before (raw Terraform 1.x output):

  # module.ecs_service.aws_ecs_service.main will be updated in-place
  ~ resource "aws_ecs_service" "main" {
        id   = "arn:aws:ecs:region:123:service/cluster/service"
        name = "my-service"
      ~ tags = {
            "Environment" = "prod"
          + "Team"        = "platform"
        }
    }

After (terraform-landscape formatted):

~ aws_ecs_service.module.ecs_service.main
    id:   "arn:aws:ecs:region:123:service/cluster/service"
    name: "my-service"  
    tags: {
        "Environment": "prod"
        "Team":        => "platform"
    }

Compatibility

  • ✅ Terraform 0.11.x (existing support maintained)
  • ✅ Terraform 1.0+
  • ✅ Ruby 2.5+ (per gemspec requirements)

Future Considerations

This implementation focuses on supporting the most common Terraform output patterns. Edge cases or provider-specific output formats may require additional enhancements.

References

  • Related to #101
  • Tested with Terraform v1.12.1

aashari avatar Jul 12 '25 21:07 aashari

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 1
Sum 2

cb-heimdall avatar Jul 12 '25 21:07 cb-heimdall