Google provider 1.16 creates individual instances from templates
A new resource applies an instance template to a single VM. Its schema distinguishes inherited values from explicit overrides.
A reusable instance definition is useful even when the desired result is one named virtual machine. Google provider 1.16.0 adds google_compute_instance_from_template for that case. The July 12 release introduces a resource that creates an individual Compute Engine instance using an existing instance template, with optional overrides supplied by the instance declaration.
The interesting implementation problem is deciding what an omitted field means. In an ordinary instance resource, the provider can supply defaults for arguments the configuration leaves out. In a template-based resource, doing that indiscriminately would overwrite the template. A missing argument needs to mean that the template supplies the value, while an explicitly configured false value must remain an override.
I like this addition because it preserves an infrastructure abstraction that already exists outside Terraform. A configuration can refer to a template without reproducing all of its contents in a second instance definition. That makes the distinction between a shared definition and a particular machine visible in the resource declarations.
A template supplies the baseline
The 1.16.0 resource documentation requires an instance name and source_instance_template. The source can be a template name or self link. A zone is optional when the provider supplies one. Other instance arguments can override template properties, and the resource exports the attributes available from the ordinary instance resource.
variable "instance_template" {}
resource "google_compute_instance_from_template" "example" {
name = "example-instance"
zone = "us-central1-a"
source_instance_template = "${var.instance_template}"
can_ip_forward = false
labels {
purpose = "example"
}
}
This excerpt assumes an existing template identified through the input variable. The explicit forwarding argument matters when the template enables forwarding. The documentation demonstrates the same kind of override, creating a template with forwarding enabled and an instance with it disabled.
That relationship is different from writing a complete machine definition twice. A reviewer can see which values belong to the reusable template and which values the instance changes. The resulting machine still has concrete properties, but the source of each property becomes part of the configuration's design.
For instances that do not use a template, the documentation directs users to google_compute_instance. The new resource has a specific creation contract. Its existence does not change the meaning of the ordinary resource or turn every instance declaration into a template consumer.
The schema removes automatic overrides
The implementation in this release derives its schema from the ordinary compute instance resource. It makes boot_disk, machine_type, and network_interface non-required because a template can supply them. It also removes certain deprecated fields that the read implementation never sets.
More significantly, it recursively removes defaults from schema fields. The source comment states the reason explicitly, avoiding defaults that would accidentally override the template. Non-required fields become computed unless they are deprecated or removed. Terraform can then record values returned from the instance even when the configuration did not specify them.
This separates omission from a provider-selected default. If the provider filled every omitted argument with its ordinary default, the declaration could silently alter the template's intended instance. Treating the resulting value as computed permits the remote object to supply information the user chose not to override.
The recursion matters because instance configuration contains nested structures. Applying the rule only to top-level fields would leave another route for defaults to enter a template-based request. The schema transformation follows nested resource definitions so that inheritance is reflected more broadly in the configuration model.
I find this a useful example of why reusing a resource implementation requires more than copying its arguments. The same field has different defaulting semantics when another object supplies its value. Reuse is sound only when that difference survives through validation and request construction.
Explicit zero values need another mechanism
Creation expands the configured instance and then arranges to send explicitly present top-level fields, even when their values are zero values. It records those names in the API client's ForceSendFields. Without such handling, a false boolean can become indistinguishable from an omitted field during request serialization.
The release's code also records limits to this mechanism. It skips set-valued fields because the existence check appears to report them as present even when that interpretation is inappropriate. Its comments leave nested force-send handling as further work. The implementation therefore should not be described as a universal inheritance and override system for every possible nested value.
After parsing the template reference, creation calls the beta Compute API's instance insertion method with SourceInstanceTemplate. It waits for the operation and then uses the ordinary instance read function. Update and deletion likewise reuse the existing instance handlers, while changing source_instance_template is marked as requiring replacement.
These details make the lifecycle understandable. The template participates in creation, and Terraform subsequently manages the resulting individual instance. Selecting a different source template requests a replacement through this schema. The provider's removed defaults and explicit top-level zero-value handling keep that creation request closer to the inheritance relationship expressed in the configuration.