Coder Templates
Coder workspace templates are complete workspace definitions that live under registry/<namespace>/templates/<name>/ and provision the infrastructure that workspaces run on.
Before You Start
Before writing or modifying any code:
- Understand the request. What platform is the template targeting (Docker, AWS, GCP, Azure, Kubernetes)? What kind of workspace (VM, container, devcontainer)?
- Research existing templates and modules. Look under
registry/ in this repo for similar templates and modules first; if you are not in the repo or cannot find a match, browse https://registry.coder.com. Read main.tf to understand patterns for that platform, especially how they handle agent setup, persistent storage, and module consumption. Prefer platform-specific helper modules (e.g. region selectors) that provide ready-made coder_parameter blocks over hard-coding option lists.
- Check provider docs. Verify the infrastructure provider resources you plan to use. Check both the Coder provider and the platform provider (AWS, Docker, etc.) version-specific docs if needed.
- Clarify before building. If the request is ambiguous (e.g. unclear platform, whether to use devcontainers vs plain VMs, what parameters to expose, or which namespace to use), ask for clarification rather than guessing. Never assume a namespace; always confirm with the user.
- Plan the structure. Decide on infrastructure resources, what
coder_parameter options to expose, which registry modules to consume, and whether additional files like cloud-init configs are needed. When the user describes requirements in terms of their development needs rather than specific Terraform changes (e.g. "I need Node 20 + Postgres 16" or "make this template work for data science"), summarize what you plan to add or change before proceeding. Keep it brief: list the parameters, modules, and infrastructure changes. Skip this for straightforward requests where the action is clear (e.g. "add the code-server module" or "change the default region to us-west-2").
When updating an existing template, read and understand all of its current resources, parameters, and module consumption before making changes. If you observe patterns that deviate from the coder template standards (e.g. missing metadata blocks, hardcoded values that should be parameters, inline implementations that existing modules could replace, missing error handling in scripts), note these to the user as improvement opportunities in your response.
Always prefer the proper implementation over a simpler shortcut. Templates are infrastructure that users depend on. Doing less work is not the same as reducing complexity if it leaves the template incomplete or fragile.
Features marked as "Premium" in this skill require a Coder Premium license. When your implementation uses a Premium feature, note this in your response to the user so they can verify their deployment supports it.
Documentation References
Coder
Coder Terraform provider
Resources:
Data sources:
Terraform providers commonly used in templates
All provider docs follow https://registry.terraform.io/providers/ORG/NAME/latest/docs:
| Provider |
Source |
| Docker |
kreuzwerker/docker |
| AWS |
hashicorp/aws |
| Azure |
hashicorp/azurerm |
| GCP |
hashicorp/google |
| Kubernetes |
hashicorp/kubernetes |
| Cloud-Init |
hashicorp/cloudinit |
Browse all providers: https://registry.terraform.io/browse/providers
Scaffolding a New Template
Only use this when creating a brand new template that does not yet exist. When updating an existing template, edit its files directly.
From repo root:
./scripts/new_template.sh namespace/template-name
Names must be lowercase alphanumeric with hyphens (e.g. my-org/aws-ec2). Underscores are not allowed.
Creates registry/<namespace>/templates/<template-name>/ with:
main.tf: full workspace Terraform config with common patterns — read this as the primary reference for template structure
README.md: frontmatter and documentation
If the namespace is new, the script also creates registry/<namespace>/ with a README. New namespaces additionally need:
registry/<namespace>/.images/avatar.svg (or .png): square image, 400x400px minimum
- The namespace README
avatar field pointing to ./.images/avatar.svg
The scaffolding script does not create the .images/ directory or avatar file. When a new namespace is created, create registry/<namespace>/.images/ and add a placeholder avatar.svg so the directory structure is ready for the user to replace with their real avatar.
The generated namespace README contains placeholder fields (display_name, bio, status, github, avatar, etc.) that the user must fill out. The status field is required and must be official, partner, or community (typically community for new contributors).
Key Patterns
- Provider version constraints must reflect actual functionality requirements. Only set a minimum
coder provider version when the template uses a resource, attribute, or behavior introduced in that version. The same applies to infrastructure providers (Docker, AWS, etc.); check provider changelogs to confirm.
- Include
data.coder_workspace.me and data.coder_workspace_owner.me for workspace and owner metadata. Include data.coder_provisioner.me only when you need the provisioner's arch or os for coder_agent (typical for Docker, Kubernetes, Incus); omit when the workspace OS/arch is fixed (e.g. cloud VMs with a known image).
- Use
locals {} for computed values: username, environment variables, startup scripts, URL assembly
- Use
data.coder_workspace.me.start_count as count on ephemeral resources
- Connect containers/VMs to the agent via
coder_agent.main.init_script and CODER_AGENT_TOKEN
- Add
metadata blocks for workspace dashboard stats (coder stat cpu, coder stat mem, etc.)
- Use
coder_metadata on the primary compute resource to surface key details (region, instance type, image, disk size) in the workspace dashboard
- Optionally use
display_apps block to hide specific built-in apps (defaults show all)
- Before implementing functionality from scratch, look for an existing module under
registry/*/modules/ in this repo; if you cannot find one or are not in the repo, search https://registry.coder.com. If a module already exists for what you need, consume it rather than reimplementing it. When multiple modules serve similar purposes, prefer the actively maintained one and check that you are not using a deprecated or superseded module.
- Before consuming a module, read its
main.tf and README.md to understand the full interface: accepted variables, outputs, prerequisites, and runtime requirements. Prefer paths under registry/<namespace>/modules/<name>/ in this workspace; otherwise use https://registry.coder.com/modules/<namespace>/<module-name>. Never pass arguments without confirming they exist.
- After identifying a module's prerequisites, verify the template's base image satisfies them. If it lacks a required tool, either switch to an image that includes it or ensure the prerequisite is installed before the module's script runs. These runtime issues are not caught by
terraform validate; they only surface when the workspace starts.
- Module source URLs use
registry.coder.com/<namespace>/<module>/coder. Older templates may use registry.coder.com/modules/...; prefer the shorter form when writing new modules or templates.
- Label infrastructure resources with
coder.owner and coder.workspace_id for tracking orphans
- Use
lifecycle { ignore_changes = all } on persistent volumes to prevent data loss
- Do not add comments that narrate what the code does or label sections. Only comment when explaining something non-obvious (e.g. why a workaround exists, a subtle constraint, or an unusual design choice).
Additional files
Templates can include files beyond main.tf + README.md:
cloud-init/*.tftpl: cloud-init configs for VM provisioning (AWS, Azure, GCP), loaded via templatefile(). Prefer this subdirectory over placing cloud-init files at the template root.
build/Dockerfile: custom container images built by the template
.tftpl files: any Terraform template files for scripts, configs, or cloud-init data
Parameters
Use data "coder_parameter" for user-facing workspace options. Typical parameters: region/instance type/CPU/memory/disk for cloud VMs; container image or runtime version for Docker (pass as build_arg when using a local Dockerfile). Use same-platform templates in registry/ as a starting reference, not a rigid pattern. Expose stated preferences as the parameter default with additional sensible option values unless the user explicitly restricts it.
- Prefer
dynamic "option" blocks with for_each from a locals map over static option blocks. See the region selector modules (e.g. coder/aws-region) for the pattern.
- Use
form_type for richer UI controls: dropdown (searchable), multi-select (for list(string)), slider (numeric), radio, checkbox, textarea.
- Conditional parameters: use
count to show/hide a parameter based on another parameter's value.
mutable = false for infrastructure that can't change after creation (region, disk); mutable = true for runtime config.
ephemeral = true for one-shot build options that don't persist between starts.
validation {} with min/max/monotonic for numbers, regex/error for strings.
- Dynamic parameter features require Coder provider
>= 2.4.0.
Presets
Workspace presets bundle commonly-used parameter combinations into selectable options. When a user creates a workspace, they can pick a preset to auto-fill multiple parameters at once. Define presets with data "coder_workspace_preset":
data "coder_workspace_preset" "default" {
name = "Standard Dev Environment"
default = true
parameters = {
"region" = "us-east-1"
"cpu" = "4"
"memory" = "8"
"container_image" = "codercom/enterprise-base:ubuntu"
}
}
- The keys in
parameters must match the name attribute of coder_parameter data sources in the same template.
- Set
default = true on at most one preset to pre-select it in the UI.
- A template can define multiple presets for different use cases.
- Optional fields:
description (context text in UI) and icon (e.g. /emojis/1f680.png).
Prebuilds (Premium)
Prebuilds maintain an automatically-managed pool of pre-provisioned workspaces for a preset, reducing workspace creation time. This is a Premium feature. Prebuilds are configured as a nested block inside a preset:
data "coder_workspace_preset" "goland" {
name = "GoLand: Large"
parameters = {
"jetbrains_ide" = "GO"
"cpu" = "8"
"memory" = "16"
}
prebuilds {
instances = 3
expiration_policy {
ttl = 86400
}
scheduling {
timezone = "UTC"
schedule {
cron = "* 8-18 * * 1-5"
instances = 5
}
}
}
}
instances: number of prebuilt workspaces to keep in the pool (base count when no schedule matches).
expiration_policy.ttl: seconds before unclaimed prebuilds are cleaned up.
scheduling: scale the pool up or down on a time-based cron schedule. The cron minute field must always be *.
- The preset must define all required parameters needed to build the workspace.
- When a prebuild is claimed, ownership transfers to the real user. Use
lifecycle { ignore_changes = [...] } on resources that reference owner-specific values to prevent unnecessary recreation.
README.md
Required YAML frontmatter:
---
display_name: Docker Containers
description: Provision Docker containers with persistent home volumes as Coder workspaces
icon: ../../../../.icons/docker.svg
verified: false
tags: [docker, container]
---
Content rules:
- Single H1 heading matching
display_name, directly below frontmatter
- When increasing header levels, increment by one each time (h1 -> h2 -> h3, not h1 -> h3)
- Opening paragraph describing what the template provisions. Be specific about the platform, compute type, and key capabilities (e.g. "Provision Kubernetes pods on an existing Amazon EKS cluster as Coder workspaces with persistent home volumes") rather than generic (e.g. "AWS Kubernetes template"). The frontmatter
description field should follow the same principle.
- Prerequisites section (infrastructure requirements, provider credentials)
- Architecture section (what resources are created, what's ephemeral vs persistent)
- Code fences labeled
tf (NOT hcl)
- Relative icon paths (e.g.
../../../../.icons/)
- Do NOT include tables or lists that enumerate variables, parameters, or outputs. The registry generates variable and output documentation automatically from the Terraform source. Workspace parameter options are visible in the Coder UI. Describe what the template does and how to use it in prose, not by listing every configurable field.
- Use GFM alerts for callouts:
> [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING], > [!CAUTION]
Icons
Templates reference icons in the README frontmatter icon: field using a relative path to the repo's .icons/ directory (e.g. ../../../../.icons/aws.svg). This icon is displayed on the registry website.
Workflow:
- Check what exists. List the
.icons/ directory at the repo root for available SVGs.
- Use existing icons when they fit. Most templates use a platform icon (aws, gcp, azure, docker, kubernetes) that already exists.
- When an icon doesn't exist, reference the expected path anyway so the structure is correct. Try to source the official SVG from the platform's branding page or repository. If you can obtain it, add it to
.icons/ in this repo.
- Don't substitute a generic icon. If the platform has its own brand identity, use the correct name even if the file doesn't exist yet.
- Track missing icons so you can report them in your response.
Testing
Templates do NOT require .tftest.hcl or main.test.ts. Testing is done by pushing the template to a Coder deployment.
Commands
| Task |
Command |
Scope |
| Format all |
bun run fmt |
Repo |
| Validate |
./scripts/terraform_validate.sh |
Repo |
| ShellCheck |
bun run check:shellcheck |
Repo |
Final Checks
Before considering the work complete, verify:
terraform init && terraform validate passes in the template directory
bun run fmt has been run
bun run check:shellcheck passes if the template includes shell scripts
- README documents prerequisites and architecture
- Shell scripts handle errors gracefully (
|| echo "Warning..." for non-fatal failures). If a script sources external files ($HOME/.bashrc, /etc/bashrc, /etc/os-release), the source must come before set -u; CI enforces this ordering.
- No hardcoded values that should be configurable via variables or parameters
- Asset and icon paths in frontmatter and Terraform must be relative (e.g.
../../../../.icons/), not absolute. External hyperlinks to docs or other websites are fine.
Response to the User
In your response, include:
- A ready-to-run push command with real values filled in. Use
-d to point at the template directory (so it works from the repo root), -m for a short description, and -y to skip interactive prompts:
coder templates push \
registry/ \
-m "Initial version: <brief description>" \
-y < template-name > -d < namespace > /templates/ < template-name > /
- If a new namespace was created, remind the user to fill out the namespace README (
display_name, bio, status, github, etc.) and replace the placeholder avatar. Note that this is only needed if they plan to contribute to the registry.
- If any icons were referenced but not found, list them and note they need to be sourced and added to both this repo's
.icons/ directory and the coder/coder repo at site/static/icon/.
- A note that to contribute the template to the public registry, they can open a pull request to https://github.com/coder/registry.
1---2name: coder-templates3description: Creates and updates Coder Registry workspace templates with agent setup, infrastructure provisioning, and module consumption4---56# Coder Templates78Coder workspace templates are complete workspace definitions that live under `registry/<namespace>/templates/<name>/` and provision the infrastructure that workspaces run on.910## Before You Start1112Before writing or modifying any code:13141. **Understand the request.** What platform is the template targeting (Docker, AWS, GCP, Azure, Kubernetes)? What kind of workspace (VM, container, devcontainer)?152. **Research existing templates and modules.** Look under `registry/` in this repo for similar templates and modules first; if you are not in the repo or cannot find a match, browse <https://registry.coder.com>. Read `main.tf` to understand patterns for that platform, especially how they handle agent setup, persistent storage, and module consumption. Prefer platform-specific helper modules (e.g. region selectors) that provide ready-made `coder_parameter` blocks over hard-coding option lists.163. **Check provider docs.** Verify the infrastructure provider resources you plan to use. Check both the Coder provider and the platform provider (AWS, Docker, etc.) version-specific docs if needed.174. **Clarify before building.** If the request is ambiguous (e.g. unclear platform, whether to use devcontainers vs plain VMs, what parameters to expose, or which namespace to use), ask for clarification rather than guessing. Never assume a namespace; always confirm with the user.185. **Plan the structure.** Decide on infrastructure resources, what `coder_parameter` options to expose, which registry modules to consume, and whether additional files like cloud-init configs are needed. When the user describes requirements in terms of their development needs rather than specific Terraform changes (e.g. "I need Node 20 + Postgres 16" or "make this template work for data science"), summarize what you plan to add or change before proceeding. Keep it brief: list the parameters, modules, and infrastructure changes. Skip this for straightforward requests where the action is clear (e.g. "add the code-server module" or "change the default region to us-west-2").1920When updating an existing template, read and understand all of its current resources, parameters, and module consumption before making changes. If you observe patterns that deviate from the coder template standards (e.g. missing metadata blocks, hardcoded values that should be parameters, inline implementations that existing modules could replace, missing error handling in scripts), note these to the user as improvement opportunities in your response.2122Always prefer the proper implementation over a simpler shortcut. Templates are infrastructure that users depend on. Doing less work is not the same as reducing complexity if it leaves the template incomplete or fragile.2324Features marked as "Premium" in this skill require a Coder Premium license. When your implementation uses a Premium feature, note this in your response to the user so they can verify their deployment supports it.2526## Documentation References2728### Coder2930- Platform docs (latest): <https://coder.com/docs>31- Version-specific docs: `https://coder.com/docs/@v{MAJOR}.{MINOR}.{PATCH}` (e.g. <https://coder.com/docs/@v2.31.5>)32- Creating templates: <https://coder.com/docs/admin/templates/creating-templates>33- Extending templates: <https://coder.com/docs/admin/templates/extending-templates>34- Template parameters: <https://coder.com/docs/admin/templates/extending-templates/parameters>35- Dynamic parameters: <https://coder.com/docs/admin/templates/extending-templates/dynamic-parameters>36- Workspace presets: <https://coder.com/docs/admin/templates/extending-templates/parameters#workspace-presets>37- Prebuilt workspaces: <https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces>38- Agent Boundaries: <https://coder.com/docs/ai-coder/agent-boundaries>39- Coder Registry: <https://registry.coder.com>4041### Coder Terraform provider4243- Provider docs (latest): <https://registry.terraform.io/providers/coder/coder/latest/docs>44- Version-specific provider docs: replace `latest` with a version number (e.g. <https://registry.terraform.io/providers/coder/coder/2.13.1/docs>)4546Resources:4748| Resource | Docs |49| ---------------- | ------------------------------------------------------------------------------------ |50| `coder_agent` | <https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent> |51| `coder_app` | <https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app> |52| `coder_script` | <https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script> |53| `coder_env` | <https://registry.terraform.io/providers/coder/coder/latest/docs/resources/env> |54| `coder_metadata` | <https://registry.terraform.io/providers/coder/coder/latest/docs/resources/metadata> |5556Data sources:5758| Data Source | Docs |59| ------------------------ | ----------------------------------------------------------------------------------------------- |60| `coder_parameter` | <https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter> |61| `coder_workspace` | <https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace> |62| `coder_workspace_owner` | <https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_owner> |63| `coder_provisioner` | <https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/provisioner> |64| `coder_workspace_preset` | <https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace_preset> |6566### Terraform providers commonly used in templates6768All provider docs follow `https://registry.terraform.io/providers/ORG/NAME/latest/docs`:6970| Provider | Source |71| ---------- | ---------------------- |72| Docker | `kreuzwerker/docker` |73| AWS | `hashicorp/aws` |74| Azure | `hashicorp/azurerm` |75| GCP | `hashicorp/google` |76| Kubernetes | `hashicorp/kubernetes` |77| Cloud-Init | `hashicorp/cloudinit` |7879Browse all providers: <https://registry.terraform.io/browse/providers>8081## Scaffolding a New Template8283Only use this when creating a brand new template that does not yet exist. When updating an existing template, edit its files directly.8485From repo root:8687```bash88./scripts/new_template.sh namespace/template-name89```9091Names must be lowercase alphanumeric with hyphens (e.g. `my-org/aws-ec2`). Underscores are not allowed.9293Creates `registry/<namespace>/templates/<template-name>/` with:9495- `main.tf`: full workspace Terraform config with common patterns — read this as the primary reference for template structure96- `README.md`: frontmatter and documentation9798If the namespace is new, the script also creates `registry/<namespace>/` with a README. New namespaces additionally need:99100- `registry/<namespace>/.images/avatar.svg` (or `.png`): square image, 400x400px minimum101- The namespace README `avatar` field pointing to `./.images/avatar.svg`102103The scaffolding script does not create the `.images/` directory or avatar file. When a new namespace is created, create `registry/<namespace>/.images/` and add a placeholder `avatar.svg` so the directory structure is ready for the user to replace with their real avatar.104105The generated namespace README contains placeholder fields (`display_name`, `bio`, `status`, `github`, `avatar`, etc.) that the user must fill out. The `status` field is required and must be `official`, `partner`, or `community` (typically `community` for new contributors).106107## Key Patterns108109- Provider version constraints must reflect actual functionality requirements. Only set a minimum `coder` provider version when the template uses a resource, attribute, or behavior introduced in that version. The same applies to infrastructure providers (Docker, AWS, etc.); check provider changelogs to confirm.110- Include `data.coder_workspace.me` and `data.coder_workspace_owner.me` for workspace and owner metadata. Include `data.coder_provisioner.me` only when you need the provisioner's `arch` or `os` for `coder_agent` (typical for Docker, Kubernetes, Incus); omit when the workspace OS/arch is fixed (e.g. cloud VMs with a known image).111- Use `locals {}` for computed values: username, environment variables, startup scripts, URL assembly112- Use `data.coder_workspace.me.start_count` as `count` on ephemeral resources113- Connect containers/VMs to the agent via `coder_agent.main.init_script` and `CODER_AGENT_TOKEN`114- Add `metadata` blocks for workspace dashboard stats (`coder stat cpu`, `coder stat mem`, etc.)115- Use `coder_metadata` on the primary compute resource to surface key details (region, instance type, image, disk size) in the workspace dashboard116- Optionally use `display_apps` block to hide specific built-in apps (defaults show all)117- Before implementing functionality from scratch, look for an existing module under `registry/*/modules/` in this repo; if you cannot find one or are not in the repo, search <https://registry.coder.com>. If a module already exists for what you need, consume it rather than reimplementing it. When multiple modules serve similar purposes, prefer the actively maintained one and check that you are not using a deprecated or superseded module.118- Before consuming a module, read its `main.tf` and `README.md` to understand the full interface: accepted variables, outputs, prerequisites, and runtime requirements. Prefer paths under `registry/<namespace>/modules/<name>/` in this workspace; otherwise use `https://registry.coder.com/modules/<namespace>/<module-name>`. Never pass arguments without confirming they exist.119- After identifying a module's prerequisites, verify the template's base image satisfies them. If it lacks a required tool, either switch to an image that includes it or ensure the prerequisite is installed before the module's script runs. These runtime issues are not caught by `terraform validate`; they only surface when the workspace starts.120- Module source URLs use `registry.coder.com/<namespace>/<module>/coder`. Older templates may use `registry.coder.com/modules/...`; prefer the shorter form when writing new modules or templates.121- Label infrastructure resources with `coder.owner` and `coder.workspace_id` for tracking orphans122- Use `lifecycle { ignore_changes = all }` on persistent volumes to prevent data loss123- Do not add comments that narrate what the code does or label sections. Only comment when explaining something non-obvious (e.g. why a workaround exists, a subtle constraint, or an unusual design choice).124125### Additional files126127Templates can include files beyond `main.tf` + `README.md`:128129- `cloud-init/*.tftpl`: cloud-init configs for VM provisioning (AWS, Azure, GCP), loaded via `templatefile()`. Prefer this subdirectory over placing cloud-init files at the template root.130- `build/Dockerfile`: custom container images built by the template131- `.tftpl` files: any Terraform template files for scripts, configs, or cloud-init data132133### Parameters134135Use `data "coder_parameter"` for user-facing workspace options. Typical parameters: region/instance type/CPU/memory/disk for cloud VMs; container image or runtime version for Docker (pass as `build_arg` when using a local Dockerfile). Use same-platform templates in `registry/` as a starting reference, not a rigid pattern. Expose stated preferences as the parameter `default` with additional sensible `option` values unless the user explicitly restricts it.136137- Prefer `dynamic "option"` blocks with `for_each` from a `locals` map over static `option` blocks. See the region selector modules (e.g. `coder/aws-region`) for the pattern.138- Use `form_type` for richer UI controls: `dropdown` (searchable), `multi-select` (for `list(string)`), `slider` (numeric), `radio`, `checkbox`, `textarea`.139- Conditional parameters: use `count` to show/hide a parameter based on another parameter's value.140- `mutable = false` for infrastructure that can't change after creation (region, disk); `mutable = true` for runtime config.141- `ephemeral = true` for one-shot build options that don't persist between starts.142- `validation {}` with `min`/`max`/`monotonic` for numbers, `regex`/`error` for strings.143- Dynamic parameter features require Coder provider `>= 2.4.0`.144145### Presets146147Workspace presets bundle commonly-used parameter combinations into selectable options. When a user creates a workspace, they can pick a preset to auto-fill multiple parameters at once. Define presets with `data "coder_workspace_preset"`:148149```tf150data "coder_workspace_preset" "default" {151 name = "Standard Dev Environment"152 default = true153154 parameters = {155 "region" = "us-east-1"156 "cpu" = "4"157 "memory" = "8"158 "container_image" = "codercom/enterprise-base:ubuntu"159 }160}161```162163- The keys in `parameters` must match the `name` attribute of `coder_parameter` data sources in the same template.164- Set `default = true` on at most one preset to pre-select it in the UI.165- A template can define multiple presets for different use cases.166- Optional fields: `description` (context text in UI) and `icon` (e.g. `/emojis/1f680.png`).167168### Prebuilds (Premium)169170Prebuilds maintain an automatically-managed pool of pre-provisioned workspaces for a preset, reducing workspace creation time. This is a Premium feature. Prebuilds are configured as a nested block inside a preset:171172```tf173data "coder_workspace_preset" "goland" {174 name = "GoLand: Large"175 parameters = {176 "jetbrains_ide" = "GO"177 "cpu" = "8"178 "memory" = "16"179 }180181 prebuilds {182 instances = 3183184 expiration_policy {185 ttl = 86400186 }187188 scheduling {189 timezone = "UTC"190 schedule {191 cron = "* 8-18 * * 1-5"192 instances = 5193 }194 }195 }196}197```198199- `instances`: number of prebuilt workspaces to keep in the pool (base count when no schedule matches).200- `expiration_policy.ttl`: seconds before unclaimed prebuilds are cleaned up.201- `scheduling`: scale the pool up or down on a time-based cron schedule. The `cron` minute field must always be `*`.202- The preset must define all required parameters needed to build the workspace.203- When a prebuild is claimed, ownership transfers to the real user. Use `lifecycle { ignore_changes = [...] }` on resources that reference owner-specific values to prevent unnecessary recreation.204205## README.md206207Required YAML frontmatter:208209```yaml210---211display_name: Docker Containers212description: Provision Docker containers with persistent home volumes as Coder workspaces213icon: ../../../../.icons/docker.svg214verified: false215tags: [docker, container]216---217```218219Content rules:220221- Single H1 heading matching `display_name`, directly below frontmatter222- When increasing header levels, increment by one each time (h1 -> h2 -> h3, not h1 -> h3)223- Opening paragraph describing what the template provisions. Be specific about the platform, compute type, and key capabilities (e.g. "Provision Kubernetes pods on an existing Amazon EKS cluster as Coder workspaces with persistent home volumes") rather than generic (e.g. "AWS Kubernetes template"). The frontmatter `description` field should follow the same principle.224- **Prerequisites** section (infrastructure requirements, provider credentials)225- **Architecture** section (what resources are created, what's ephemeral vs persistent)226- Code fences labeled `tf` (NOT `hcl`)227- Relative icon paths (e.g. `../../../../.icons/`)228- **Do NOT include tables or lists that enumerate variables, parameters, or outputs.** The registry generates variable and output documentation automatically from the Terraform source. Workspace parameter options are visible in the Coder UI. Describe what the template does and how to use it in prose, not by listing every configurable field.229- Use [GFM alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) for callouts: `> [!NOTE]`, `> [!TIP]`, `> [!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]`230231## Icons232233Templates reference icons in the README frontmatter `icon:` field using a relative path to the repo's `.icons/` directory (e.g. `../../../../.icons/aws.svg`). This icon is displayed on the registry website.234235Workflow:2362371. **Check what exists.** List the `.icons/` directory at the repo root for available SVGs.2382. **Use existing icons when they fit.** Most templates use a platform icon (aws, gcp, azure, docker, kubernetes) that already exists.2393. **When an icon doesn't exist,** reference the expected path anyway so the structure is correct. Try to source the official SVG from the platform's branding page or repository. If you can obtain it, add it to `.icons/` in this repo.2404. **Don't substitute a generic icon.** If the platform has its own brand identity, use the correct name even if the file doesn't exist yet.2415. **Track missing icons** so you can report them in your response.242243## Testing244245Templates do NOT require `.tftest.hcl` or `main.test.ts`. Testing is done by pushing the template to a Coder deployment.246247## Commands248249| Task | Command | Scope |250| ---------- | --------------------------------- | ----- |251| Format all | `bun run fmt` | Repo |252| Validate | `./scripts/terraform_validate.sh` | Repo |253| ShellCheck | `bun run check:shellcheck` | Repo |254255## Final Checks256257Before considering the work complete, verify:258259- `terraform init && terraform validate` passes in the template directory260- `bun run fmt` has been run261- `bun run check:shellcheck` passes if the template includes shell scripts262- README documents prerequisites and architecture263- Shell scripts handle errors gracefully (`|| echo "Warning..."` for non-fatal failures). If a script sources external files (`$HOME/.bashrc`, `/etc/bashrc`, `/etc/os-release`), the `source` must come before `set -u`; CI enforces this ordering.264- No hardcoded values that should be configurable via variables or parameters265- Asset and icon paths in frontmatter and Terraform must be relative (e.g. `../../../../.icons/`), not absolute. External hyperlinks to docs or other websites are fine.266267## Response to the User268269In your response, include:270271- A ready-to-run push command with real values filled in. Use `-d` to point at the template directory (so it works from the repo root), `-m` for a short description, and `-y` to skip interactive prompts:272273```bash274coder templates push \275 registry/ \276 -m "Initial version: <brief description>" \277 -y < template-name > -d < namespace > /templates/ < template-name > /278```279280- If a new namespace was created, remind the user to fill out the namespace README (`display_name`, `bio`, `status`, `github`, etc.) and replace the placeholder avatar. Note that this is only needed if they plan to contribute to the registry.281- If any icons were referenced but not found, list them and note they need to be sourced and added to both this repo's `.icons/` directory and the `coder/coder` repo at `site/static/icon/`.282- A note that to contribute the template to the public registry, they can open a pull request to <https://github.com/coder/registry>.