mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
## Summary
GCP base templates (`gcp-linux`, `gcp-windows`) in the Template Builder
had a Terraform `variable "project_id"` with no default, but their
`base.json` manifests didn't declare it. The UI never prompted for it,
so the provisioner import always failed with:
```
required template variables need values: project_id
```
## Changes
- Add `project_id` as a required variable in both GCP `base.json`
manifests
- Convert templates from raw Terraform variable blocks to Go template
injection (`{{ .Variables.project_id }}`), matching the existing
kubernetes pattern
- Fix `DefaultBaseRenderContext` to supply a `"REQUIRED"` placeholder
for required variables without defaults (previously rendered as `<no
value>`)
- Replace duplicate test subtests with proper GCP coverage including a
missing-variable error case
<details>
<summary>Implementation plan</summary>
### Root cause
The GCP base templates contained `variable "project_id" {}` (no default
= required) in their `.tf.tmpl` files, but the `base.json` manifests had
an empty `variables` array. The Template Builder UI
(`BaseTemplateParametersStep`) is data-driven from `base.json`, so it
never showed a field for `project_id`. The composed Terraform output
still contained the required variable, causing the provisioner import to
fail.
### Fix approach
Follow the pattern established by the kubernetes base template:
1. Declare variables in `base.json` so the UI prompts for them
2. Use Go template syntax (`{{ .Variables.project_id }}`) to inject
values at compose time
3. Remove raw Terraform `variable` blocks from the template since the
value is now baked in
### Files changed
| File | Change |
|---|---|
| `bases/gcp-linux/base.json` | Added `project_id` as a required
variable |
| `bases/gcp-windows/base.json` | Added `project_id` as a required
variable |
| `bases/gcp-linux/main.tf.tmpl` | Removed Terraform variable block, use
Go template injection |
| `bases/gcp-windows/main.tf.tmpl` | Same |
| `bases.go` | `DefaultBaseRenderContext` supplies placeholder for
required vars without defaults |
| `compose_test.go` | Replaced duplicate subtests with proper GCP tests
|
| `templatebuilder_handler_test.go` | Updated `gcp-windows` spec to
expect `project_id` variable |
| Golden files | Regenerated |
</details>
> 🤖 Generated by Coder Agents on behalf of @jeremyruppel
98 lines
2.4 KiB
Plaintext
98 lines
2.4 KiB
Plaintext
terraform {
|
|
required_providers {
|
|
coder = {
|
|
source = "coder/coder"
|
|
}
|
|
google = {
|
|
source = "hashicorp/google"
|
|
}
|
|
}
|
|
}
|
|
|
|
provider "coder" {}
|
|
|
|
variable "project_id" {
|
|
description = "Which Google Compute Project should your workspace live in?"
|
|
default = "test-project_id"
|
|
}
|
|
|
|
# See https://registry.coder.com/modules/coder/gcp-region
|
|
module "gcp_region" {
|
|
source = "registry.coder.com/coder/gcp-region/coder"
|
|
|
|
# This ensures that the latest non-breaking version of the module gets downloaded, you can also pin the module version to prevent breaking changes in production.
|
|
version = "~> 1.0"
|
|
|
|
regions = ["us", "europe"]
|
|
default = "us-central1-a"
|
|
}
|
|
|
|
provider "google" {
|
|
zone = module.gcp_region.value
|
|
project = var.project_id
|
|
}
|
|
|
|
data "coder_workspace" "me" {}
|
|
data "coder_workspace_owner" "me" {}
|
|
|
|
data "google_compute_default_service_account" "default" {}
|
|
|
|
resource "google_compute_disk" "root" {
|
|
name = "coder-${data.coder_workspace.me.id}-root"
|
|
type = "pd-ssd"
|
|
zone = module.gcp_region.value
|
|
image = "projects/windows-cloud/global/images/windows-server-2022-dc-core-v20220215"
|
|
lifecycle {
|
|
ignore_changes = [name, image]
|
|
}
|
|
}
|
|
|
|
resource "coder_agent" "main" {
|
|
auth = "google-instance-identity"
|
|
arch = "amd64"
|
|
os = "windows"
|
|
}
|
|
|
|
resource "google_compute_instance" "dev" {
|
|
zone = module.gcp_region.value
|
|
count = data.coder_workspace.me.start_count
|
|
name = "coder-${lower(data.coder_workspace_owner.me.name)}-${lower(data.coder_workspace.me.name)}"
|
|
machine_type = "e2-medium"
|
|
network_interface {
|
|
network = "default"
|
|
access_config {
|
|
// Ephemeral public IP
|
|
}
|
|
}
|
|
boot_disk {
|
|
auto_delete = false
|
|
source = google_compute_disk.root.name
|
|
}
|
|
service_account {
|
|
email = data.google_compute_default_service_account.default.email
|
|
scopes = ["cloud-platform"]
|
|
}
|
|
metadata = {
|
|
windows-startup-script-ps1 = coder_agent.main.init_script
|
|
serial-port-enable = "TRUE"
|
|
}
|
|
}
|
|
resource "coder_metadata" "workspace_info" {
|
|
count = data.coder_workspace.me.start_count
|
|
resource_id = google_compute_instance.dev[0].id
|
|
|
|
item {
|
|
key = "type"
|
|
value = google_compute_instance.dev[0].machine_type
|
|
}
|
|
}
|
|
|
|
resource "coder_metadata" "home_info" {
|
|
resource_id = google_compute_disk.root.id
|
|
|
|
item {
|
|
key = "size"
|
|
value = "${google_compute_disk.root.size} GiB"
|
|
}
|
|
}
|