When to Use Resolvables
Use resolvables when a resource property depends on output from another resource:- Subnet needs VPC ID (generated when VPC is created)
- Security Group references VPC ID
- IAM Policy references Role ARN
- Any property that uses an identifier generated by cloud infrastructure
Defining a Resolvable Class
Each resource type that can be referenced needs a Resolvable class:hidden res property lets other resources reference this resource’s properties.
Accepting Resolvable References
Use a union type to accept either a literal value or a resolvable reference:Embedding resolvables in string fields
String|formae.Resolvable lets a field be either a literal or a reference, where the whole value is one or the other. To let users splice a reference into the middle of a string (the user-facing side is covered in Embedding resolvables in strings), widen the field to also accept formae.Embedded:
functionCode = formae.embed("const id = '\(store.res.id)'; …"). formae pulls each embedded reference into the same dependency graph as a whole-value resolvable, resolves it at apply time, and hands your plugin the fully assembled plain string. Your plugin never sees an embed marker, exactly as with formae.Resolvable. Extraction is handled for you too: formae regenerates the formae.embed(...) call rather than the resolved value.
Widen a field to formae.Embedded only where embedding genuinely helps, typically free-form text the user authors (code, scripts, templates, user-data) that needs a value from another resource. For a field that is only ever a whole reference, formae.Resolvable remains the right type.
Using Resolvables in Forma Files
Users reference resolvables through the resource’sres property:
vpcId property contains a resolvable marker that formae resolves at apply time.
How Resolution Works
formae uses resolvables to build a dependency graph that determines the order of operations. If a Subnet references a VPC’s ID, formae knows to create the VPC first and destroy the Subnet first. During apply, formae creates the VPC, waits for the response containing{"VpcId": "vpc-12345"}, then passes that resolved value to the Subnet’s Create call. Your plugin never sees resolvable markers, just the final {"VpcId": "vpc-12345", "CidrBlock": "10.0.1.0/24"}.
Resources without dependencies on each other can be processed in parallel.
Note: Parent-child relationships (covered separately) are about discovery ordering. When formae discovers child resources, it automatically injects resolvables that feed into this same dependency graph.
Multiple Resolvable Properties
A resource can expose multiple resolvable properties:Resolvables in Collections
Resolvables work within collections:Collection Resolvables
Some resource properties resolve to collections (Mappings or Listings) rather than scalar values. For example, a Docker Compose stack exposes anendpoints Mapping, and an OVH database service exposes an endpoints Listing.
To let users reference individual items within these collections, use MappingResolvable or ListingResolvable instead of the base Resolvable:
Mapping Properties
UseMappingResolvable when a property resolves to a key-value map:
at(key):
Listing Properties
UseListingResolvable when a property resolves to an ordered list:
at(index), which returns a MappingResolvable for further field navigation:
Typed Element Resolvables
For list properties whose elements have a known structure, you can create a typed resolvable for the element. This gives users field-level access instead of the genericat(key):
MappingResolvable.at(key) fallback always works. Use typed element resolvables when your users frequently reference specific fields in list items.
Return Type Guidelines
Use the correct resolvable type for each property to get compile-time safety:What Plugin Authors Need to Know
You don’t handle resolution. formae’s resolver handles all resolution logic. Your plugin:- Defines which properties can be referenced (via the Resolvable class)
- Accepts union types for properties that might receive references
- Returns property values in Read/Create responses that formae uses to resolve references
Summary
Start by identifying which resource properties other resources might need to reference. Those are your resolvable candidates.

