Tf2cdk – Convert Terraform to AWS CDK (Not Cdktf)

Written by jtaylortech | Published 2025/11/06
Tech Story Tags: terraform | infrastructure-as-code | cloud-infrastructure | cdk | aws | aws-cdk | tf2cdk | aws-eks

TLDRSame issue: migrating to Control Tower requires CloudFormation. Existing infrastructure is Terraform. I've built a command-line tool that converts Terraform configurations to native AWS CDK code.via the TL;DR App

Hey HN! I built tf2cdk - a CLI that converts Terraform configurations to native AWS CDK code.

GitHub: https://github.com/jtaylortech/tf2cdk

Important: This is NOT cdktf

cdktf (CDK for Terraform):

  • Write CDK code that generates Terraform
  • Outputs HCL, uses Terraform state
  • For teams who want CDK's programming model with Terraform's engine

tf2cdk (this project):

  • Converts existing Terraform TO native CDK
  • Outputs CDK code, uses CloudFormation stacks
  • For teams migrating OFF Terraform entirely

Different problems. Not competitors.

The Problem

I've worked with multiple organizations migrating to AWS Control Tower. Every time, same issue:

Control Tower requires CloudFormation. Existing infrastructure is Terraform. Manual conversion takes 2-4 months for large codebases.

This also happens with:

  • Landing Zone Accelerator (LZA) - CloudFormation only
  • AWS Service Catalog - Native CloudFormation integration
  • Terraform licensing concerns - Teams want to eliminate Terraform entirely

How It Works

tf2cdk is a Python CLI that:

  1. Parses HCL - Uses python-hcl2 to parse Terraform files
  2. Maps resources - 30+ Terraform resources → CDK constructs
  3. Generates code - Idiomatic TypeScript or Python
  4. Validates - Type-safe with comprehensive error handling
tf2cdk convert ./terraform --output ./cdk-app --language typescript

All generated code lives in the output directory. You can inspect/modify it.

Example

Input (Terraform):

resource "aws_s3_bucket" "data" {
  bucket = "my-data-bucket"
  
  tags = {
    Environment = "production"
  }
}

resource "aws_s3_bucket_versioning" "data" {
  bucket = aws_s3_bucket.data.id
  versioning_configuration {
    status = "Enabled"
  }
}

Output (CDK TypeScript):

import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

export class InfrastructureStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const data = new s3.Bucket(this, 'Data', {
      bucketName: 'my-data-bucket',
      versioned: true,
      tags: { Environment: 'production' },
    });
  }
}

Notice how it:

  • Merges aws_s3_bucket_versioning into the bucket (CDK pattern)
  • Converts snake_case to camelCase
  • Generates clean, idiomatic code

Technical Details

Architecture:

Terraform HCL
    ↓ (python-hcl2)
Parsed Config
    ↓ (Resource Mapper)
CDK Model
    ↓ (Code Generator)
TypeScript/Python

Resource Mappings:

RESOURCE_MAPPINGS = {
    'aws_s3_bucket': {
        'cdk_class': 's3.Bucket',
        'module': 'aws-cdk-lib/aws-s3',
        'props': {'bucket': 'bucketName', 'tags': 'tags'}
    },
    # 30+ more...
}

Error Handling:

  • Validates source files exist
  • Catches HCL parse errors with helpful tips
  • Warns about unsupported resources
  • Shows conversion progress
  • Proper exit codes for automation

Testing:

  • 28 tests (parser, converter, generator, CLI, edge cases)
  • Tests empty configs, unsupported resources, complex props
  • CLI integration tests for all commands
  • All tests passing

Supported Resources (30+)

Compute: EC2, Lambda, ECS, Auto Scaling Storage: S3, EBS, EFS Database: RDS, DynamoDB, ElastiCache Network: VPC, Subnet, Security Groups, Route53, ALB/NLB Security: IAM, KMS, Secrets Manager Monitoring: CloudWatch, SNS, SQS

Community contributions welcome for additional resources.

Special Patterns

# Control Tower account factory structure
tf2cdk convert ./terraform --pattern control-tower

# Landing Zone Accelerator format
tf2cdk convert ./terraform --pattern lza

# GovCloud compliance annotations
tf2cdk convert ./terraform --pattern govcloud

Why Open Source?

Terraform→CDK conversion is a one-time migration problem. You need it once, then you're done.

Making it free and open source:

  • Maximizes adoption
  • Gets community contributions (more resource mappings)
  • Helps the entire AWS community
  • Builds credibility

For large migrations needing implementation services, those are available separately. But the tool itself is free forever (MIT License).

Limitations

  • Complex Terraform expressions may need manual adjustment
  • Custom providers need manual mapping configuration
  • State migration is guided, not fully automated
  • Some Terraform-specific features (provisioners) have no CDK equivalent

Roadmap

v0.1.0 (current): 30+ resources, TypeScript/Python, basic patterns v0.2.0: 50+ resources, state import planning, more patterns v0.3.0: 100+ resources, module conversion, advanced expressions v1.0.0: Comprehensive resource coverage, GUI (optional)

Try It

# Homebrew
brew tap jtaylortech/tf2cdk
brew install tf2cdk

# pip
pip install tf2cdk

# Convert
tf2cdk convert ./terraform --output ./cdk-app --dry-run

Feedback Wanted

  • What Terraform resources are you using that aren't supported?
  • What patterns would help (multi-account, multi-region, etc.)?
  • What's your Terraform→CDK migration pain point?
  • Documentation gaps?

All code is on GitHub, MIT licensed. Issues and PRs welcome.


Related: If you're looking for CDK→Terraform (opposite direction), check out cdktf from HashiCorp. Different use case, both tools are useful.


Written by jtaylortech | Engineer @ AWS with expertise in Cloud Infrastructure. USAF Veteran.
Published by HackerNoon on 2025/11/06