
September 10, 2026
13 min read
By Kokil Thapa | Last reviewed: September 2026
You need infrastructure as code, but the tooling split is confusing. AWS CDK vs CDKTF is not a branding difference — one synthesizes to CloudFormation for AWS-only stacks, while the other generates Terraform for any provider HashiCorp supports. On real client projects I have shipped Laravel apps to EC2 with GitLab CI and Deployer 7, and the IaC choice often decides whether ops can reuse existing Terraform modules or must adopt CloudFormation semantics. This guide compares synthesis, state, team fit, and day-two operations so you can pick the right tool before you commit a repo structure.
What is the difference between AWS CDK and CDKTF?
Both tools belong to the Cloud Development Kit family. You write application code in TypeScript, Python, Java, C#, or Go. A CLI synthesizes that code into an deployable artifact. The artifact is where they diverge.
AWS CDK treats infrastructure as real code and outputs CloudFormation templates. You deploy with cdk deploy. AWS owns the construct library, and every resource maps to CloudFormation resource types. State lives in CloudFormation stacks — no separate state file unless you bolt on custom tooling.
CDK for Terraform (CDKTF) outputs Terraform JSON or HCL. You deploy with cdktf deploy. It uses the Terraform CLI under the hood. State follows Terraform rules: local files, S3 + DynamoDB locking, Terraform Cloud, or any supported backend. Provider bindings come from the Terraform Registry, not AWS-maintained L2 constructs.
The mental model matters for hiring and onboarding. A team that already runs Terraform in production can adopt CDKTF without relearning state backends or module registries. A team greenfield on AWS with no Terraform investment often moves faster with AWS CDK because L2 constructs hide IAM wiring and sensible defaults.
Side-by-side comparison
| Criteria | AWS CDK | CDKTF |
|---|---|---|
| Output format | CloudFormation JSON/YAML | Terraform JSON/HCL |
| Cloud scope | AWS only | Any Terraform provider |
| Deploy command | cdk deploy | cdktf deploy |
| State management | CloudFormation stacks | Terraform backends (S3, TFC, etc.) |
| Construct library | Rich AWS L2/L3 constructs | Provider-generated bindings (L1-style) |
| Drift detection | CloudFormation drift checks | terraform plan |
| Module ecosystem | CDK constructs + CFN modules | Entire Terraform Registry |
| Multi-account AWS | Stack sets, custom patterns | Workspaces, separate state per env |
| Learning curve | Lower for AWS-only teams | Lower if team knows Terraform |
For PHP and Laravel workloads I deploy on Ubuntu EC2, the stack usually includes VPC, ALB, RDS, S3, and IAM roles. AWS CDK's aws-ec2 and aws-rds L2 constructs save hours on security group rules and subnet placement. CDKTF gives you the same resources through the AWS provider, but you compose them with Terraform idioms your platform team may already standardize in multi-account AWS layouts.
How does AWS CDK synthesize infrastructure compared to CDKTF?
Synthesis is the compile step. Neither tool talks to AWS or GCP during synthesis — it is pure code generation. Understanding this pipeline prevents the common mistake of editing generated files by hand.
AWS CDK synthesis flow
You define a Stack subclass, instantiate constructs, then run:
npm install -g aws-cdk
cdk init app --language typescript
cdk synth
cdk deploy MyStack cdk synth writes CloudFormation templates to cdk.out/. CloudFormation creates, updates, or deletes stacks on deploy. Rollbacks follow CloudFormation's stack policy. Nested stacks and cross-stack references are first-class. I have used this pattern alongside GitLab CI where the pipeline runs cdk synth, uploads artifacts, and deploys from a runner with IAM credentials scoped by least-privilege IAM roles.
CDKTF synthesis flow
CDKTF projects use cdktf.json for configuration. Initialization looks like this:
npm install -g cdktf-cli
mkdir my-infra && cd my-infra
cdktf init --template=typescript --local
cdktf get
cdktf synth
cdktf deploy cdktf get downloads provider bindings from the Terraform Registry into .gen/. cdktf synth writes Terraform JSON under cdktf.out/stacks/<stack-name>/. Deploy invokes terraform apply with your configured backend. You can inspect the generated HCL, commit it, or gitignore it — teams disagree here, but the Terraform plan is always the contract ops reviews.
On sister sites I maintain with Deployer 7 and GitLab CI on shared EC2, application deploy and infra deploy stay separate jobs. CDKTF fits that split when Terraform state already lives in S3 with DynamoDB locking. AWS CDK fits when the same AWS org uses Control Tower and CloudFormation stack sets for guardrails. Both approaches work; mixing them in one repo without clear boundaries creates confusion.
When should you choose AWS CDK over CDKTF?
Pick AWS CDK when your scope is AWS-only and you want opinionated abstractions. The aws-ecs-patterns.ApplicationLoadBalancedFargateService construct wires an ALB, Fargate service, security groups, and IAM in one class. Replicating that in raw Terraform or CDKTF takes dozens of resources and careful ordering.
AWS CDK also wins when your org mandates CloudFormation. Some enterprise AWS accounts block direct API provisioning outside CFN. Stack policies, change sets, and Service Catalog integrations assume CloudFormation as the source of truth. CDKTF cannot participate in those workflows without an awkward export/import layer.
Additional AWS CDK advantages:
- Aspects and tagging: Apply tags or compliance rules across all constructs in a stack tree.
- CDK Pipelines: Self-mutating deployment pipelines native to CodePipeline.
- L3 patterns: API Gateway + Lambda, CloudFront + S3 static sites, and similar bundles ship maintained.
- CloudFormation modules: Wrap existing CFN modules as constructs without rewriting them.
For deploying Laravel on AWS EC2 with RDS, I often start with CDK when the client has no Terraform history. The first VPC stack deploys in an afternoon. You still handle PHP-FPM and Apache outside IaC — that is application config, not infra — but the network layer is repeatable.
Choose CDKTF instead when any of these apply:
- You already manage Terraform state and modules across staging and production.
- You need GCP, Azure, Cloudflare, or Datadog resources in the same codebase.
- Your platform team publishes internal Terraform modules you must consume.
- You want
terraform planin every pull request with a familiar diff format. - You are standardizing on Terraform Cloud or Spacelift for policy-as-code.
How do you get started with CDKTF in a real project?
Assume a TypeScript monorepo with an app stack and a shared networking stack. CDKTF supports multiple stacks in one project, each with its own Terraform state.
Project layout
my-infra/
├── cdktf.json
├── main.ts
├── constructs/
│ └── laravel-ec2.ts
├── .gen/ # generated provider bindings
└── cdktf.out/ # synthesized Terraform (gitignored) Minimal VPC stack (TypeScript)
import { Construct } from "constructs";
import { TerraformStack, TerraformOutput } from "cdktf";
import { AwsProvider } from "@cdktf/provider-aws/lib/provider";
import { Vpc } from "@cdktf/provider-aws/lib/vpc";
export class NetworkStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
new AwsProvider(this, "aws", { region: "ap-south-1" });
const vpc = new Vpc(this, "main", {
cidrBlock: "10.0.0.0/16",
tags: { Name: "laravel-prod-vpc" },
});
new TerraformOutput(this, "vpc_id", { value: vpc.id });
}
} Configure a remote backend in cdktf.json or via generated backend block. For AWS, the standard pattern mirrors plain Terraform: S3 bucket for state, DynamoDB table for locks, encryption enabled. This is the same backend I recommend in CloudFormation and Terraform fundamentals discussions — only the deploy engine changes.
CI integration
A GitLab CI job might run:
cdktf synth
cdktf diff ProductionStack
cdktf deploy ProductionStack --auto-approve Store AWS credentials in CI variables. Never commit .tfstate. Use JSON formatter tools locally to inspect synthesized output before the first deploy. A malformed provider block is easier to catch in review than after a partial apply.
Compare this with AWS CDK bootstrap:
cdk bootstrap aws://ACCOUNT_ID/ap-south-1
cdk deploy --all --require-approval never CDK bootstrap creates an S3 bucket and IAM roles for asset publishing — Lambda layers, Docker images, and similar. CDKTF has no equivalent bootstrap because Terraform does not ship assets through the same pipeline. If you deploy Lambda from CDKTF, you build and push containers in a separate CI step, then reference the ECR URI in code.
What are the day-two operational trade-offs?
Choosing between AWS CDK vs CDKTF affects maintenance more than the first deploy. These operational differences show up six months in.
State and drift
CloudFormation tracks desired state per stack. A failed update rolls back automatically unless you disable rollback. Terraform via CDKTF requires explicit plan review. Drift from manual console changes appears in terraform plan as unexpected diffs. CloudFormation drift detection runs separately. Neither tool prevents console cowboys — IAM policies and code review do.
Provider and construct updates
AWS CDK releases align with CloudFormation resource coverage. Breaking changes happen on major versions; pin aws-cdk-lib in package.json. CDKTF provider bindings regenerate with cdktf get when you bump provider versions in cdktf.json. A Terraform AWS provider major bump can rename attributes — your TypeScript compiles, but plan may want to recreate resources.
Cost and team overhead
Both tools are free open source. Costs are AWS resources plus engineer time. For Nepal startups budgeting in NPR, a wrong IaC choice costs rework, not licence fees. I have seen teams spend Rs 200,000–400,000 (~USD 1,500–3,000) re-platforming after picking CDK for a multi-cloud roadmap they did not yet need. Start narrow. Expand when requirements force it. Read budgeting AWS and Azure in NPR for startups before over-engineering infra tooling.
Hybrid and migration paths
You can run AWS CDK for application stacks and plain Terraform for shared networking — many orgs do. Avoid managing the same VPC in both. If you must migrate, import resources into one tool and delete the other stack's references. CloudFormation-based IaC on AWS and CDKTF-generated Terraform cannot share state for a single resource.
For PHP workloads comparing clouds, see GCP vs AWS vs Azure for PHP workloads. If AWS wins, your IaC choice still depends on whether Terraform is already in the room. AWS vs DigitalOcean vs Hetzner for Laravel hosting covers simpler paths when full IaC is overkill.
Which tool fits multi-cloud and team skill sets?
Language choice is nearly identical — TypeScript dominates new projects in 2026. Python suits data and ML teams. Java and C# appear in enterprise shops. Go is less common but supported. The split is not "my devs know TypeScript therefore CDK." Both use TypeScript equally well.
Skill fit follows ops history:
- Platform engineers with Terraform modules: CDKTF adds typed constructs without abandoning registry modules.
- AWS-centric DevOps with CFN experience: AWS CDK is the natural upgrade from YAML templates.
- Full-stack Laravel teams: Often lack dedicated infra staff. AWS CDK L2 constructs reduce foot-guns on security groups and IAM.
- Agencies shipping legal-tech and booking portals: Repeatable VPC + RDS patterns matter. I reuse CDK stacks across Court Marriage In Nepal–style deployments and similar Laravel properties on shared EC2 infrastructure.
External references worth bookmarking: the AWS CDK v2 Developer Guide, the HashiCorp CDKTF documentation, and the Terraform language specification for understanding generated output.
Neither tool replaces Linux system administration for OS patches, PHP-FPM tuning, or log rotation. IaC provisions resources. Configuration management — Ansible, SSM, or shell scripts — still configures what runs inside EC2. Treat them as complementary layers in enterprise application development engagements.
Verdict for 2026
Choose AWS CDK if you deploy exclusively to AWS, want high-level constructs, and prefer CloudFormation stack semantics with automatic rollback. It is the fastest path from zero to a production VPC, RDS, and ALB for a Laravel app.
Choose CDKTF if Terraform is already your org standard, you need multi-cloud or third-party providers, or you must consume existing Terraform modules without rewriting them in CloudFormation.
Avoid both for a single EC2 and manual LAMP stack on a Rs 1,500/month (~USD 11) VPS. IaC pays off when environments multiply and drift becomes expensive. For larger builds, custom software development projects benefit from codified infra from day one.
Key Takeaways
- AWS CDK outputs CloudFormation for AWS-only deployments; CDKTF outputs Terraform for any supported provider.
- Pick AWS CDK for L2/L3 constructs, CFN stack rollback, and AWS-native org policies.
- Pick CDKTF when Terraform state, modules, and multi-cloud consistency already exist.
- Never manage the same resource in both tools — dual ownership causes destroy/recreate incidents.
- Run
cdk synthorcdktf synthin CI and review generated output before apply. - IaC provisions cloud resources; OS and application config remain separate concerns handled by deploy scripts or configuration management.
People Also Ask
Can CDKTF replace AWS CDK for AWS-only projects?
Technically yes — the AWS provider covers the same resources. Practically, you lose AWS-maintained L2 constructs and CDK Pipelines integration. Teams without Terraform history usually ship slower on CDKTF for pure AWS work because they write more boilerplate for IAM and networking.
Does AWS CDK support Terraform as a backend?
No. AWS CDK synthesizes only to CloudFormation. HashiCorp built CDKTF as the Terraform-targeting sibling. There is no supported path to emit Terraform from aws-cdk-lib. Choose one engine per project.
Is CDKTF production-ready in 2026?
Yes. CDKTF reached general availability and is maintained by HashiCorp alongside Terraform. Production readiness depends more on your team's Terraform maturity and remote state setup than on CDKTF itself. Pin provider versions and run plan in CI before every apply.
Which has better testing support?
AWS CDK ships assertions for unit-testing synthesized CloudFormation templates. CDKTF supports snapshot testing of synthesized Terraform JSON and integration tests via terraform plan in CI. Both allow testing infra logic before deploy. CDK's template assertions are more ergonomic for AWS-specific edge cases.
Pick the right IaC engine before your stack grows
The AWS CDK vs CDKTF choice is really CloudFormation versus Terraform under typed code. AWS-only teams with no Terraform baggage should start with AWS CDK. Teams already running Terraform modules across accounts should adopt CDKTF and keep their state backends. Either beats hand-written YAML once you have more than one environment. Need help designing AWS infra for a Laravel or legal-tech platform? Contact us or explore recent Laravel + AWS portfolio work and ongoing support services for production deployments.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

