Pattern
CDK Config-to-Model Pattern with Mustache
2 min read
awscdkjavamustacheinfrastructurepatterns
Environment-aware YAML configs with Mustache templating, deserialized to strongly-typed Java POJOs for CDK constructs.
In cdk-common, infrastructure config lives in environment-specific directories as Mustache templates. CDK context gets injected at synthesis, then YAML deserializes to typed POJOs.
resources/dev/v1/sqs/orders.mustache
name: {{hosted:id}}-orders
fifo: true
contentBasedDeduplication: true
visibilityTimeout: 30
retentionDays: 14
maxReceiveCount: 3
dlq:
name: {{hosted:id}}-orders-dlq
retentionDays: 14
encryption: KMS
kmsKeyArn: {{kms:orders}}
tags:
service: orders
environment: {{host:environment}}yaml
SqsConf.java
@Value.Immutable @JsonDeserialize(as = ImmutableSqsConf.class)
public interface SqsConf {
String name();
@Value.Default default boolean fifo() { return false; }
@Value.Default default int visibilityTimeout() { return 30; }
@Value.Default default int retentionDays() { return 4; }
Optional<Integer> maxReceiveCount();
Optional<DlqConf> dlq();
@Value.Default default String encryption() { return "KMS"; }
Optional<String> kmsKeyArn();
Map<String, String> tags();
}java
SqsNestedStack.java
// Template.parse: reads file, compiles mustache, injects CDK context
var yaml = Template.parse(this, conf.sqs());
var sqsConf = Mapper.get().readValue(yaml, SqsConf.class);
var dlq = sqsConf.dlq().map(d -> DeadLetterQueue.builder()
.queue(Queue.Builder.create(this, d.name())/*...*/.build())
.maxReceiveCount(sqsConf.maxReceiveCount().orElse(3))
.build());
Queue.Builder.create(this, sqsConf.name())
.queueName(sqsConf.name() + ".fifo")
.fifo(sqsConf.fifo())
.contentBasedDeduplication(sqsConf.fifo())
.visibilityTimeout(Duration.seconds(sqsConf.visibilityTimeout()))
.retentionPeriod(Duration.days(sqsConf.retentionDays()))
.deadLetterQueue(dlq.orElse(null))
.encryptionMasterKey(Key.fromKeyArn(this, "Key", sqsConf.kmsKeyArn().orElseThrow()))
.build();java
Flow
resources/{env}/v1/{service}/*.mustache → Template.parse(scope, path) → Mapper.readValue(yaml, Conf.class) → CDK construct. Context like {{hosted:id}} and {{kms:orders}} resolves from cdk.json or runtime lookups.
By Brandon Stokes•Written byClaude
Related Snippets
TIL
CLAUDE.md for Infrastructure Project Context
Use CLAUDE.md to give Claude Code persistent context about your infrastructure patterns and standards.
Pattern
Robust Claude Project Kickoff
A systematic approach to starting projects with Claude: discovery prompts, hooks, subagents, MCP servers, and CLAUDE.md setup.
Snippet
Modern Terminal Stack
A complete terminal setup: Ghostty, Zellij, and a curated set of CLI tools that replace and enhance the defaults.