kubernetes/kops · error

os disk is required for VMScaleSet %q

Error message

os disk is required for VMScaleSet %q

What it means

This error is thrown by the Azure VM ScaleSet terraform task when rendering Terraform JSON. kOps requires that a VM ScaleSet define both a storage profile and, within it, an OSDisk; without an OS disk the scale set cannot boot any instances, so RenderTerraform refuses to emit a partial/invalid resource. It is a fail-fast validation before building the terraformAzureVMScaleSet struct.

Source

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

	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,
		AdminUsername:                 e.AdminUser,
		DisablePasswordAuthentication: &disablePasswordAuthentication,
		AdminSSHKey: []*terraformAzureVMScaleSetSSHKey{
			{
				Username:  e.AdminUser,

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Find where the VMScaleSet task is built for your instance group (upup/pkg/fi/cloudup/azure package model code) and ensure StorageProfile.VirtualMachineScaleSetStorageProfile.OSDisk is assigned
  2. Inspect e.StorageProfile itself: if it is also nil, fix the earlier 'storage profile is required' path — build the whole VirtualMachineScaleSetStorageProfile
  3. If this came from custom code, copy the OSDisk population from the stock azure model (ManagedDisk, OSType, DiskSizeGB, Caching) and re-render
  4. If this is stock kOps failing, file an issue with the cluster spec and kops version, and try a newer kOps release

Example fix

// before
storageProfile := &compute.VirtualMachineScaleSetStorageProfile{}
tf := &terraformAzureVMScaleSet{ ... }
// after
storageProfile := &compute.VirtualMachineScaleSetStorageProfile{
    OSDisk: &compute.VirtualMachineScaleSetOSDisk{
        ManagedDisk: &compute.VirtualMachineScaleSetManagedDiskParameters{ StorageAccountType: storageType },
        OSType:      compute.OperatingSystemTypesLinux,
        Caching:     compute.CachingTypesReadWrite,
    },
}
tf := &terraformAzureVMScaleSet{ ... }
Defensive patterns

Strategy: validation

Validate before calling

if ss.StorageProfile == nil || ss.StorageProfile.VirtualMachineScaleSetStorageProfile == nil {
    return fmt.Errorf("VMScaleSet %s: storage profile missing", name)
}
if ss.StorageProfile.VirtualMachineScaleSetStorageProfile.OSDisk == nil {
    return fmt.Errorf("VMScaleSet %s: OSDisk missing", name)
}

Type guard

func hasOSDisk(ss *compute.VirtualMachineScaleSet) bool {
    return ss != nil && ss.StorageProfile != nil &&
        ss.StorageProfile.VirtualMachineScaleSetStorageProfile != nil &&
        ss.StorageProfile.VirtualMachineScaleSetStorageProfile.OSDisk != nil
}

Prevention

When it happens

Trigger: RenderTerraform is invoked on a VMScaleSet task whose e.StorageProfile is non-nil and passes the first check, but e.StorageProfile.VirtualMachineScaleSetStorageProfile.OSDisk is nil — i.e. the task was constructed (typically from an Azure model context building instance groups) without setting an OS disk.

Common situations: A custom Azure model template or newer/patched kOps code path forgets to populate OSDisk when assembling the storage profile; an upgrade where a previously-populated OSDisk field is dropped during task copying; hand-edited cluster spec or controller code creating VMScaleSet tasks directly.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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