AWS CDK Starter Kit

Stacks

Foundation and application stacks provided by the AWS CDK Starter Kit with generated pnpm scripts.

Overview

The starter kit includes two stacks: FoundationStack for OIDC and tooling setup, and StarterStack for your application resources. Projen generates pnpm scripts for each environment.

Learn how to create AWS CDK stacks before exploring these patterns.

Mermaid diagram loading.Starter Kit Stacks Generated Scripts

FoundationStack

Source: src/stacks/foundation-stack.ts

Sets up GitHub OpenID Connect (OIDC) and an IAM role for GitHub Actions deployments through the GitHubActionsOidcConstruct. Also adds a CloudFormation Toolkit cleaner to remove old CDK assets.

Constructor

new FoundationStack(scope: Construct, id: string, props: FoundationStackProps)
ParameterTypeDescription
scopeConstructParent app scope
idstringStack identifier
propsFoundationStackPropsStack configuration

FoundationStackProps

PropertyTypeRequiredDescription
environmentstringYesEnvironment label for the OIDC subject (test, production, etc.)
githubActionsOidcFoundationStackGitHubActionsOidcPropsNoOptional OIDC role settings passed to GitHubActionsOidcConstruct (additionalRepositories, maxSessionDuration, roleName). The stack always scopes the trust policy to environment.

Resources created

ResourceTypeDescription
OIDC Provideriam.OpenIdConnectProviderFor token.actions.githubusercontent.com with client ID sts.amazonaws.com
IAM Roleiam.RoleNamed GitHubActionsServiceRole (or custom via GITHUB_DEPLOY_ROLE). Trusts GitHub OIDC with subject repo:<owner>/<repo>:environment:<ENV>
Toolkit CleanerToolkitCleanerFrom cloudstructs package. Automatically cleans up old CDK assets

Deployment behavior

  • Excluded from branch deployments - guarded by if (!process.env.GIT_BRANCH_REF) in src/main.ts
  • Deploy once per account/region - enables OIDC deployments for that environment
  • Creates GitHub environment link - IAM role subject matches GitHub environment name

Usage

# Deploy Foundation + Starter stacks for test environment
pnpm run test:deploy:all

# Deploy only FoundationStack
pnpm run test:deploy:stack FoundationStack

StarterStack

Source: src/stacks/starter-stack.ts

Your application entry stack. Add constructs and resources here. Includes a commented example using NetworkConstruct for a secure VPC.

Constructor

new StarterStack(scope: Construct, id: string, props?: StarterStackProps)
ParameterTypeDescription
scopeConstructParent app scope
idstringStack identifier
propsStarterStackPropsOptional stack configuration

StarterStackProps

PropertyTypeRequiredDescription
environmentstringNoUsed for tagging and resource naming

Usage

# Synthesize and diff only StarterStack
pnpm run test:synth
pnpm run test:diff:stack StarterStack

# Deploy only StarterStack
pnpm run test:deploy:stack StarterStack

# Branch deployment
pnpm run test:branch:deploy:stack StarterStack

Adding resources

// 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, 'DataBucket', {
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      encryption: s3.BucketEncryption.S3_MANAGED,
    });
  }
}

Generated pnpm scripts

Projen generates scripts for each environment defined in .projenrc.ts. The examples below assume test (with branch deploys enabled) and production (branch deploys disabled).

Test environment (regular)

ScriptDescription
pnpm run test:synthSynthesize all stacks
pnpm run test:lsList all stacks
pnpm run test:deploy:allDeploy all stacks
pnpm run test:deploy:stack <StackName>Deploy specific stack
pnpm run test:destroy:allDestroy all stacks
pnpm run test:destroy:stack <StackName>Destroy specific stack
pnpm run test:diff:allShow diff for all stacks
pnpm run test:diff:stack <StackName>Show diff for specific stack

Test environment (branch)

ScriptDescription
pnpm run test:branch:synthSynthesize all branch stacks
pnpm run test:branch:lsList all branch stacks
pnpm run test:branch:deploy:allDeploy all branch stacks
pnpm run test:branch:deploy:stack <StackName>Deploy specific branch stack
pnpm run test:branch:destroy:allDestroy all branch stacks
pnpm run test:branch:destroy:stack <StackName>Destroy specific branch stack
pnpm run test:branch:diff:allShow diff for all branch stacks
pnpm run test:branch:diff:stack <StackName>Show diff for specific branch stack

Production environment

ScriptDescription
pnpm run production:synthSynthesize all stacks
pnpm run production:lsList all stacks
pnpm run production:deploy:allDeploy all stacks
pnpm run production:deploy:stack <StackName>Deploy specific stack
pnpm run production:destroy:allDestroy all stacks
pnpm run production:destroy:stack <StackName>Destroy specific stack
pnpm run production:diff:allShow diff for all stacks
pnpm run production:diff:stack <StackName>Show diff for specific stack

Script behavior

  • :all scripts operate on all stacks in the app
  • :stack scripts accept stack names as arguments
  • Branch tasks automatically inject GIT_BRANCH_REF from current git branch
  • FoundationStack is excluded from branch deploys by design

Adding a new stack

  1. Create the stack file:
// 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
  }
}
  1. Export from index:
// src/stacks/index.ts
export { FoundationStack } from './foundation-stack';
export { StarterStack } from './starter-stack';
export { AppStack } from './app-stack';
  1. Instantiate in src/main.ts:
import { AppStack } from './stacks';

new AppStack(app, createEnvResourceName('AppStack'), { env: awsAccountConfig });
  1. Verify:
pnpm run test:synth
pnpm run test:ls

Next steps