Skip to main content
Some resources can only exist within the context of a parent resource. For example, an IAM RolePolicy belongs to an IAM Role, or an ECS TaskSet belongs to a Service. formae models these relationships to enable tiered discovery and correct ordering of create/destroy operations.

Why Parent-Child Matters

Parent-child relationships exist primarily for discovery. To list child resources, you need the parent’s identifier. formae discovers parents first, then uses their properties to discover children. When formae discovers a child resource, it automatically injects a resolvable reference from the child to its parent. This resolvable reference feeds into formae’s dependency DAG, which ensures correct ordering during apply and destroy operations. See Resolvables for details on how the DAG determines update ordering. formae handles discovery ordering and resolvable injection automatically when you declare the relationship correctly.

Declaring a Parent-Child Relationship

Use the parent and listParam fields in your @ResourceHint:

The ListProperty Class

formae.ListProperty maps parent properties to List API parameters:
Example: For IAM RolePolicies:
  • parentProperty = "RoleName": Get the RoleName from the discovered Role
  • listParameter = "RoleName": Pass it to the List API as the RoleName parameter

How Tiered Discovery Works

When formae runs discovery:
  1. Discover root resources: Resources without a parent are discovered first (VPCs, Roles, S3 Buckets)
  2. Extract parent properties: For each discovered parent, formae extracts the parentProperty value
  3. Discover children: formae calls your plugin’s List() operation with the parent’s property value in AdditionalProperties
  4. Recurse: If children have their own children, the process continues

Automatic Resolvable Injection

When formae discovers a child resource, it automatically creates a resolvable reference to the parent:
This resolvable reference is added to formae’s dependency DAG, which determines update ordering:
  • Apply: VPC is created before Subnet (dependency first)
  • Destroy: Subnet is destroyed before VPC (dependent first)
The ordering mechanism is the same as any other resolvable. Parent-child just automates the injection during discovery.

Multi-Level Hierarchies

Parent-child relationships can be nested to any depth:
Discovery order: VPC to Subnet to NetworkInterface (parents before children) Update ordering (via injected resolvables):
  • Apply: VPC to Subnet to NetworkInterface
  • Destroy: NetworkInterface to Subnet to VPC

Multiple List Parameters

Some resources require multiple parent properties to list. Use a list of ListProperty:
Your plugin’s List() receives both parameters in AdditionalProperties.

Plugin Implementation

Your plugin’s List() operation receives parent properties in request.AdditionalProperties:

When to Use Parent-Child

Use parent-child relationships when: Don’t use parent-child for:
  • Simple references (Subnet references VPC but isn’t “inside” it conceptually)
  • Resources that can exist independently
  • Resources where you don’t need tiered discovery

Common Patterns

AWS CloudControl Resources

Many AWS resources follow the parent-child pattern:

Resources Without Discovery

Some child resources can’t be discovered (API doesn’t support listing):
These resources must be defined in Forma files; they won’t be auto-discovered.

Summary

Declare parent-child relationships to enable tiered discovery and automatic ordering. formae handles the complexity of discovering in the right order and injecting references automatically.