feat: implement expiration policy logic for prebuilds (#17996)

## Summary 

This PR introduces support for expiration policies in prebuilds. The TTL
(time-to-live) is retrieved from the Terraform configuration
([terraform-provider-coder
PR](https://github.com/coder/terraform-provider-coder/pull/404)):
```
prebuilds = {
	  instances = 2
	  expiration_policy {
		  ttl = 86400
	  }
  }
```
**Note**: Since there is no need for precise TTL enforcement down to the
second, in this implementation expired prebuilds are handled in a single
reconciliation cycle: they are deleted, and new instances are created
only if needed to match the desired count.

## Changes

* The outcome of a reconciliation cycle is now expressed as a slice of
reconciliation actions, instead of a single aggregated action.
* Adjusted reconciliation logic to delete expired prebuilds and
guarantee that the number of desired instances is correct.
* Updated relevant data structures and methods to support expiration
policies parameters.
* Added documentation to `Prebuilt workspaces` page
* Update `terraform-provider-coder` to version 2.5.0:
https://github.com/coder/terraform-provider-coder/releases/tag/v2.5.0

Depends on: https://github.com/coder/terraform-provider-coder/pull/404
Fixes: https://github.com/coder/coder/issues/17916
This commit is contained in:
Susana Ferreira
2025-05-26 20:31:24 +01:00
committed by GitHub
parent 589f18627e
commit 6f6e73af03
18 changed files with 1503 additions and 994 deletions
@@ -31,7 +31,8 @@ Prebuilt workspaces are tightly integrated with [workspace presets](./parameters
## Enable prebuilt workspaces for template presets
In your template, add a `prebuilds` block within a `coder_workspace_preset` definition to identify the number of prebuilt
instances your Coder deployment should maintain:
instances your Coder deployment should maintain, and optionally configure a `expiration_policy` block to set a TTL
(Time To Live) for unclaimed prebuilt workspaces to ensure stale resources are automatically cleaned up.
```hcl
data "coder_workspace_preset" "goland" {
@@ -42,7 +43,10 @@ instances your Coder deployment should maintain:
memory = 16
}
prebuilds {
instances = 3 # Number of prebuilt workspaces to maintain
instances = 3 # Number of prebuilt workspaces to maintain
expiration_policy {
ttl = 86400 # Time (in seconds) after which unclaimed prebuilds are expired (1 day)
}
}
}
```
@@ -50,6 +54,9 @@ instances your Coder deployment should maintain:
After you publish a new template version, Coder will automatically provision and maintain prebuilt workspaces through an
internal reconciliation loop (similar to Kubernetes) to ensure the defined `instances` count are running.
The `expiration_policy` block ensures that any prebuilt workspaces left unclaimed for more than `ttl` seconds is considered
expired and automatically cleaned up.
## Prebuilt workspace lifecycle
Prebuilt workspaces follow a specific lifecycle from creation through eligibility to claiming.
@@ -95,6 +102,15 @@ Unclaimed prebuilt workspaces can be interacted with in the same way as any othe
However, if a Prebuilt workspace is stopped, the reconciliation loop will not destroy it.
This gives template admins the ability to park problematic prebuilt workspaces in a stopped state for further investigation.
### Expiration Policy
Prebuilt workspaces support expiration policies through the `ttl` setting inside the `expiration_policy` block.
This value defines the Time To Live (TTL) of a prebuilt workspace, i.e., the duration in seconds that an unclaimed
prebuilt workspace can remain before it is considered expired and eligible for cleanup.
Expired prebuilt workspaces are removed during the reconciliation loop to avoid stale environments and resource waste.
New prebuilt workspaces are only created to maintain the desired count if needed.
### Template updates and the prebuilt workspace lifecycle
Prebuilt workspaces are not updated after they are provisioned.