fix(coderd/templatebuilder): prompt for DigitalOcean base variables (#27268)

## Summary

The DigitalOcean template builder base declared Terraform `variable`
blocks for `project_uuid` and `ssh_key_id` that the template builder
never filled. `project_uuid` was required with no default, so the build
broke with no way to supply a value from the wizard (DEVEX-591).

This brings the DigitalOcean base to parity with the GCP bases fixed in
#27015:

- Declare `project_uuid` (required) and `ssh_key_id` (optional, default
`0`) in `base.json` so the wizard prompts for them on the first step.
- Inject the entered values via `default = {{ .Variables.* }}` in
`main.tf.tmpl`, keeping the existing `variable` blocks and validation.
- Drop the `sensitive` flags. The variable-injection path
(`mergeBaseVariables`, `DefaultBaseRenderContext`, and the snapshot test
helper) skips sensitive variables, so a sensitive base variable renders
empty. A project UUID / SSH key ID are not secrets.
- Update the README now that the values are prompted rather than
manually edited.
- Regenerate the `digitalocean-linux.tf.golden` snapshot.

## Testing

- `go test ./coderd/templatebuilder/`

<img width="1048" height="616" alt="Screenshot 2026-07-15 at 12 44
42 PM"
src="https://github.com/user-attachments/assets/89e334ca-e904-4387-9264-6ed1614a40ba"
/>

<details>
<summary>Audit of all template builder bases for unfilled
variables</summary>

| Base | Variable status | Verdict |
|------|-----------------|---------|
| aws-linux | no HCL `variable` blocks; provider env auth | OK |
| aws-windows | same | OK |
| azure-linux | same | OK |
| **digitalocean-linux** | `project_uuid` (required, no default) +
`ssh_key_id`; absent from `base.json` | **Fixed here** |
| docker | `docker_socket` has `default = ""`; `container_image` via `{{
.Variables }}` + declared | OK |
| gcp-linux | fixed in #27015 | OK |
| gcp-windows | fixed in #27015 | OK |
| kubernetes | `namespace` (required), `use_kubeconfig`,
`container_image` all via `{{ .Variables }}` + declared | OK |
| scratch | no variables | OK |

DigitalOcean was the only broken base; all others either have safe
defaults or already declare their variables.

**Mechanism note:** `base.json` `variables[]` drives the first-step
prompts and values are injected as HCL literals via `{{
.Variables.<name> }}` (strings quoted, numbers/bools raw; supported
types: string, number, bool). Sensitive/computed variables are
intentionally skipped everywhere the injection map is built, so they
cannot currently be injected. That is why the `sensitive` flags were
removed here.
</details>

---
*This PR was generated by Coder Agents on behalf of @jeremyruppel.*
This commit is contained in:
Jeremy Ruppel
2026-07-15 14:05:18 -04:00
committed by GitHub
parent 3b72a3e5dd
commit d0982e3cc7
4 changed files with 29 additions and 16 deletions
@@ -19,18 +19,14 @@ To deploy workspaces as DigitalOcean Droplets, you'll need:
- DigitalOcean [personal access token (PAT)](https://docs.digitalocean.com/reference/api/create-personal-access-token)
- DigitalOcean project ID (you can get your project information via the `doctl` CLI by running `doctl projects list`)
- DigitalOcean project ID, which the template builder prompts for. You can get
your project information via the `doctl` CLI by running `doctl projects list`.
- Remove the following sections from the `main.tf` file if you don't want to
associate your workspaces with a project:
- **Optional:** DigitalOcean SSH key ID, which the template builder prompts for
(obtain via the `doctl` CLI by running `doctl compute ssh-key list`).
- `variable "project_uuid"`
- `resource "digitalocean_project_resources" "project"`
- **Optional:** DigitalOcean SSH key ID (obtain via the `doctl` CLI by running
`doctl compute ssh-key list`)
- Note that this is only required for Fedora images to work.
- Note that this is only required for Fedora images to work. Leave it as `0`
if you don't need it.
### Authentication
@@ -2,5 +2,24 @@
"id": "digitalocean-linux",
"display_name": "DigitalOcean Droplet (Linux)",
"os": "linux",
"default_context": {}
"default_context": {},
"variables": [
{
"name": "project_uuid",
"type": "string",
"description": "Which DigitalOcean project should your workspace live in? Find it with `doctl projects list`.",
"required": true,
"sensitive": false,
"computed": false
},
{
"name": "ssh_key_id",
"type": "number",
"description": "(Optional) DigitalOcean SSH key ID, required by some Droplet images such as Fedora. Set to 0 for no key. Find it with `doctl compute ssh-key list`.",
"default": 0,
"required": false,
"sensitive": false,
"computed": false
}
]
}
@@ -18,7 +18,7 @@ variable "project_uuid" {
$ doctl projects list
EOF
sensitive = true
default = {{ .Variables.project_uuid }}
validation {
# make sure length of alphanumeric string is 36 (UUIDv4 size)
@@ -39,8 +39,7 @@ variable "ssh_key_id" {
$ doctl compute ssh-key list
EOF
sensitive = true
default = 0
default = {{ .Variables.ssh_key_id }}
validation {
condition = var.ssh_key_id >= 0
@@ -18,7 +18,7 @@ variable "project_uuid" {
$ doctl projects list
EOF
sensitive = true
default = "test-project_uuid"
validation {
# make sure length of alphanumeric string is 36 (UUIDv4 size)
@@ -39,7 +39,6 @@ variable "ssh_key_id" {
$ doctl compute ssh-key list
EOF
sensitive = true
default = 0
validation {