A TTL (time-to-live) policy destroys a stack and everything in it once its deadline passes. It’s the mechanism for ephemeral infrastructure: dev workspaces, test environments, demos, anything that should clean itself up without someone remembering to run destroy.
How it works
The deadline is expressed one of two ways: a duration (ttl), measured from when the stack is created, or an absolute instant (expiresAt). Either way it counts down in the background: no apply is needed to trigger the eventual destroy. Re-applying the stack does not move the deadline; a ttl always counts from the stack’s creation, and an expiresAt names the instant directly.
When the deadline passes, formae destroys the stack and all its resources.
Configuration
A TTL policy carries exactly one of ttl or expiresAt. Declaring both, or neither, fails validation when the forma is evaluated.
Relative or absolute?
ttl fits infrastructure whose lifetime is known at creation: a sandbox that lives for the workday, a test environment that should survive its CI run and no longer. Because it measures from stack creation, attaching a ttl to a stack that already exists counts the time the stack has already lived: a ttl = 1.h on a three-day-old stack is already expired and the stack is destroyed on the next expiry check.
expiresAt fits deadlines known as a date: the end of a trial, a scheduled teardown, a booking window. It reads the same to every observer, never shifts on re-apply, and is the right form when another system computes the deadline. To destroy an existing stack some time from now, compute the instant and set expiresAt rather than attaching a ttl.
To move a deadline, re-apply the stack with a new expiresAt (or a new ttl; the change applies in place, still anchored to creation). To remove one, re-apply the stack in reconcile mode without the policy.
onDependents
When the TTL expires, formae checks whether any resource outside the stack depends on a resource inside it:
abort (default): cancel the destruction. The stack stays intact until the dependency is removed.
cascade: delete the dependent resources too, following the dependency chain into other stacks.
cascade can delete resources in stacks you didn’t intend to touch, anywhere the dependency chain leads. Use abort unless you’re certain nothing outside the stack should survive it.
Examples
Inline TTL policy:
Absolute deadline, for a stack that must be gone at a known instant:
Reusable TTL policy, shared by every developer’s sandbox stack:
Reusable TTL policy, shared by every developer’s sandbox stack:
Use cases
- Development environments that clean themselves up at the end of the workday.
- CI/CD test infrastructure that disappears once the test run finishes with it.
- Demo environments that auto-destroy after the demo window.
- Cost control: forgotten resources stop accumulating cost on their own.
Monitoring
Shows every stack’s attached policies, including TTL and its expiry.
See also
- Policy: inline vs. reusable policies, and how to query them.
- Auto-reconcile policy: enforce declared state instead of expiring it. The two can be combined on the same stack.