Skip to content

Multi-Stack Output

When your project grows beyond a single stack, chant supports directory-based partitioning to split resources into multiple stacks automatically.

chant determines single-stack vs. multi-stack mode based on your src/ directory structure:

  • Single-stack: Resources live directly in src/ — outputs one template file
  • Multi-stack: Resources are organized into subdirectories — each subdirectory becomes a separate stack
my-project/
├── chant.config.ts
├── src/
│ ├── networking/
│ │ ├── vpc.ts
│ │ └── subnets.ts
│ ├── compute/
│ │ ├── api-function.ts
│ │ └── worker-function.ts
│ └── storage/
│ ├── data-table.ts
│ └── assets-bucket.ts
├── dist/
│ ├── networking.json
│ ├── compute.json
│ ├── storage.json
│ └── manifest.json

Resources in one stack can reference resources in another stack through direct imports. chant resolves these references and generates cross-stack outputs and imports using the appropriate provider-specific mechanism.

Child projects (lexicon-specific nested stacks)

Section titled “Child projects (lexicon-specific nested stacks)”

Some lexicons support child projects — subdirectories that build to separate output files within a single lexicon. Unlike directory-based partitioning, these are declared in code and produce child templates that the parent references.

chant’s core provides two primitives for this:

  • stackOutput(ref) — marks a value for cross-stack export. When the serializer encounters a StackOutput entity, it emits it into the template’s Outputs section.
  • ChildProjectInstance — a Declarable representing a reference to a child project directory. The build pipeline detects these, recursively builds the child, and attaches the child’s BuildResult for the serializer.

Discovery stops at child project boundaries — findInfraFiles() does not recurse into child project subdirectories. Each child project is a separate project scope, only built when referenced by a ChildProjectInstance.

When a serializer produces multiple files, it returns a SerializerResult with a primary template plus additional files:

interface SerializerResult {
/** Primary template content */
primary: string;
/** Additional files keyed by filename */
files?: Record<string, string>;
}

The build pipeline writes additional files alongside the primary output. For example, the AWS lexicon’s nestedStack() produces child CloudFormation templates with explicit cross-stack reference wiring via stackOutput(). See the AWS Nested Stacks guide for details.

For lexicon authors implementing child project support, see Child Projects.

See Multi-Stack Projects for the high-level overview.