Skip to content

Writing Resources

Resources are the building blocks of a chant project. Each resource maps to a single infrastructure component defined by the lexicon you’re using.

Import the lexicon types and instantiate a typed resource constructor. Here’s a basic S3 bucket using the AWS lexicon:

src/resource-basic.ts
import { Bucket, VersioningConfiguration, Sub, AWS, Ref } from "@intentius/chant-lexicon-aws";
import { environment } from "./parameters";
export const appBucket = new Bucket({
BucketName: Sub`${AWS.StackName}-${Ref(environment)}-app-data`,
VersioningConfiguration: new VersioningConfiguration({
Status: "Enabled",
}),
PublicAccessBlockConfiguration: {
BlockPublicAcls: true,
BlockPublicPolicy: true,
IgnorePublicAcls: true,
RestrictPublicBuckets: true,
},
});

Every resource definition follows this pattern:

  1. Import types directly from the lexicon package (e.g., import { Bucket } from "@intentius/chant-lexicon-aws")
  2. Instantiate with new ResourceType({...}) using the constructor provided by your lexicon
  3. Export the result as a const

The export is required — chant discovers resources by scanning exports across your src/ directory.

See your lexicon’s documentation for available resource types and concrete examples.

chant reads TypeScript as data. It never executes your code. This means resource properties must be statically evaluable — the evaluator must be able to resolve every value at build time.

Allowed expressions:

ExpressionExample
Literals"us-east-1", 42, true
const referencesconst name = "my-resource"; then name
Arrays and objects[1, 2, 3], { key: "val" }
Spread from const...defaults
Cross-file resource referencesotherResource.arn (via import)
Typed sub-resource constructorsnew SubResourceType({...})
IntrinsicsLexicon-specific helpers (see your lexicon’s docs)

Not allowed (caught by lint before build):

ExpressionLint Rule
Function calls (getName())EVL001
Control flow wrapping resources (if/for)EVL002
Dynamic property access (config[key])EVL003
Spread from non-const sourceEVL004
let / var bindingsEVL001

For the full list of supported and unsupported patterns, see TypeScript as Data.

Use const variables to share values across properties or files:

src/resource-tags.ts
import { Bucket, defaultTags, Sub, AWS, Ref } from "@intentius/chant-lexicon-aws";
import { environment } from "./parameters";
// defaultTags() automatically applies tags to every taggable resource
export const tags = defaultTags([
{ Key: "Team", Value: "platform" },
{ Key: "Environment", Value: "production" },
]);
// This bucket will receive the default tags at synthesis time
export const taggedBucket = new Bucket({
BucketName: Sub`${AWS.StackName}-${Ref(environment)}-tagged`,
PublicAccessBlockConfiguration: {
BlockPublicAcls: true,
BlockPublicPolicy: true,
IgnorePublicAcls: true,
RestrictPublicBuckets: true,
},
});

A file can export more than one resource. There is no hard rule on one resource per file, but keeping related resources together and unrelated ones apart makes projects easier to navigate.