AWS CDK Starter Kit

Local Development

Daily commands for building, testing, formatting, and deploying CDK infrastructure from your workstation.

Overview

This guide covers the essential commands and workflows for developing CDK infrastructure on your local machine before pushing to CI/CD. Everything runs through Projen-generated pnpm scripts, so the same commands work locally and in your pipelines.

Daily development cycle

The typical workflow for making infrastructure changes:

Mermaid diagram loading.
# 1. Create a feature branch
git checkout -b feature/add-lambda

# 2. Make changes to your stacks in src/stacks/
# Edit stack definitions, constructs, etc.

# 3. Build and lint
pnpm run build

# 4. Synthesize CloudFormation templates
pnpm run test:synth

# 5. Preview changes
pnpm run test:diff

# 6. Deploy changes (if diff looks good)
pnpm run test:deploy:all

# 7. Test your infrastructure
# Run manual tests or automated tests

# 8. Commit and push
git add .
git commit -m "feat: add Lambda function for processing"
git push origin feature/add-lambda

# 9. Open pull request on GitHub

Essential pnpm commands

The starter kit provides convenient pnpm scripts for all operations. Run npx projen --help to see the full list of generated tasks.

Build and test

pnpm run build       # compile, synth, test, lint in one go (used by CI)
pnpm test            # jest with coverage enabled

Need a faster feedback loop? Use watch mode:

pnpm run watch        # rebuild and re-test on file changes
pnpm run test:watch   # jest watch mode with the repo's config

Code quality

pnpm run biome              # check mode (validates formatting and linting)
pnpm run biome -- --apply   # fix mode (note the extra --)

Example output:

$ pnpm run biome
Checked 42 files in 0.12s. No fixes needed.

Biome rules are enforced in CI. Run them locally before you commit to avoid failed pipelines.

Environment operations

pnpm run test:synth                    # synthesize all stacks for the test account
pnpm run test:diff                     # diff all stacks against deployed state
pnpm run test:diff:stack StarterStack  # diff a specific stack
pnpm run test:deploy:all               # deploy all stacks
pnpm run test:deploy:stack FooStack    # deploy a specific stack
pnpm run test:destroy:stack FooStack   # destroy a specific stack
pnpm run test:ls                       # list all stacks for the environment

Important: Replace test with any other environment name you configure (see Configuration > Environments).

Every command sets CDK_DEFAULT_ACCOUNT, CDK_DEFAULT_REGION, ENVIRONMENT, and (for branch tasks) GIT_BRANCH_REF so names and tags stay consistent.

Branch previews

For isolated testing per feature branch:

pnpm run test:branch:synth              # synthesize with branch suffix
pnpm run test:branch:diff:stack Name    # diff branch-specific stack
pnpm run test:branch:deploy:all         # deploy all branch stacks
pnpm run test:branch:destroy:all        # cleanup when done

See Branch-based Development for the full preview workflow.

Cleanup

Always destroy branch stacks when you finish to avoid unnecessary costs:

pnpm run test:branch:destroy:all

Working with CDK directly

While pnpm scripts are convenient, you can also use CDK commands directly for more control.

Synthesize templates

npx cdk synth
npx cdk synth StarterStack    # specific stack only

Generates CloudFormation templates in cdk.out/. Review these to understand exactly what CDK will deploy.

Preview changes

npx cdk diff
npx cdk diff StarterStack     # specific stack only

Shows what CDK will create, modify, or destroy. Always review before deploying.

Deploy stacks

npx cdk deploy
npx cdk deploy StarterStack   # specific stack only
npx cdk deploy --all          # all stacks

CDK prompts for confirmation on IAM and security changes. Review carefully and type y to proceed.

Deploy with auto-approve (use with caution):

npx cdk deploy --require-approval never

Watch mode for rapid iteration

When supported by your stacks, CDK watch gives rapid redeploys:

npx cdk watch

This uses your current AWS credentials and monitors file changes. Deployments are scoped by the environment variables injected into the process. Run pnpm run test:synth once to set env vars in your shell session.

List stacks

npx cdk ls

Shows all stacks defined in your CDK app.

Destroy resources

npx cdk destroy
npx cdk destroy StarterStack  # specific stack only

Destroys all resources managed by the stack. CDK prompts for confirmation.

View outputs

After deployment, stack outputs appear in the terminal. You can also query them:

aws cloudformation describe-stacks \
  --stack-name StarterStack \
  --query 'Stacks[0].Outputs'

Code quality checks

Biome

Run Biome for formatting and linting validation:

# From repository root
pnpm run biome

# Or fix issues automatically
pnpm run biome -- --apply

Common issues Biome catches:

  • Formatting inconsistencies
  • Unused imports and variables
  • TypeScript best practice violations
  • Consistent code style across the project

Example output:

src/stacks/starter-stack.ts:15:1: lint/style/useConst: Use 'const' instead of 'let'.
src/main.ts:8:10: lint/correctness/noUnusedImports: Remove unused import 'Duration'.

TypeScript compilation

TypeScript errors are caught during build:

pnpm run build

This runs the full compilation and will fail on type errors. Fix all TypeScript issues before committing.

Working with multiple AWS accounts

Mermaid diagram loading.Local Development Target Environments

Using AWS CLI profiles

Configure profiles in ~/.aws/config:

[profile test-account]
sso_start_url = https://my-org.awsapps.com/start
sso_region = us-east-1
sso_account_id = 123456789012
sso_role_name = AdministratorAccess
region = us-east-1

[profile production-account]
sso_start_url = https://my-org.awsapps.com/start
sso_region = us-east-1
sso_account_id = 210987654321
sso_role_name = AdministratorAccess
region = us-east-1

Switch profiles:

export AWS_PROFILE=test-account
pnpm run test:deploy:all

export AWS_PROFILE=production-account
pnpm run production:deploy:all

Using Granted

Granted simplifies multi-account access:

# Install via Homebrew
brew install common-fate/granted/granted

# Configure SSO
granted sso populate

# Assume role
assume test-account

# Deploy to test
pnpm run test:deploy:all

# Switch to production
assume production-account
pnpm run production:deploy:all

Learn more: Setting up the AWS CLI with AWS SSO

Testing infrastructure

Manual testing

After applying changes, manually verify resources:

# Example: Verify Lambda function
aws lambda get-function --function-name my-function

# Example: Invoke Lambda
aws lambda invoke \
  --function-name my-function \
  --payload '{"key": "value"}' \
  response.json

# Example: Check S3 bucket
aws s3 ls s3://my-bucket-name

# Example: Test IAM role
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/MyRole \
  --role-session-name test

Unit tests with Jest

The starter kit includes Jest for testing constructs:

pnpm test                 # run all tests
pnpm run test:watch       # watch mode for TDD
pnpm test -- --coverage   # generate coverage report

Write tests in test/ directory. CDK provides snapshot testing for construct output validation.

Keep configuration in sync

Any time you edit .projenrc.ts, regenerate the project:

npx projen

Review the resulting git diff before committing. Generated files should never be hand-edited. Tweak .projenrc.ts, rerun Projen, and let the automation update tasks, workflows, and config.

Best practices

Before making changes

  • Pull latest from main
  • Review existing stack definitions
  • Check for similar patterns in other stacks
  • Plan resource naming conventions

During development

  • Make small, incremental changes
  • Run pnpm run test:diff frequently
  • Format code regularly (pnpm run biome -- --apply)
  • Add descriptive construct IDs
  • Tag resources appropriately

Before committing

  • Run full build: pnpm run build
  • Review diff output carefully
  • Check for sensitive data in code (no hardcoded secrets)
  • Update tests if needed
  • Write clear commit messages

After deploying

  • Verify resources in AWS Console
  • Test functionality manually
  • Document any manual steps required
  • Update stack outputs if needed

Next steps