Skip to content

Adoption

A team runs Loom-on-chant by keeping what it wants and replacing or leaving out the rest, all through parameters, with no forking of any composite’s source. Every referenceable piece of Loom’s infrastructure exposes a provision | reference-existing | omit choice, where omit makes sense at all; some pieces are load-bearing and only choose between provision and reference-existing. The seams ship with each composite. A runnable example (src/examples/byo/) and a verification test (src/examples/byo/adoption.test.ts) prove they compose at every tier.

The deep-dives cover the areas most teams wire first:

  • Network & IAM — the two load-bearing reference-existing seams; a platform/security team already owns these.
  • DNS & certificates — reference an existing Route53 zone and ACM cert, provision new ones, or drop the custom domain.
  • Identity & topology — a shared Cognito pool or external IdP across many Loom instances, single- vs multi-boundary.

Every seam, its options, its default, and what replacing it requires.

CompositeSeamOptionsDefaultWhat replacing it requires
shared-foundationnetworkprovision | reference-existingprovision (light-tier scaffolding only; production / production-ha require reference-existing)vpcId, publicSubnetIds (≥2, across 2 AZs), privateSubnetIds (required once PrivateLink is in play)
shared-foundationkmsprovision | reference-existing | omitprovisionLOOM_KMS_KEY_ARN → an existing key (encrypts the two ECR repos); LOOM_KMS=omit drops it
shared-foundationecrprovision | reference-existing | omitprovisionall four of LOOM_FRONTEND_REPOSITORY_URI/_ARN, LOOM_BACKEND_REPOSITORY_URI/_ARN (a partial set is ignored); LOOM_ECR=omit drops the repos
shared-foundationroute53provision | reference-existing | omitprovision (production / production-ha only; unused on light)LOOM_HOSTED_ZONE_ID → the existing zone’s id (loomster adds the alias record, creates no zone); LOOM_ROUTE53=omit drops DNS
shared-foundationacmprovision | reference-existing | omitprovision (production / production-ha only)LOOM_CERTIFICATE_ARN → an already-DNS-validated cert; LOOM_ACM=omit drops HTTPS
shared-foundationagentRoleprovision | reference-existing | omitprovisionLOOM_AGENT_ROLE_ARN → the least-privilege AgentCore execution role a security team already built; LOOM_AGENT_ROLE=omit drops it
shared-foundationloggingBucketNamereference-existing | unsetunset (no access logging)An existing S3 bucket for ALB/NLB + artifact-bucket access logs — Loom never creates this bucket itself
shared-foundationprivateLinkprovision | omitprovision on production / production-ha, omit on light (both overridable)privateLink.modeomit drops the NLB + VPC endpoint service on production; provision (with private subnets supplied) adds it on any tier
loom-dbdataprovision | reference-existing | omitprovisionendpoint, credentialsSecretArn, optionally connectionSecretArn/port/dbName — an externally-managed Postgres endpoint (RDS, Aurora, or otherwise)
loom-dbdbIngress (provision mode only)cidr | security-groupcidr (Loom’s own 10.0.0.0/8)sourceSecurityGroupId — typically shared-foundation’s own ECS task SG
loom-cognitoidentityprovision | reference-existing | omitprovisionuserPoolId, domain, resourceServerIdentifier, m2mClientId; optionally userPoolArn/userClientId/issuer/discoveryUrl/tokenUrl (derived when omitted)
loom-cognitogroups / demo seedopt-in onlyempty (resourceGroups: []), demo seed undefinedA team’s own org structure — Loom’s upstream 12 groups / 22 demo users are never defaulted in
loom-backendexecution + task IAM rolesprovision | reference-existingprovisionboth executionRoleArn + taskRoleArn (LOOM_BACKEND_EXECUTION_ROLE_ARN / LOOM_BACKEND_TASK_ROLE_ARN) — a referenced execution role needs ECR-pull + logs-write; the task role needs whatever the app calls
loom-frontendexecution IAM roleprovision | reference-existingprovisionexecutionRoleArn (LOOM_FRONTEND_EXECUTION_ROLE_ARN) — needs ECR-pull + logs-write; no task role (matches Loom’s template)
loom-backend / loom-frontendCross-stack inputs (cluster ARN, target-group ARN, DB secret ARN, Cognito pool id, image URI)plain composite propsn/a (all required or explicitly optional per prop)Any value from any source — a stackOutput(...)-resolved CFN Parameter (the concrete stacks’ convention) or a literal known at author time (src/examples/byo/’s convention)
loom-agentsagent execution rolevia shared-foundation’s agentRole seamprovisionedagentRoleArn (see the agentRole row above) — the composite creates no other referenceable resource of its own
CIGenerated pipeline vs. BYO-CIchant build --components --generate gitlab | hand off the Build ArchivegeneratedPoint existing CI at the Build Archive instead of running the generated pipeline — see examples/adopt-alb-services/ in the chant repo

The seams above get the infrastructure right; a deployed Loom also has to be usable. That’s a separate layer — Loom’s own database seeds almost nothing, so a fresh deploy’s Security screen has no role or authorizer and no agent can be created. loom-seed closes that by registering what loomster provisioned into Loom’s app database through Loom’s own API. See Seeded defaults and Screens for the full detail.

One clarification worth making here: the Cognito demo seed in the matrix above (loom-cognito’s groups / demo seed row) is Loom’s upstream 12 groups and 22 demo users, which loomster never defaults in — you bring your own org structure. That’s distinct from loom-seed, which populates the application database (roles, authorizers, catalog), not the identity pool.

src/examples/byo/ deploys shared-foundation, loom-db, loom-cognito (twice, as two Loom instances), loom-backend, and loom-frontend with every referenceable seam set to reference-existing, against one consistent set of illustrative platform-team-owned resources (one VPC, one KMS key, one ACM cert + Route53 zone, one pair of ECR repos, one agent role, one external Postgres endpoint, one shared Cognito pool). No file under src/composites/ changed to build it. src/examples/byo/README.md has the layout and the exact chant build commands; src/examples/byo/adoption.test.ts proves the shipped modules compose, that the two Cognito instances resolve to one pool, that every stack with resources of its own serializes to valid CloudFormation with no dangling Ref/Fn::GetAtt targets, and — since the DNS seams only build on the full tiers — that the whole reference-existing seam set holds at light, production, and production-ha.

  • No bastion composite. Nothing here models a bastion host, and Loom’s own upstream template doesn’t define one either. There’s nothing to reference or omit.
  • A fully-reference-existing loom-db / loom-cognito stack has zero resources of its own, by design. chant build --lexicon aws on a directory with no lexicon-tagged declarable at all (not even a Parameter) fails its own empty-output guard, a general chant behavior, not something these seams introduce. Such a stack’s outputs are meant to be consumed by a downstream stackOutput(...), not built standalone, so adoption.test.ts verifies these stacks directly rather than through the CLI’s own build path.