This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a .NET library that provides reusable AWS CDK constructs for serverless applications and static websites. The library is designed specifically for LayeredCraft projects and includes:
- Lambda Functions: Comprehensive Lambda construct with integrated OpenTelemetry support, IAM management, and environment configuration
- Static Sites: Complete static website hosting with S3, CloudFront, SSL certificates, Route53 DNS, and optional API proxying
# Build the solution
dotnet build
# Run all tests (preferred method for xUnit v3)
dotnet run --project test/LayeredCraft.Cdk.Constructs.Tests/ --framework net8.0
# Run tests for a specific project
dotnet test test/LayeredCraft.Cdk.Constructs.Tests/
# Run a specific test
dotnet test --filter "Construct_ShouldCreateLambdaFunction"# Restore packages
dotnet restore
# Add a package reference
dotnet add src/LayeredCraft.Cdk.Constructs/ package PackageName
# Add a test package reference
dotnet add test/LayeredCraft.Cdk.Constructs.Tests/ package PackageNameLambdaFunctionConstruct (src/LayeredCraft.Cdk.Constructs/LambdaFunctionConstruct.cs)
- Main CDK construct that creates Lambda functions with comprehensive configuration
- Automatically creates IAM roles and policies with CloudWatch Logs permissions
- Supports configurable OpenTelemetry layer integration via AWS managed layer (disabled by default)
- Configurable OTEL layer version and architecture (amd64/arm64)
- Supports AWS Lambda SnapStart for improved cold start performance
- Creates function versions and aliases for deployment management
- Handles Lambda permissions for multiple targets (function, version, alias)
StaticSiteConstruct (src/LayeredCraft.Cdk.Constructs/StaticSiteConstruct.cs)
- Comprehensive CDK construct for static website hosting
- Creates S3 bucket with public access for website hosting
- Sets up CloudFront distribution with SSL certificate and custom error pages
- Configures Route53 DNS records for primary domain and alternates
- Supports optional API proxying via CloudFront behaviors for
/api/*paths - Includes automatic asset deployment with cache invalidation
- Exposes
SiteDomainproperty containing the fully qualified domain name
DynamoDbTableConstruct (src/LayeredCraft.Cdk.Constructs/DynamoDbTableConstruct.cs)
- Comprehensive CDK construct for DynamoDB table creation and configuration
- Supports partition keys, sort keys, and global secondary indexes
- Configures DynamoDB streams for real-time data processing
- Includes time-to-live (TTL) attribute support for automatic data expiration
- Automatically generates CloudFormation outputs for table ARN, name, and stream ARN
- Provides
AttachStreamLambdamethod for easy Lambda stream integration - Supports both PAY_PER_REQUEST and PROVISIONED billing modes
Configuration Models (src/LayeredCraft.Cdk.Constructs/Models/)
LambdaFunctionConstructProps: Main configuration interface and record for Lambda constructLambdaPermission: Record for defining Lambda invocation permissionsStaticSiteConstructProps: Configuration interface and record for static site constructDynamoDbTableConstructProps: Configuration interface and record for DynamoDB table construct
Extensions (src/LayeredCraft.Cdk.Constructs/Extensions/)
StackExtensions: Utility methods for CDK Stack operationsCreateExportName: Generates consistent CloudFormation export names with hash truncation support
- Construct Pattern: Uses AWS CDK construct pattern for reusable infrastructure components
- Interface + Record Pattern: Props classes use both interface and record for flexibility and immutability
- Multi-Target Permissions: Automatically applies permissions to function, version, and alias
- OpenTelemetry Integration: Configurable support for AWS OTEL collector layer with version and architecture options
- Versioning Strategy: Creates new versions on every deployment with "live" alias
- .NET 8.0 and .NET 9.0
- Uses AWS CDK v2 (Amazon.CDK.Lib 2.213.0)
Starting with version 2.0.0, the OpenTelemetry layer configuration has been updated:
- Default Behavior: OTEL layer is now disabled by default (breaking change from v1.x)
- Architecture Support: Configurable architecture via
Architectureproperty (default: "amd64") - Version Control: Configurable OTEL layer version via
OtelLayerVersionproperty (default: "0-117-0") - Layer ARN Format:
arn:aws:lambda:{region}:901920570463:layer:aws-otel-collector-{architecture}-ver-{version}:1
To enable OTEL layer in v2.0.0+:
var props = new LambdaFunctionConstructProps
{
// ... other properties
IncludeOtelLayer = true, // Explicitly enable
Architecture = "arm64", // Optional: change architecture
OtelLayerVersion = "0-117-0" // Optional: specify version
};- Uses xUnit v3 with AutoFixture for data generation
- AwesomeAssertions for fluent assertions
- NSubstitute for mocking (though not heavily used in current tests)
- AWS CDK Template assertions for infrastructure testing
Custom Attributes:
LambdaFunctionConstructAutoDataAttribute: AutoFixture attribute with customizable parametersBaseFixtureFactory: Factory for creating configured AutoFixture instances
Test Customizations:
LambdaFunctionConstructCustomization: Configures realistic test data for Lambda constructsStaticSiteConstructCustomization: Configures realistic test data for static site constructs- Supports parameterized test scenarios for Lambda (OTEL layer on/off, permissions included/excluded) and static sites (API domain on/off, alternate domains included/excluded)
- Uses AutoFixture with custom configurations for realistic AWS resource names
- Test assets include
test-lambda.zipfor Lambda deployment packages andstatic-site/folder for static site assets - Tests verify both resource creation and property configuration
- Supports parameterized scenarios for both Lambda (OTEL layer on/off, permissions included/excluded) and static sites (API domain on/off, alternate domains included/excluded)
The library includes comprehensive testing helpers for consumers:
CdkTestHelper (CdkTestHelper.cs):
CreateTestStack(): Creates CDK app and stack with test environmentCreateTestStack<TStack>(): Creates custom stack types directly using generics and reflectionCreateTestStackMinimal(): Creates only the stack (app created internally)CreateTestStackMinimal<TStack>(): Creates custom stack types with app created internallyGetTestAssetPath(): Resolves test asset paths relative to executing assemblyCreatePropsBuilder(): Creates fluent builder with Lambda test defaultsCreateStaticSitePropsBuilder(): Creates fluent builder with static site test defaultsCreateDynamoDbTablePropsBuilder(): Creates fluent builder with DynamoDB table test defaults
LambdaFunctionConstructAssertions (LambdaFunctionConstructAssertions.cs):
- Extension methods for Template assertions
ShouldHaveLambdaFunction(),ShouldHaveOtelLayer(),ShouldHaveCloudWatchLogsPermissions(),ShouldHaveSnapStart(), etc.
LambdaFunctionConstructPropsBuilder (LambdaFunctionConstructPropsBuilder.cs):
- Fluent builder for creating test props with common AWS service integrations
- Methods like
WithDynamoDbAccess(),WithS3Access(),WithApiGatewayPermission(),WithSnapStart()
StaticSiteConstructAssertions (StaticSiteConstructAssertions.cs):
- Extension methods for Template assertions specific to static sites
ShouldHaveCompleteStaticSite(),ShouldHaveStaticWebsiteBucket(),ShouldHaveCloudFrontDistribution(),ShouldHaveSSLCertificate(),ShouldHaveRoute53Records(),ShouldHaveApiProxyBehavior(), etc.
StaticSiteConstructPropsBuilder (StaticSiteConstructPropsBuilder.cs):
- Fluent builder for creating static site test props with scenario-based configurations
- Methods like
WithDomainName(),WithAlternateDomains(),WithApiDomain(),ForBlog(),ForDocumentation(),ForSinglePageApp()
DynamoDbTableConstructAssertions (DynamoDbTableConstructAssertions.cs):
- Extension methods for Template assertions specific to DynamoDB tables
ShouldHaveDynamoTable(),ShouldHavePartitionKey(),ShouldHaveSortKey(),ShouldHaveGlobalSecondaryIndex(),ShouldHaveTableStream(),ShouldHaveTimeToLiveAttribute(),ShouldHaveTableOutputs(), etc.
DynamoDbTableConstructPropsBuilder (DynamoDbTableConstructPropsBuilder.cs):
- Fluent builder for creating DynamoDB table test props with scenario-based configurations
- Methods like
WithTableName(),WithPartitionKey(),WithSortKey(),WithGlobalSecondaryIndex(),WithStream(),WithTimeToLiveAttribute(),ForUserTable(),ForSessionTable(),ForEventSourcing()
Critical Testing Pattern:
- Always create CDK templates AFTER adding constructs to stacks
- Use
Template.FromStack(stack)after construct creation, not before
Generic Stack Creation:
- Use
CreateTestStack<TStack>()andCreateTestStackMinimal<TStack>()for custom stack types - Use
CreateTestStack<TStack, TProps>()andCreateTestStackMinimal<TStack, TProps>()for custom props types - These methods use
Activator.CreateInstancewithBindingFlags.NonPublicto support internal constructors - Eliminates the need to create unused base stacks when testing custom stack implementations
- Supports any stack type that inherits from
Amazon.CDK.Stackand follows the standard constructor pattern - Constructor Support: Works with both public and internal constructors (CDK default is internal)
- Dual Generics: Use dual generics when your stack constructor expects specific props interfaces
- C# 12+ features enabled (records, required properties, collection expressions)
- Nullable reference types enabled
- Implicit usings enabled
- Uses
requiredproperties for mandatory configuration
- Configured for NuGet.org publishing with MIT license
- Includes source linking via Microsoft.SourceLink.GitHub
- Symbol packages (snupkg) enabled for debugging support
- Package metadata includes proper tagging for discoverability
- Uses
PROVIDED_AL2023runtime for Lambda functions (supports custom runtimes) - Configurable OpenTelemetry layer version and architecture (defaults to version 0-117-0, amd64 architecture)
- Default memory: 1024MB, timeout: 6 seconds, log retention: 2 weeks
- Uses
RemovalPolicy.RETAINfor Lambda versions to prevent deletion
The package provides comprehensive testing helpers with support for:
- Custom stack types with public or internal constructors
- Custom props interfaces that extend IStackProps
- Automatic test asset path resolution
- Fluent assertion methods for common AWS resources
CRITICAL: Test Collection Requirement
- All CDK construct tests MUST be decorated with
[Collection("CDK Tests")]to ensure sequential execution - CDK tests cannot run in parallel due to shared CDK context and resource conflicts
- This is already configured in the existing test files and must be maintained for all new construct tests
[Collection("CDK Tests")]
public class LambdaFunctionConstructTests
{
// Your CDK construct tests here
}Single Generic (for IStackProps):
// Works with both public and internal constructors
var (app, stack) = CdkTestHelper.CreateTestStack<MyStack>("stack-name", stackProps);
var stack = CdkTestHelper.CreateTestStackMinimal<MyStack>("stack-name", stackProps);Dual Generic (for custom props interfaces):
// Exact type matching for Activator.CreateInstance
var (app, stack) = CdkTestHelper.CreateTestStack<MyStack, IMyProps>("stack-name", customProps);
var stack = CdkTestHelper.CreateTestStackMinimal<MyStack, IMyProps>("stack-name", customProps);Important Implementation Notes:
- Methods use
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublicto access internal constructors - This follows standard testing library patterns for accessing non-public members
- CDK's default pattern is internal constructors, so this support is essential for real-world testing
- The reflection approach ensures compatibility with any custom stack implementation