homeresume
 
   
🔍

Infrastructure as Code (IaC) with AWS CDK (EC2 Example)

June 11, 2026

Infrastructure as Code (IaC) is a DevOps approach where infrastructure is defined and managed using code instead of manual setup. This makes environments reproducible, version-controlled, and easy to scale.

In this guide, you'll provision an AWS EC2 instance using the AWS Cloud Development Kit (CDK). CDK lets you define infrastructure in TypeScript (or other languages), synthesize CloudFormation templates, and deploy stacks through the CDK CLI.

Requirements

Before starting, install:

  • Node.js version 26
  • AWS CDK CLI (npm i -g aws-cdk)
  • AWS CLI

AWS Credentials Setup

  1. Go to IAM → Security credentials in AWS
  2. Create access keys
  3. Configure locally:
aws configure

This stores credentials in:

  • ~/.aws/credentials
  • ~/.aws/config

CDK requires CloudFormation permissions (and bootstrap-related IAM/S3 access). An IAM user scoped only for Terraform EC2 is often insufficient - attach broader permissions or use a dedicated CDK user.

Project Structure

A simple CDK TypeScript setup:

.
├── bin/
│ └── app.ts
├── lib/
│ └── ec2-stack.ts
├── cdk.json
├── package.json
└── tsconfig.json

Install dependencies:

npm i

App Entry

The CDK app wires stacks together in bin/app.ts:

#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { Ec2Stack } from '../lib/ec2-stack';
const app = new cdk.App();
new Ec2Stack(app, 'Ec2Stack', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION ?? 'eu-north-1',
},
instanceName: app.node.tryGetContext('instanceName') ?? 'MyEC2Name',
});

Set the target account and region once per shell session:

export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
export CDK_DEFAULT_REGION=eu-north-1

On Windows PowerShell:

$env:CDK_DEFAULT_ACCOUNT = aws sts get-caller-identity --query Account --output text
$env:CDK_DEFAULT_REGION = "eu-north-1"

Stack and EC2 Instance

Define the stack in lib/ec2-stack.ts:

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';
export interface Ec2StackProps extends cdk.StackProps {
instanceName?: string;
}
export class Ec2Stack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: Ec2StackProps) {
super(scope, id, props);
const instanceName = props?.instanceName ?? 'MyEC2Name';
const instance = new ec2.Instance(this, 'AppServer', {
vpc: ec2.Vpc.fromLookup(this, 'DefaultVpc', { isDefault: true }),
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T3,
ec2.InstanceSize.MICRO,
),
machineImage: ec2.MachineImage.latestAmazonLinux2023(),
instanceName,
});
new cdk.CfnOutput(this, 'InstanceId', {
value: instance.instanceId,
description: 'EC2 instance ID',
});
new cdk.CfnOutput(this, 'InstancePublicIp', {
value: instance.instancePublicIp,
description: 'Public IP address',
});
}
}

CDK resolves the default VPC during synthesis. Amazon Linux 2023 is selected automatically for the current region.

Configuration

CDK settings live in cdk.json:

{
"app": "npx ts-node --prefer-ts-exts bin/app.ts",
"context": {
"instanceName": "MyEC2Name"
}
}

Change instanceName in context to override the default tag without editing stack code.

CDK Workflow

Bootstrap the environment (once per account/region):

  • cdk bootstrap

Preview the CloudFormation template:

  • cdk synth

Compare deployed stack with local changes:

  • cdk diff

Deploy the stack:

  • cdk deploy

Destroy infrastructure:

  • cdk destroy

Important Notes

  • State management

CDK deploys through CloudFormation. Stack state lives in AWS, not in a local file like Terraform's terraform.tfstate.

  • Bootstrap stack

The first cdk bootstrap creates an S3 bucket and IAM roles CDK uses for deployments. Keep the bootstrap stack in place while you use CDK in that account/region.

  • Idempotency

Running cdk deploy again updates the stack in place when possible instead of recreating resources unnecessarily.

  • Version control

Treat CDK code like application code. Commit cdk.json and lockfiles; do not commit cdk.out/ or node_modules/.

Demo

CDK project files for this post live in the cdk-aws-ec2 folder. Get access via code demos.