> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formae.io/llms.txt
> Use this file to discover all available pages before exploring further.

# TTL policy

> Automatically destroy a stack and its resources after a set duration.

A TTL (time-to-live) policy destroys a stack and everything in it once a set duration has passed. 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 countdown starts when the stack is first created with the policy attached, and it counts down in the background: no `apply` is needed to trigger the eventual destroy. Re-applying the stack does not restart the clock; it always counts from the original creation time.

When the TTL expires, formae destroys the stack and all its resources.

## Configuration

| Property       | Type                     | Description                                                                   |
| -------------- | ------------------------ | ----------------------------------------------------------------------------- |
| `ttl`          | Duration                 | How long the stack should live, for example `1.h`, `24.h`, `7.d`              |
| `onDependents` | `"abort"` \| `"cascade"` | What to do if resources outside the stack depend on it. Defaults to `"abort"` |

### 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.

<Warning>
  `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.
</Warning>

## Examples

**Inline TTL policy:**

```kotlin theme={"languages":{"custom":["/languages/pkl.json"]}}
amends "@formae/forma.pkl"

import "@formae/formae.pkl"
import "@aws/aws.pkl"
import "@aws/logs/loggroup.pkl"

local devTarget = new formae.Target {
  label = "dev-target"
  config = new aws.Config {
    region = "us-east-1"
  }
}

forma {
  devTarget

  new formae.Stack {
    label = "feature-xyz"
    description = "Temporary dev environment for feature XYZ"
    policies = new Listing {
      new formae.TTLPolicy {
        ttl = 8.h              // Destroy after 8 hours
        onDependents = "abort" // Don't destroy if other resources depend on it
      }
    }
  }

  new loggroup.LogGroup {
    label = "feature-logs"
    stack = "feature-xyz"
    target = devTarget.res
    logGroupName = "/dev/feature-xyz/logs"
    retentionInDays = 1
  }
}
```

**Reusable TTL policy**, shared by every developer's sandbox stack:

```kotlin theme={"languages":{"custom":["/languages/pkl.json"]}}
amends "@formae/forma.pkl"

import "@formae/formae.pkl"
import "@aws/aws.pkl"
import "@aws/logs/loggroup.pkl"

local ephemeralPolicy = new formae.TTLPolicy {
  label = "ephemeral-4h"
  ttl = 4.h
  onDependents = "cascade"
}

local devTarget = new formae.Target {
  label = "dev-target"
  config = new aws.Config {
    region = "us-east-1"
  }
}

forma {
  ephemeralPolicy
  devTarget

  new formae.Stack {
    label = "alice-dev"
    description = "Alice's development environment"
    policies = new Listing { ephemeralPolicy.res }
  }

  new loggroup.LogGroup {
    label = "alice-logs"
    stack = "alice-dev"
    target = devTarget.res
    logGroupName = "/dev/alice/logs"
  }

  new formae.Stack {
    label = "bob-dev"
    description = "Bob's development environment"
    policies = new Listing { ephemeralPolicy.res }
  }

  new loggroup.LogGroup {
    label = "bob-logs"
    stack = "bob-dev"
    target = devTarget.res
    logGroupName = "/dev/bob/logs"
  }
}
```

## 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

```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
formae inventory stacks
```

Shows every stack's attached policies, including TTL and its expiry.

## See also

* [Policy](/documentation/concepts/policy): inline vs. reusable policies, and how to query them.
* [Auto-reconcile policy](/documentation/concepts/policies/auto-reconcile): enforce declared state instead of expiring it. The two can be combined on the same stack.
