|
| 1 | +# Resource Persistence |
| 2 | + |
| 3 | +Coder templates have full control over workspace ephemerality. In a |
| 4 | +completely ephemeral workspace, there are zero resources in the On state. In |
| 5 | +a completely persistent workspace, there is no difference between the Off and |
| 6 | +On states. |
| 7 | + |
| 8 | +Most workspaces fall somewhere in the middle, persisting user data |
| 9 | +such as filesystem volumes, but deleting expensive, reproducible resources |
| 10 | +such as compute instances. |
| 11 | + |
| 12 | +By default, all Coder resources are persistent, but |
| 13 | +production templates **must** employ the practices laid out in this document |
| 14 | +to prevent accidental deletion. |
| 15 | + |
| 16 | +## Disabling Persistence |
| 17 | + |
| 18 | +The [`coder_workspace` data source](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace) exposes the `start_count = [0 | 1]` attribute that other |
| 19 | +resources reference to become ephemeral. |
| 20 | + |
| 21 | +For example: |
| 22 | + |
| 23 | +```hcl |
| 24 | +data "coder_workspace" "me" { |
| 25 | +} |
| 26 | +
|
| 27 | +resource "docker_container" "workspace" { |
| 28 | + # When `start_count` is 0, `count` is 0, so no `docker_container` is created. |
| 29 | + count = data.coder_workspace.me.start_count # 0 (stopped), 1 (started) |
| 30 | + # ... other config |
| 31 | +} |
| 32 | +``` |
| 33 | + |
| 34 | +## ⚠️ Persistence Pitfalls |
| 35 | + |
| 36 | +Take this example resource: |
| 37 | + |
| 38 | +```hcl |
| 39 | +data "coder_workspace" "me" { |
| 40 | +} |
| 41 | +
|
| 42 | +resource "docker_volume" "home_volume" { |
| 43 | + name = "coder-${data.coder_workspace.me.owner}-home" |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +Because we depend on `coder_workspace.me.owner`, if the owner changes their |
| 48 | +username, Terraform would recreate the volume (wiping its data!) the next |
| 49 | +time the workspace restarts. |
| 50 | + |
| 51 | +Therefore, persistent resource names must only depend on immutable IDs such as: |
| 52 | +* `coder_workspace.me.owner_id` |
| 53 | +* `coder_workspace.me.id` |
| 54 | + |
| 55 | +```hcl |
| 56 | +data "coder_workspace" "me" { |
| 57 | +} |
| 58 | +
|
| 59 | +resource "docker_volume" "home_volume" { |
| 60 | + # This volume will survive until the Workspace is deleted or the template |
| 61 | + # admin changes this resource block. |
| 62 | + name = "coder-${data.coder_workspace.id}-home" |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +## 🛡 Bulletproofing |
| 67 | +Even if our persistent resource depends exclusively on static IDs, a change to |
| 68 | +the `name` format or other attributes would cause Terraform to rebuild the resource. |
| 69 | + |
| 70 | +Prevent Terraform from recreating the resource under any circumstance by setting the [`ignore_changes = all` directive in the `lifecycle` block](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes). |
| 71 | + |
| 72 | +```hcl |
| 73 | +data "coder_workspace" "me" { |
| 74 | +} |
| 75 | +
|
| 76 | +resource "docker_volume" "home_volume" { |
| 77 | + # This resource will survive until either the entire block is deleted |
| 78 | + # or the workspace is. |
| 79 | + name = "coder-${data.coder_workspace.me.id}-home" |
| 80 | + lifecycle { |
| 81 | + ignore_changes = all |
| 82 | + } |
| 83 | +} |
| 84 | +``` |
| 85 | + |
| 86 | +## Up next |
| 87 | + |
| 88 | +- [Templates](../templates.md) |
0 commit comments