|
| 1 | +# Prebuilt workspaces |
| 2 | + |
| 3 | +Prebuilt workspaces allow template administrators to improve the developer experience by reducing workspace |
| 4 | +creation time with an automatically maintained pool of ready-to-use workspaces for specific parameter presets. |
| 5 | + |
| 6 | +The template administrator configures a template to provision prebuilt workspaces in the background, and then when a developer creates |
| 7 | +a new workspace that matches the preset, Coder assigns them an existing prebuilt instance. |
| 8 | +Prebuilt workspaces significantly reduce wait times, especially for templates with complex provisioning or lengthy startup procedures. |
| 9 | + |
| 10 | +Prebuilt workspaces are: |
| 11 | + |
| 12 | +- Created and maintained automatically by Coder to match your specified preset configurations. |
| 13 | +- Claimed transparently when developers create workspaces. |
| 14 | +- Monitored and replaced automatically to maintain your desired pool size. |
| 15 | + |
| 16 | +## Relationship to workspace presets |
| 17 | + |
| 18 | +Prebuilt workspaces are tightly integrated with [workspace presets](./parameters.md#workspace-presets-beta): |
| 19 | + |
| 20 | +1. Each prebuilt workspace is associated with a specific template preset. |
| 21 | +1. The preset must define all required parameters needed to build the workspace. |
| 22 | +1. The preset parameters define the base configuration and are immutable once a prebuilt workspace is provisioned. |
| 23 | +1. Parameters that are not defined in the preset can still be customized by users when they claim a workspace. |
| 24 | + |
| 25 | +## Prerequisites |
| 26 | + |
| 27 | +- [**Premium license**](../../licensing/index.md) |
| 28 | +- **Compatible Terraform provider**: Use `coder/coder` Terraform provider `>= 2.4.0`. |
| 29 | +- **Feature flag**: Enable the `workspace-prebuilds` [experiment](../../../reference/cli/server.md#--experiments). |
| 30 | + |
| 31 | +## Enable prebuilt workspaces for template presets |
| 32 | + |
| 33 | +In your template, add a `prebuilds` block within a `coder_workspace_preset` definition to identify the number of prebuilt |
| 34 | +instances your Coder deployment should maintain: |
| 35 | + |
| 36 | + ```hcl |
| 37 | + data "coder_workspace_preset" "goland" { |
| 38 | + name = "GoLand: Large" |
| 39 | + parameters = { |
| 40 | + jetbrains_ide = "GO" |
| 41 | + cpus = 8 |
| 42 | + memory = 16 |
| 43 | + } |
| 44 | + prebuilds { |
| 45 | + instances = 3 # Number of prebuilt workspaces to maintain |
| 46 | + } |
| 47 | + } |
| 48 | + ``` |
| 49 | + |
| 50 | +After you publish a new template version, Coder will automatically provision and maintain prebuilt workspaces through an |
| 51 | +internal reconciliation loop (similar to Kubernetes) to ensure the defined `instances` count are running. |
| 52 | + |
| 53 | +## Prebuilt workspace lifecycle |
| 54 | + |
| 55 | +Prebuilt workspaces follow a specific lifecycle from creation through eligibility to claiming. |
| 56 | + |
| 57 | +1. After you configure a preset with prebuilds and publish the template, Coder provisions the prebuilt workspace(s). |
| 58 | + |
| 59 | + 1. Coder automatically creates the defined `instances` count of prebuilt workspaces. |
| 60 | + 1. Each new prebuilt workspace is initially owned by an unprivileged system pseudo-user named `prebuilds`. |
| 61 | + - The `prebuilds` user belongs to the `Everyone` group (you can add it to additional groups if needed). |
| 62 | + 1. Each prebuilt workspace receives a randomly generated name for identification. |
| 63 | + 1. The workspace is provisioned like a regular workspace; only its ownership distinguishes it as a prebuilt workspace. |
| 64 | + |
| 65 | +1. Prebuilt workspaces start up and become eligible to be claimed by a developer. |
| 66 | + |
| 67 | + Before a prebuilt workspace is available to users: |
| 68 | + |
| 69 | + 1. The workspace is provisioned. |
| 70 | + 1. The agent starts up and connects to coderd. |
| 71 | + 1. The agent starts its bootstrap procedures and completes its startup scripts. |
| 72 | + 1. The agent reports `ready` status. |
| 73 | + |
| 74 | + After the agent reports `ready`, the prebuilt workspace considered eligible to be claimed. |
| 75 | + |
| 76 | + Prebuilt workspaces that fail during provisioning are retried with a backoff to prevent transient failures. |
| 77 | + |
| 78 | +1. When a developer requests a new workspace, the claiming process occurs: |
| 79 | + |
| 80 | + 1. Developer selects a template and preset that has prebuilt workspaces configured. |
| 81 | + 1. If an eligible prebuilt workspace exists, ownership transfers from the `prebuilds` user to the requesting user. |
| 82 | + 1. The workspace name changes to the user's requested name. |
| 83 | + 1. `terraform apply` is executed using the new ownership details, which may affect the [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace) and |
| 84 | + [`coder_workspace_owner`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_owner) |
| 85 | + datasources (see [Preventing resource replacement](#preventing-resource-replacement) for further considerations). |
| 86 | + |
| 87 | + The developer doesn't see the claiming process — the workspace will just be ready faster than usual. |
| 88 | + |
| 89 | +You can view available prebuilt workspaces in the **Workspaces** view in the Coder dashboard: |
| 90 | + |
| 91 | + |
| 92 | +_Note the search term `owner:prebuilds`._ |
| 93 | + |
| 94 | +### Template updates and the prebuilt workspace lifecycle |
| 95 | + |
| 96 | +Prebuilt workspaces are not updated after they are provisioned. |
| 97 | + |
| 98 | +When a template's active version is updated: |
| 99 | + |
| 100 | +1. Prebuilt workspaces for old versions are automatically deleted. |
| 101 | +1. New prebuilt workspaces are created for the active template version. |
| 102 | +1. If dependencies change (e.g., an [AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) update) without a template version change: |
| 103 | + - You may delete the existing prebuilt workspaces manually. |
| 104 | + - Coder will automatically create new prebuilt workspaces with the updated dependencies. |
| 105 | + |
| 106 | +The system always maintains the desired number of prebuilt workspaces for the active template version. |
| 107 | + |
| 108 | +## Administration and troubleshooting |
| 109 | + |
| 110 | +### Managing resource quotas |
| 111 | + |
| 112 | +Prebuilt workspaces can be used in conjunction with [resource quotas](../../users/quotas.md). |
| 113 | +Because unclaimed prebuilt workspaces are owned by the `prebuilds` user, you can: |
| 114 | + |
| 115 | +1. Configure quotas for any group that includes this user. |
| 116 | +1. Set appropriate limits to balance prebuilt workspace availability with resource constraints. |
| 117 | + |
| 118 | +If a quota is exceeded, the prebuilt workspace will fail provisioning the same way other workspaces do. |
| 119 | + |
| 120 | +### Template configuration best practices |
| 121 | + |
| 122 | +#### Preventing resource replacement |
| 123 | + |
| 124 | +When a prebuilt workspace is claimed, another `terraform apply` run occurs with new values for the workspace owner and name. |
| 125 | + |
| 126 | +This can cause issues in the following scenario: |
| 127 | + |
| 128 | +1. The workspace is initially created with values from the `prebuilds` user and a random name. |
| 129 | +1. After claiming, various workspace properties change (ownership, name, and potentially other values), which Terraform sees as configuration drift. |
| 130 | +1. If these values are used in immutable fields, Terraform will destroy and recreate the resource, eliminating the benefit of prebuilds. |
| 131 | + |
| 132 | +For example, when these values are used in immutable fields like the AWS instance `user_data`, you'll see resource replacement during claiming: |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | +To prevent this, add a `lifecycle` block with `ignore_changes`: |
| 137 | + |
| 138 | +```hcl |
| 139 | +resource "docker_container" "workspace" { |
| 140 | + lifecycle { |
| 141 | + ignore_changes = all |
| 142 | + } |
| 143 | +
|
| 144 | + count = data.coder_workspace.me.start_count |
| 145 | + name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" |
| 146 | + ... |
| 147 | +} |
| 148 | +``` |
| 149 | + |
| 150 | +For more targeted control, specify which attributes to ignore: |
| 151 | + |
| 152 | +```hcl |
| 153 | +resource "docker_container" "workspace" { |
| 154 | + lifecycle { |
| 155 | + ignore_changes = [name] |
| 156 | + } |
| 157 | +
|
| 158 | + count = data.coder_workspace.me.start_count |
| 159 | + name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" |
| 160 | + ... |
| 161 | +} |
| 162 | +``` |
| 163 | + |
| 164 | +Learn more about `ignore_changes` in the [Terraform documentation](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes). |
| 165 | + |
| 166 | +### Current limitations |
| 167 | + |
| 168 | +The prebuilt workspaces feature has these current limitations: |
| 169 | + |
| 170 | +- **Organizations** |
| 171 | + |
| 172 | + Prebuilt workspaces can only be used with the default organization. |
| 173 | + |
| 174 | + [coder/internal#364](https://github.com/coder/internal/issues/364) |
| 175 | + |
| 176 | +- **Autoscaling** |
| 177 | + |
| 178 | + Prebuilt workspaces remain running until claimed. There's no automated mechanism to reduce instances during off-hours. |
| 179 | + |
| 180 | + [coder/internal#312](https://github.com/coder/internal/issues/312) |
| 181 | + |
| 182 | +### Monitoring and observability |
| 183 | + |
| 184 | +#### Available metrics |
| 185 | + |
| 186 | +Coder provides several metrics to monitor your prebuilt workspaces: |
| 187 | + |
| 188 | +- `coderd_prebuilt_workspaces_created_total` (counter): Total number of prebuilt workspaces created to meet the desired instance count. |
| 189 | +- `coderd_prebuilt_workspaces_failed_total` (counter): Total number of prebuilt workspaces that failed to build. |
| 190 | +- `coderd_prebuilt_workspaces_claimed_total` (counter): Total number of prebuilt workspaces claimed by users. |
| 191 | +- `coderd_prebuilt_workspaces_desired` (gauge): Target number of prebuilt workspaces that should be available. |
| 192 | +- `coderd_prebuilt_workspaces_running` (gauge): Current number of prebuilt workspaces in a `running` state. |
| 193 | +- `coderd_prebuilt_workspaces_eligible` (gauge): Current number of prebuilt workspaces eligible to be claimed. |
| 194 | + |
| 195 | +#### Logs |
| 196 | + |
| 197 | +Search for `coderd.prebuilds:` in your logs to track the reconciliation loop's behavior. |
| 198 | + |
| 199 | +These logs provide information about: |
| 200 | + |
| 201 | +1. Creation and deletion attempts for prebuilt workspaces. |
| 202 | +1. Backoff events after failed builds. |
| 203 | +1. Claiming operations. |
0 commit comments