Overview
This page provides annotated code examples for common tasks. Copy and adapt these patterns to extend your CDK infrastructure.
Add resources to the starter stack
The quickest way to begin is extending StarterStack in src/stacks/starter-stack.ts:
// src/stacks/starter-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
export class StarterStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
new s3.Bucket(this, 'ArtifactsBucket', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
});
}
}
Tagging, naming, and branch-awareness are already handled in src/main.ts. Resources you add inherit the environment tags configured in the app.
Add a new stack alongside starter stack
Step 1: Create src/stacks/app-stack.ts:
// src/stacks/app-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class AppStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Add resources here
}
}
Step 2: Export from src/stacks/index.ts:
export { AppStack } from './app-stack';
Step 3: Instantiate in src/main.ts:
import { AppStack } from './stacks';
new AppStack(app, createEnvResourceName('AppStack'), { env: awsAccountConfig });
Step 4: Validate:
npm run test:synth
Compose constructs for reuse
Create constructs under src/constructs/ and extend BaseConstruct for environment, account, region, and branch helpers.
// src/constructs/storage-bucket.ts
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
import { BaseConstruct } from './base-construct';
export class StorageBucket extends BaseConstruct {
public readonly bucket: s3.Bucket;
constructor(scope: Construct, id: string, props?: s3.BucketProps) {
super(scope, id);
this.bucket = new s3.Bucket(this, 'Bucket', {
bucketName: this.unique('artifacts'),
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
...props,
});
}
}
Use the construct inside any stack:
import { StorageBucket } from '../constructs';
new StorageBucket(this, 'ArtifactsBucket', { versioned: true });
Use the opinionated VPC
NetworkConstruct provisions a three-tier VPC with environment-specific CIDRs, endpoints, and flow logs:
import { NetworkConstruct } from '../constructs';
const network = new NetworkConstruct(this, 'Network');
// network.vpc is available for ECS clusters, RDS, etc.
Because NetworkConstruct inherits from BaseConstruct, VPC names and the flow-log bucket automatically include environment or branch suffixes.
Add environment-specific configuration
Pass configuration to stacks based on the current environment:
// src/main.ts
const environment = process.env.ENVIRONMENT || 'test';
const config = {
test: { instanceType: 't3.micro', minCapacity: 1 },
production: { instanceType: 't3.large', minCapacity: 3 },
}[environment];
new AppStack(app, createEnvResourceName('AppStack'), {
env: awsAccountConfig,
...config,
});
Use branch-specific stack actions locally
All environment tasks have branch variants for isolated testing:
git checkout -b feature/cost-reduction
npm run test:branch:deploy:stack StarterStack
npm run test:branch:destroy:stack StarterStack
Branch deploy tasks set GIT_BRANCH_REF, so stack names and resource tags include the cleaned branch suffix. See Environments > Ephemeral environments for the full workflow.
Add cross-stack references
Share resources between stacks using construct properties:
// src/stacks/network-stack.ts
export class NetworkStack extends cdk.Stack {
public readonly vpc: ec2.Vpc;
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 3 });
}
}
// src/main.ts
const networkStack = new NetworkStack(app, createEnvResourceName('NetworkStack'), {
env: awsAccountConfig,
});
new AppStack(app, createEnvResourceName('AppStack'), {
env: awsAccountConfig,
vpc: networkStack.vpc,
});
Next steps
- Project Structure - Understand the directory layout
- Constructs reference - Deep dive into BaseConstruct
- Stacks reference - FoundationStack and StarterStack details