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.
Defining a Resource
Section titled “Defining a Resource”Import the lexicon types and instantiate a typed resource constructor. Here’s a basic S3 bucket using the AWS lexicon:
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:
- Import types directly from the lexicon package (e.g.,
import { Bucket } from "@intentius/chant-lexicon-aws") - Instantiate with
new ResourceType({...})using the constructor provided by your lexicon - 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.
Property Rules
Section titled “Property Rules”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:
| Expression | Example |
|---|---|
| Literals | "us-east-1", 42, true |
const references | const name = "my-resource"; then name |
| Arrays and objects | [1, 2, 3], { key: "val" } |
Spread from const | ...defaults |
| Cross-file resource references | otherResource.arn (via import) |
| Typed sub-resource constructors | new SubResourceType({...}) |
| Intrinsics | Lexicon-specific helpers (see your lexicon’s docs) |
Not allowed (caught by lint before build):
| Expression | Lint Rule |
|---|---|
Function calls (getName()) | EVL001 |
Control flow wrapping resources (if/for) | EVL002 |
Dynamic property access (config[key]) | EVL003 |
Spread from non-const source | EVL004 |
let / var bindings | EVL001 |
For the full list of supported and unsupported patterns, see TypeScript as Data.
Extracting Shared Values
Section titled “Extracting Shared Values”Use const variables to share values across properties or files:
import { Bucket, defaultTags, Sub, AWS, Ref } from "@intentius/chant-lexicon-aws";import { environment } from "./parameters";
// defaultTags() automatically applies tags to every taggable resourceexport const tags = defaultTags([ { Key: "Team", Value: "platform" }, { Key: "Environment", Value: "production" },]);
// This bucket will receive the default tags at synthesis timeexport const taggedBucket = new Bucket({ BucketName: Sub`${AWS.StackName}-${Ref(environment)}-tagged`, PublicAccessBlockConfiguration: { BlockPublicAcls: true, BlockPublicPolicy: true, IgnorePublicAcls: true, RestrictPublicBuckets: true, },});Multiple Resources per File
Section titled “Multiple Resources per File”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.
Next Steps
Section titled “Next Steps”- Cross-File References — reference resources defined in other files
- Composite Resources — group related resources into reusable units
- Presets — share default property values across resources