kubernetes/kops · error

storage profile is required for VMScaleSet %q

Error message

storage profile is required for VMScaleSet %q

What it means

RenderTerraform (terraform target for a VMScaleSet) requires the task's StorageProfile, including the embedded compute.VirtualMachineScaleSetStorageProfile, to be set because it is emitted verbatim into the Terraform azurerm_linux_virtual_machine_scale_set resource. A nil storage profile means kOps cannot generate a valid VMSS terraform block, so rendering fails with this error naming the scale set.

Source

Thrown at upup/pkg/fi/cloudup/azuretasks/vmscaleset_terraform.go:95

	Instances                     *int64                                      `cty:"instances"`
	Zones                         []string                                    `cty:"zones"`
	UpgradeMode                   *string                                     `cty:"upgrade_mode"`
	ComputerNamePrefix            *string                                     `cty:"computer_name_prefix"`
	AdminUsername                 *string                                     `cty:"admin_username"`
	DisablePasswordAuthentication *bool                                       `cty:"disable_password_authentication"`
	AdminSSHKey                   []*terraformAzureVMScaleSetSSHKey           `cty:"admin_ssh_key"`
	SourceImageReference          *terraformAzureVMScaleSetImageReference     `cty:"source_image_reference"`
	SourceImageID                 *string                                     `cty:"source_image_id"`
	OSDisk                        *terraformAzureVMScaleSetOSDisk             `cty:"os_disk"`
	NetworkInterface              []*terraformAzureVMScaleSetNetworkInterface `cty:"network_interface"`
	Identity                      *terraformAzureVMScaleSetIdentity           `cty:"identity"`
	UserData                      *terraformWriter.Literal                    `cty:"user_data"`
	Tags                          map[string]string                           `cty:"tags"`
}

func (*VMScaleSet) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *VMScaleSet) error {
	if e.StorageProfile == nil || e.StorageProfile.VirtualMachineScaleSetStorageProfile == nil {
		return fmt.Errorf("storage profile is required for VMScaleSet %q", fi.ValueOf(e.Name))
	}

	storageProfile := e.StorageProfile.VirtualMachineScaleSetStorageProfile
	if storageProfile.OSDisk == nil {
		return fmt.Errorf("os disk is required for VMScaleSet %q", fi.ValueOf(e.Name))
	}

	upgradeMode := string(compute.UpgradeModeManual)
	disablePasswordAuthentication := true
	tf := &terraformAzureVMScaleSet{
		Name:                          e.Name,
		ResourceGroupName:             e.ResourceGroup.terraformName(),
		Location:                      new(t.Cloud.Region()),
		SKU:                           e.SKUName,
		Instances:                     e.Capacity,
		Zones:                         stringSlice(e.Zones),
		UpgradeMode:                   &upgradeMode,
		ComputerNamePrefix:            e.ComputerNamePrefix,

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure the InstanceGroup/cluster spec defines a valid image and machineType, then regenerate: `kops update cluster --target terraform -f out.tf`.
  2. Update kops to the latest patch — a missing storage profile from the model builder is usually a code bug; check kOps GitHub issues for your version.
  3. If you registered a custom hook/override that clears StorageProfile, remove it and let the azure model populate it.
  4. As a last resort, debug the model build path (pkg/model/azuremodel) to confirm the VMScaleSet task gets StorageProfile from the machine template.

Example fix

// before
e := &VMScaleSet{Name: name} // StorageProfile nil
// after
e := &VMScaleSet{
  Name: name,
  StorageProfile: &VMScaleSetStorageProfile{
    VirtualMachineScaleSetStorageProfile: &compute.VirtualMachineScaleSetStorageProfile{
      OSDisk: &compute.VirtualMachineScaleSetOSDisk{ /* ... */ },
    },
  },
}
Defensive patterns

Strategy: validation

Validate before calling

func (e *VMScaleSet) validateForTerraform() error {
  if e.StorageProfile == nil || e.StorageProfile.VirtualMachineScaleSetStorageProfile == nil {
    return fmt.Errorf("storage profile is required for VMScaleSet %q", fi.ValueOf(e.Name))
  }
  if e.StorageProfile.VirtualMachineScaleSetStorageProfile.OSDisk == nil {
    return fmt.Errorf("os disk is required for VMScaleSet %q", fi.ValueOf(e.Name))
  }
  return nil
}

Type guard

func hasStorageProfile(e *VMScaleSet) bool {
  return e.StorageProfile != nil && e.StorageProfile.VirtualMachineScaleSetStorageProfile != nil
}

Try / catch

err := vmssTask.RenderTerraform(target, a, e, changes)
if err != nil && strings.Contains(err.Error(), "storage profile is required") {
  // inspect cluster spec image/machineType, then rebuild the model
  return fmt.Errorf("terraform render blocked: %w", err)
}

Prevention

When it happens

Trigger: RenderTerraform during `kops update cluster --target terraform` when the VMScaleSet task's e.StorageProfile or e.StorageProfile.VirtualMachineScaleSetStorageProfile is nil — i.e. the image/VM size plumbing upstream didn't populate the storage profile before rendering.

Common situations: Cluster spec missing image or machine type leading to an unset storage profile; a bug or recent refactor in the azure model builder; custom overrides clearing StorageProfile; running terraform target against a partially built model.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/e945df373d227927. Report an issue: GitHub.