Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

AWS CDK: Infrastructure as Real Code

By Kokil Thapa | Last reviewed: September 2026

AWS CDK: Infrastructure as Real Code turns CloudFormation into something you can write in TypeScript, Python, Java, C#, or Go. You model VPCs, databases, queues, and Lambda functions as typed classes. CDK synthesizes a CloudFormation template and deploys it through the same AWS control plane Terraform and raw YAML use. If you already ship Laravel on AWS EC2 with RDS, CDK gives you a versioned, reviewable path from laptop to production without hand-clicking the console.

What is AWS CDK and how is it different from CloudFormation?

CloudFormation describes infrastructure in JSON or YAML. It works, but large templates become hard to refactor. Loops, shared modules, and unit tests feel bolted on. AWS CDK sits on top of CloudFormation and adds a software development layer.

You write an app containing one or more stacks. Each stack holds constructs — reusable building blocks for S3 buckets, RDS instances, or entire web tiers. When you run synthesis, CDK emits a CloudFormation template AWS executes. Nothing bypasses CloudFormation; CDK is a compiler, not a parallel provisioner.

AWS CDK: Infrastructure as Real Code LayersCDK Appentry pointStackdeploy unitConstructL1 L2 L3AWSresourcescdk synth produces CloudFormation JSON/YAMLcdk deploy runs ChangeSet against AWS APIBenefits: types, reuse, tests, IDE autocompleteSame rollback and drift semantics as native CFN
AWS CDK compiles typed constructs into CloudFormation templates AWS executes — infrastructure stays real code end to end.

Construct levels you will actually use

CDK ships three construct tiers. Knowing them saves hours of confusion during your first stack.

  • L1 (Cfn*) — one-to-one CloudFormation resources. Use when a new AWS feature lands before higher-level constructs exist.
  • L2 — sensible defaults, helper methods, and grant APIs. Most day-to-day work lives here.
  • L3 — opinionated patterns such as ApplicationLoadBalancedFargateService. Fast to ship; harder to customize deeply.

For background on the underlying engine, read the companion piece on AWS CloudFormation as infrastructure as code. CDK does not replace CloudFormation knowledge. It makes large templates manageable.

How do you set up an AWS CDK project from scratch?

CDK requires Node.js 18 or later. For greenfield work in 2026, use Node.js 26 LTS and npm 12. Install the CLI globally, bootstrap your account once, then scaffold a project.

  1. Install the AWS CDK CLI: npm install -g aws-cdk
  2. Verify versions: node --version and cdk --version
  3. Configure AWS credentials via IAM Identity Center or an access key with least privilege
  4. Scaffold: cdk init app --language=typescript
  5. Bootstrap the target account/region: cdk bootstrap aws://ACCOUNT_ID/REGION
  6. Synth locally: cdk synth
  7. Deploy: cdk deploy

Bootstrap creates an S3 staging bucket and IAM roles CDK needs for asset uploads. Skip it once per account/region pair and deployments fail with opaque errors. I've seen teams burn an afternoon on that single missed step.

Minimal TypeScript stack

Below is a trimmed stack that provisions a private S3 bucket with encryption and blocked public access. Paste it into lib/my-stack.ts after init.

import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';

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

    new s3.Bucket(this, 'AppAssets', {
      encryption: s3.BucketEncryption.S3_MANAGED,
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      enforceSSL: true,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
    });
  }
}

Run cdk diff before every deploy. The diff output is your pre-flight checklist. Treat it like a pull request for infrastructure.

CDK Synth and Deploy PipelineSourceTypeScriptcdk synthtemplatecdk diffreviewcdk deployChangeSetLiveCI gate: synth + diff + cdk-nag policy checksMerge only when diff matches approved changeAssets uploaded tobootstrap S3 bucketCloudFormation tracksstack state and rollback
Every AWS CDK deploy path runs synth, human or automated diff review, then CloudFormation ChangeSet execution.

Official setup steps live in the AWS CDK Getting Started guide. Pin aws-cdk-lib in package.json so CI and laptops synthesize identical templates.

How do you model a production Laravel stack with AWS CDK constructs?

On client projects I often pair Laravel 12 or 13 with a classic three-tier layout: ALB, EC2 Auto Scaling, RDS MySQL 8.4 or PostgreSQL 18, ElastiCache Redis 8.10, and Secrets Manager for credentials. CDK expresses that layout as one stack or a small set of nested stacks.

Split concerns early. A networking stack exports VPC and subnet IDs. An application stack imports them and attaches compute. A data stack owns RDS and Redis. Smaller blast radius beats one monolithic template when you iterate weekly.

Example: EC2 web tier with RDS

import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import * as autoscaling from 'aws-cdk-lib/aws-autoscaling';

const vpc = new ec2.Vpc(this, 'AppVpc', { maxAzs: 2 });

const db = new rds.DatabaseInstance(this, 'AppDb', {
  engine: rds.DatabaseInstanceEngine.mysql({
    version: rds.MysqlEngineVersion.VER_8_4,
  }),
  vpc,
  credentials: rds.Credentials.fromGeneratedSecret('laravel'),
  multiAz: true,
  allocatedStorage: 50,
});

const asg = new autoscaling.AutoScalingGroup(this, 'WebAsg', {
  vpc,
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T3,
    ec2.InstanceSize.MEDIUM
  ),
  machineImage: ec2.MachineImage.latestAmazonLinux2023(),
  minCapacity: 2,
  maxCapacity: 6,
});

const alb = new elbv2.ApplicationLoadBalancer(this, 'Alb', { vpc, internetFacing: true });
const listener = alb.addListener('Http', { port: 80, open: true });
listener.addTargets('Web', { port: 80, targets: [asg] });

User data scripts install PHP 8.3 or 8.4, Nginx, and pull your Deployer release. For Lambda-based Laravel, swap the ASG for Laravel Vapor on AWS Lambda constructs or custom Lambda layers. The CDK pattern stays the same: encode the topology once, deploy many times.

Store database passwords in Secrets Manager, not plain environment variables. Wire rotation through CDK and reference secrets from EC2 instance roles. The dedicated guide on managing secrets with AWS Secrets Manager covers rotation details CDK can automate.

Sister legal-tech sites I maintain share a GitLab CI plus Deployer pipeline on EC2. CDK would replace hand-maintained security groups and RDS parameter groups with reviewed code. That is the practical win: fewer console edits, more audit trail.

AWS CDK vs Terraform vs Pulumi: which fits your team?

All three are infrastructure as code. CDK is AWS-native and compiles to CloudFormation. Terraform uses its own state file and HCL. Pulumi, like CDK, uses real languages but targets many clouds with one engine.

CriterionAWS CDKTerraformPulumi
Primary targetAWS (best support)Multi-cloudMulti-cloud
LanguageTypeScript, Python, Java, C#, GoHCL (+ CDKTF optional)TypeScript, Python, Go, .NET
State modelCloudFormation stacksRemote state backendPulumi Service or self-hosted
Day-one AWS feature coverageFast via L1 constructsProvider lag possibleProvider lag possible
Drift detectionCloudFormation drift checksterraform planpulumi preview
Team fitAWS-heavy TypeScript shopsPlatform teams, multi-cloudPolyglot app teams

Pick CDK when AWS is your primary cloud and your engineers already write TypeScript or Python. Pick Terraform when you standardize one tool across AWS, GCP, and on-prem. Pick Pulumi when you want real languages without CloudFormation as the execution layer. Deeper comparisons live in Terraform infrastructure as code and Pulumi in real languages.

IaC Tool Decision MatrixAWS CDKCFN executionAWS-first teamsTerraformHCL + remote statemulti-cloud standardPulumireal languagesown engineAll three belong in Git, run in CI, and demand peer reviewCDK wins: deep AWSconstruct libraryTerraform wins: one toolmany providers
Choose AWS CDK for AWS-native typed stacks; choose Terraform or Pulumi when multi-cloud or non-CFN execution matters more.

Reusable modules mirror Terraform's module pattern. Publish internal constructs as npm packages or Python wheels. The Terraform modules guide mindset transfers directly: one reviewed module, many consuming stacks.

How do you test and deploy AWS CDK stacks in CI/CD?

Treat CDK like application code. Synth on every pull request. Block merges when diffs introduce public S3 buckets or open security groups. Add policy-as-code with cdk-nag or CloudFormation Guard.

GitLab CI example

Many teams I work with already run GitLab CI for Laravel tests. Extend the same pipeline with a CDK job.

cdk-synth:
  image: node:26
  stage: test
  script:
    - npm ci
    - npm run build
    - npx cdk synth --all
  artifacts:
    paths:
      - cdk.out/

cdk-diff:
  stage: review
  script:
    - npx cdk diff --all
  when: manual
  only:
    - main

Pair synth with application quality gates. Infrastructure changes deserve the same scrutiny as PHP code. Read how code coverage gates in CI keep bad merges out; apply the same discipline to cdk diff output.

For GitOps-style flows, commit synthesized templates or use CDK Pipelines for self-mutating deployment pipelines. Compare approaches in GitOps for infrastructure vs application GitOps. CDK Pipelines creates a CodePipeline that redeploys when you push to main.

Automate repetitive AWS API calls with Boto3 scripts where CDK is too heavy — one-off data migrations, for example. CDK owns steady-state topology; scripts own exceptional operations.

Context and environments

Pass context via cdk.json or -c stage=prod flags. Keep prod and staging in separate accounts when possible. AWS Organizations plus CDK environment objects make that explicit.

new MyStack(app, 'ProdStack', {
  env: { account: '111111111111', region: 'ap-south-1' },
});

Nepal-based workloads often land in ap-south-1 (Mumbai) for latency to Kathmandu. Price RDS and data transfer before you commit. A quick sanity check with the Nepal EMI calculator helps founders compare monthly cloud spend against on-prem hosting quotes.

What production mistakes break AWS CDK stacks?

CDK removes YAML pain but not operational discipline. These failures show up repeatedly on real deployments.

  • Skipping bootstrap — asset deployments fail until cdk bootstrap runs in the target account/region.
  • Hard-coded physical names — S3 bucket names must be globally unique. Let CDK generate names unless you have a strong reason.
  • Destroying stateful resources — default removal policies delete data. Set RemovalPolicy.RETAIN on RDS and S3 buckets you cannot rebuild from scratch.
  • Monolithic stacks — one stack with 200 resources hits CloudFormation limits and slow updates. Split by lifecycle.
  • Pin drift — upgrading aws-cdk-lib without reading release notes changes logical IDs and replaces resources. Always run cdk diff after upgrades.
  • IAM wildcardsgrantReadWrite helpers are convenient but often too broad. Tighten policies for production.
Laravel Production Stack on AWS CDKApplication Load BalancerEC2 Auto ScalingLaravel + PHP-FPMEC2 Auto ScalingNginx + queue workerRDS MySQLMulti-AZElastiCache Redissessions + cacheSecrets ManagerDB credentialsOne CDK stack per environment — separate AWS accounts ideal
A typical Laravel AWS CDK stack wires load-balanced compute to RDS, Redis, and Secrets Manager as typed constructs.

Immutable AMIs complement CDK nicely. Build golden images with Packer, reference them in your ASG construct, and stop SSH-ing into servers to patch PHP. See immutable infrastructure with Packer for the full workflow.

Governance across accounts benefits from guardrails. Tag enforcement, allowed instance types, and encryption defaults belong in policy-as-code. The overview on multi-cloud governance and policy as code applies even when you stay AWS-only.

When choosing hosting economics, weigh CDK-managed EC2 against lighter options. The comparison of AWS vs DigitalOcean vs Hetzner for Laravel helps small teams set realistic budgets — often Rs 15,000–40,000/month (~USD 110–295) for modest production tiers.

For enterprise engagements that need audited infrastructure delivery, see enterprise application development in Nepal. Ongoing stack maintenance fits support and maintenance services and Linux system administration.

Proof of shipped booking and portal workloads lives in the portfolio — for example Adventure Third Pole Trek and Mijar Law Associates. CDK would not change the Laravel code; it would codify the AWS footprint those apps run on.

Validate synthesized JSON with the JSON formatter during code review. Small syntax errors in generated templates are easier to spot when the payload is pretty-printed.

CloudFormation service limits still apply underneath CDK. The CloudFormation quotas documentation lists stack resource caps and template size limits you hit on large platforms.

Key Takeaways

  • AWS CDK: Infrastructure as Real Code compiles TypeScript or Python into CloudFormation — you keep AWS-native rollback and drift tooling.
  • Run cdk bootstrap once per account/region, then cdk diff before every deploy to catch unintended replacements.
  • Split stacks by lifecycle: network, compute, and data tiers update at different speeds.
  • Pair CDK with CI synth jobs, cdk-nag policy checks, and Secrets Manager for credentials — never plain-text prod secrets.
  • Choose CDK for AWS-heavy teams; reach for Terraform or Pulumi when multi-cloud or non-CFN execution is the priority.
  • Set RemovalPolicy.RETAIN on RDS and S3 unless you have tested backups and a written destroy procedure.

People Also Ask

Is AWS CDK free to use?

The CDK CLI and libraries are open source and free. You pay only for AWS resources your stacks create — EC2, RDS, data transfer, and the rest. Bootstrap resources (S3, ECR, IAM) carry normal AWS pricing, usually pennies at small scale.

Can AWS CDK replace Terraform entirely?

Only if AWS is your sole cloud and CloudFormation's execution model fits your operations team. Terraform still wins when one toolchain must manage AWS, GCP, Azure, and SaaS providers together. Many organizations use CDK for AWS application stacks and Terraform for shared networking.

Which language should I pick for AWS CDK?

TypeScript is the best-documented path and matches most CDK examples. Python fits data and ML teams. Java and C# suit enterprises with existing JVM or .NET standards. Pick the language your reviewers already read fluently.

Does AWS CDK work with existing CloudFormation templates?

Yes. Import templates with CfnInclude or migrate resource by resource into L2 constructs. Incremental migration beats a big-bang rewrite on production systems that already run steady traffic.

Ship infrastructure the same way you ship Laravel code

AWS CDK: Infrastructure as Real Code closes the gap between application repos and the AWS console. You get typed constructs, repeatable synth output, and CloudFormation's battle-tested deployment engine. Start with one stack — a VPC, an ALB, an RDS instance — and expand through internal construct libraries as patterns stabilize.

If you want help modeling production Laravel stacks, CI pipelines, or a migration from hand-built EC2 to codified AWS, contact us to discuss scope. Solid infrastructure code pays back every deploy night you do not spend fixing security groups by hand.

Frequently Asked Questions

AWS CDK lets you define AWS infrastructure in TypeScript, Python, Java, C#, or Go using typed constructs for VPCs, databases, queues, and Lambda. When you run cdk synth, CDK compiles your app into a CloudFormation template that AWS executes on deploy. Nothing bypasses CloudFormation; CDK is a compiler sitting on top of the same control plane Terraform and raw YAML use. Large YAML templates become hard to refactor, while CDK gives you loops, shared modules, and unit tests as normal software patterns.

Yes. The CDK CLI and libraries are open source and free. You pay only for the AWS resources your stacks create, such as EC2, RDS, and data transfer. Bootstrap resources like the S3 staging bucket, ECR, and IAM roles carry normal AWS pricing, usually pennies at small scale.

Install Node.js 18 or later; for greenfield work in 2026, use Node.js 26 LTS and npm 12. Run npm install -g aws-cdk, configure AWS credentials via IAM Identity Center or a least-privilege access key, then scaffold with cdk init app --language=typescript. Bootstrap the target account and region once using cdk bootstrap aws://ACCOUNT_ID/REGION, verify with cdk synth, and deploy with cdk deploy. Pin aws-cdk-lib in package.json so CI and local laptops synthesize identical templates. Skipping bootstrap is the most common first-day failure I have seen teams hit.

CDK ships three construct tiers. L1 Cfn* constructs map one-to-one to CloudFormation resources and are useful when a new AWS feature lands before higher-level constructs exist. L2 constructs provide sensible defaults, helper methods, and grant APIs, and most day-to-day work lives here. L3 constructs ship opinionated patterns such as ApplicationLoadBalancedFargateService, which are fast to ship but harder to customize deeply. Knowing the tier saves hours of confusion during your first stack and tells you when to drop down to raw CloudFormation resources.

Bootstrap creates an S3 staging bucket and IAM roles CDK needs for asset uploads in a specific AWS account and region. You run it once per account and region pair before your first deployment that includes assets. Without bootstrap, deployments fail with opaque errors that can waste an afternoon of debugging. After bootstrap, cdk deploy can upload Lambda code, Docker images, and other assets through the staging infrastructure CloudFormation expects.

On client projects I often pair Laravel 12 or 13 with a three-tier layout: Application Load Balancer, EC2 Auto Scaling, RDS MySQL 8.4 or PostgreSQL 18, ElastiCache Redis 8.10, and Secrets Manager for credentials. CDK expresses VPC, database, ASG, and ALB as typed constructs in one stack or nested stacks. User data scripts install PHP 8.3 or 8.4, Nginx, and pull a Deployer release. Store database passwords in Secrets Manager, not plain environment variables, and reference secrets from EC2 instance roles. For Lambda-based Laravel, swap the ASG for Vapor or custom Lambda layers while keeping the same CDK topology pattern.

All three are infrastructure as code, but they differ in execution and team fit. CDK is AWS-native, compiles to CloudFormation stacks, and suits TypeScript or Python teams already committed to AWS. Terraform uses HCL and remote state, winning when one toolchain must manage AWS, GCP, Azure, and on-prem together. Pulumi uses real languages like CDK but targets many clouds without CloudFormation as the execution layer. Pick CDK for AWS-heavy typed stacks with fast L1 coverage of new AWS features. Pick Terraform or Pulumi when multi-cloud standardization or non-CloudFormation execution matters more than AWS-native rollback tooling.

Only if AWS is your sole cloud and CloudFormation's stack-based execution model fits your operations team. Terraform still wins when one toolchain must manage AWS, GCP, Azure, and SaaS providers together. Many organizations use CDK for AWS application stacks and Terraform for shared networking. CDK does not remove the need to understand CloudFormation behavior underneath.

TypeScript is the best-documented path and matches most official CDK examples, making it the default for new projects. Python fits data and ML teams already standardized on that stack. Java and C# suit enterprises with existing JVM or .NET standards. Go is also supported. Pick the language your reviewers already read fluently, because infrastructure code gets the same pull-request scrutiny as application code. Reusable constructs can be published as npm packages or Python wheels, similar to Terraform module libraries.

Treat CDK like application code. Run cdk synth on every pull request and block merges when diffs introduce public S3 buckets or open security groups. Add policy-as-code with cdk-nag or CloudFormation Guard. In GitLab CI, use a node:26 image, run npm ci, npm run build, then npx cdk synth --all, storing cdk.out as artifacts. Add a manual cdk diff job on main before deploy. Pair synth with the same quality gates you use for Laravel tests. For GitOps-style flows, commit synthesized templates or use CDK Pipelines for self-mutating CodePipeline deployments when you push to main.

cdk diff shows exactly what CloudFormation will create, update, or replace before you execute a changeset. Treat that output like a pull request for infrastructure. On real deployments I always run diff after upgrading aws-cdk-lib, because release notes can change logical IDs and trigger unintended resource replacements. Diff catches open security groups, accidental bucket deletions, and removal-policy surprises that synthesis alone will not block. It is the pre-flight checklist every AWS CDK deploy path should include before CloudFormation ChangeSet execution.

Split concerns early instead of one monolithic template with hundreds of resources. A networking stack exports VPC and subnet IDs. An application stack imports them and attaches compute. A data stack owns RDS and Redis. Smaller blast radius beats one stack when you iterate weekly, and it keeps you under CloudFormation resource and template size limits. Network, compute, and data tiers update at different speeds, so separating stacks matches real operational lifecycles. Use separate AWS accounts for prod and staging when possible, passing explicit env account and region values in stack props.

Skipping bootstrap causes asset deployment failures until cdk bootstrap runs in the target account and region. Hard-coded physical S3 bucket names fail because names must be globally unique; let CDK generate names unless you have a strong reason. Default removal policies delete stateful data, so set RemovalPolicy.RETAIN on RDS and S3 you cannot rebuild. Monolithic stacks hit CloudFormation limits and slow updates. Upgrading aws-cdk-lib without reading release notes can replace resources via logical ID changes; always diff after upgrades. IAM grantReadWrite helpers are convenient but often too broad for production.

Yes. Import existing templates with CfnInclude or migrate resource by resource into L2 constructs. Incremental migration beats a big-bang rewrite on production systems that already serve steady traffic. CDK still synthesizes CloudFormation underneath, so your existing stacks, drift detection, and rollback behavior remain familiar. This path lets AWS-heavy teams adopt typed constructs without tearing down working infrastructure on day one.

CDK itself is free; cost comes entirely from the AWS resources your stacks provision. For modest production tiers with load-balanced EC2, RDS, and Redis, I often see Rs 15,000 to 40,000 per month, roughly USD 110 to 295, depending on instance sizes and data transfer. Nepal-based workloads often land in ap-south-1 Mumbai for latency to Kathmandu, but price RDS and inter-region data transfer before committing. Weigh CDK-managed EC2 against lighter hosting options using your expected traffic and redundancy requirements, not just the IaC tooling choice.

Share this article

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.

Quick Contact Options
Choose how you want to connect me: