Composite Resources
A composite groups related resources into a single reusable unit. Instead of defining multiple related resources separately every time, you define them once as a composite and instantiate it with props.
Defining a Composite
Section titled “Defining a Composite”Use Composite<Props> from @intentius/chant. The factory function receives props and returns a record of named resources:
import { Sub, Role, Function } from "@intentius/chant-lexicon-aws";import { Composite } from "@intentius/chant";
interface LambdaServiceProps { name: string | ReturnType<typeof Sub>; handler: string; runtime?: string; timeout?: number;}
export const LambdaService = Composite<LambdaServiceProps>((props) => { const role = new Role({ AssumeRolePolicyDocument: { Version: "2012-10-17", Statement: [{ Effect: "Allow", Principal: { Service: "lambda.amazonaws.com" }, Action: "sts:AssumeRole", }], }, });
const func = new Function({ FunctionName: props.name, Handler: props.handler, Runtime: props.runtime ?? "nodejs20.x", Role: role.Arn, Timeout: props.timeout ?? 30, Code: { ZipFile: "exports.handler = async () => ({});" }, });
return { role, func };}, "LambdaService");This defines a LambdaService composite that creates two resources: a role and a function.
Using a Composite
Section titled “Using a Composite”Instantiate a composite by calling it with props:
import { Sub, AWS } from "@intentius/chant-lexicon-aws";import { LambdaService } from "./composite-definition";
export const api = LambdaService({ name: Sub`${AWS.StackName}-api`, handler: "index.handler",});This produces all underlying resources with names derived from the props. The composite instance exposes its members directly, so api.role and api.func are accessible for cross-references.
Referencing Members
Section titled “Referencing Members”Within the factory, you can reference other members directly since they’re just variables in the same scope (as seen in the definition above — role: role.arn).
Outside the composite, access members via the instance:
export const monitor = new _.Alarm({ alarmName: "api-errors", dimensions: [{ name: "FunctionName", value: api.func.functionName }],});When to Use Composites
Section titled “When to Use Composites”Composites are useful when:
- Multiple resources always appear together — a function always needs a role and log destination
- You want consistent naming — derive all resource names from a single
nameprop - Cross-resource wiring is complex — encapsulate the references inside the composite
For sharing default property values across resources of the same type, see Presets instead.
Some lexicons also support child projects — subdirectories that build to separate output files. The parent references a child project via a lexicon-specific function (e.g. AWS nestedStack()), and cross-stack values are explicitly exported with stackOutput(). See Multi-Stack Projects for an overview.
Kubernetes Composites
Section titled “Kubernetes Composites”The Kubernetes lexicon ships 27 production-ready composites across four categories. Here’s a quick overview:
Generic Composites
Section titled “Generic Composites”Platform-agnostic patterns that work on any conformant cluster:
| Composite | What it creates |
|---|---|
| WebApp | Deployment + Service + optional Ingress |
| AutoscaledService | Deployment + Service + HPA + PDB with probes |
| CronWorkload | CronJob with RBAC |
| WorkerPool | Queue worker Deployment with RBAC and autoscaling |
| NamespaceEnv | Namespace with ResourceQuota, LimitRange, and NetworkPolicy |
| NodeAgent | DaemonSet with cluster-wide RBAC and host mounts |
Cloud-Specific Composites
Section titled “Cloud-Specific Composites”Each cloud provider has composites that integrate Kubernetes with its native services:
| Pattern | EKS | AKS | GKE |
|---|---|---|---|
| Workload identity | IrsaServiceAccount | AksWorkloadIdentityServiceAccount | WorkloadIdentityServiceAccount |
| Ingress | AlbIngress | AgicIngress | GceIngress / GkeGateway |
| Block storage | EbsStorageClass | AzureDiskStorageClass | GcePdStorageClass |
| Shared storage | EfsStorageClass | AzureFileStorageClass | FilestoreStorageClass |
| DNS | ExternalDnsAgent | AksExternalDnsAgent | GkeExternalDnsAgent |
| Observability | FluentBitAgent / AdotCollector | AzureMonitorCollector | GkeFluentBitAgent / GkeOtelCollector |
Example: AutoscaledService
Section titled “Example: AutoscaledService”AutoscaledService is the most common composite — a production HTTP service with horizontal autoscaling, disruption budgets, and health probes:
import { AutoscaledService } from "@intentius/chant-lexicon-k8s";
const { deployment, service, hpa, pdb } = AutoscaledService({ name: "api", image: "api:2.0", port: 8080, maxReplicas: 10, minReplicas: 3, targetCPUPercent: 60, targetMemoryPercent: 80, cpuRequest: "200m", memoryRequest: "256Mi", cpuLimit: "1", memoryLimit: "1Gi", livenessPath: "/healthz", readinessPath: "/readyz", topologySpread: true, namespace: "production",});All four members (deployment, service, hpa, pdb) are available for cross-references just like any other resource.
Composite Reference Pages
Section titled “Composite Reference Pages”- Generic Composites — WebApp, AutoscaledService, CronWorkload, WorkerPool, NamespaceEnv, NodeAgent
- EKS Composites — IRSA, ALB Ingress, EBS/EFS storage, CloudWatch, ADOT, ExternalDNS
- AKS Composites — Workload Identity, AGIC Ingress, Azure Disk/Files, Azure Monitor, ExternalDNS
- GKE Composites — Workload Identity, GCE Ingress, Gateway API, PD/Filestore, Cloud Logging, Config Connector