{"record":{"id":"a2287f4e791c86ac","repo":"kubernetes/kops","slug":"cluster-is-not-an-azure-cluster","errorCode":null,"errorMessage":"cluster is not an Azure cluster","messagePattern":"cluster is not an Azure cluster","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/cloudconfig.go","lineNumber":52,"sourceCode":"\t// Cluster config\n\tResourceGroup               string `json:\"resourceGroup,omitempty\"`\n\tLocation                    string `json:\"location,omitempty\"`\n\tVnetName                    string `json:\"vnetName,omitempty\"`\n\tSubnetName                  string `json:\"subnetName,omitempty\"`\n\tRouteTableName              string `json:\"routeTableName,omitempty\"`\n\tSecurityGroupName           string `json:\"securityGroupName,omitempty\"`\n\tUseInstanceMetadata         bool   `json:\"useInstanceMetadata,omitempty\"`\n\tDisableAvailabilitySetNodes bool   `json:\"disableAvailabilitySetNodes,omitempty\"`\n}\n\n// BuildCloudConfig assembles the Azure cloud provider configuration for a\n// cluster. kOps publishes the result in the azure-cloud-provider Secret, which\n// the cloud-controller-manager and CSI drivers load via the\n// --cloud-config-secret-name flag.\nfunc BuildCloudConfig(cluster *kops.Cluster) (*CloudConfig, error) {\n\tazure := cluster.Spec.CloudProvider.Azure\n\tif azure == nil {\n\t\treturn nil, fmt.Errorf(\"cluster is not an Azure cluster\")\n\t}\n\n\tsubnets := cluster.Spec.Networking.Subnets\n\tif len(subnets) == 0 {\n\t\treturn nil, fmt.Errorf(\"cluster has no subnets\")\n\t}\n\n\t// In kOps the virtual network and the network security group share a name.\n\tnetworkName := cluster.AzureNetworkSecurityGroupName()\n\n\treturn &CloudConfig{\n\t\tTenantID:                    azure.TenantID,\n\t\tSubscriptionID:              azure.SubscriptionID,\n\t\tUseManagedIdentityExtension: true,\n\t\tResourceGroup:               cluster.AzureResourceGroupName(),\n\t\tLocation:                    subnets[0].Region,\n\t\tVnetName:                    networkName,\n\t\tSubnetName:                  subnets[0].Name,","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/cloudconfig.go#L34-L70","documentation":"BuildCloudConfig validates that cluster.Spec.CloudProvider.Azure is non-nil before assembling the Azure cloud-controller-manager/CSI cloud-config. It throws \"cluster is not an Azure cluster\" when the cluster's cloudProvider block targets another provider (AWS, GCP, etc.) or is absent, so there is no Azure configuration to publish into the azure-cloud-provider Secret.","triggerScenarios":"BuildCloudConfig(cluster) called during cluster rendering (via AzureCloudConfig or an anonymous builder hook) on a kops.Cluster whose Spec.CloudProvider.Azure is nil — i.e. the cluster spec has no Azure cloud provider section.","commonSituations":"Calling an Azure-only build path on an AWS/GCP/DigitalOcean cluster; a cluster spec missing the cloudProvider block entirely; wiring a generic cloudconfig builder to the Azure implementation; tooling/scripts invoking BuildCloudConfig directly with the wrong cluster manifest.","solutions":["Ensure the cluster spec actually sets cloudProvider: azure (kops edit cluster / spec file) before building Azure cloud config","Route BuildCloudConfig only from Azure-specific code paths; guard generic callers with a cloudProvider check","Verify you are operating on the intended cluster manifest (right --name / state store)","Check that the CloudProvider field is populated after loading/validating the cluster (apply defaulting/validation if constructing specs programmatically)"],"exampleFix":"// before\nBuildCloudConfig(awsCluster) // panics path: azure == nil -> error\n// after\nif cluster.Spec.CloudProvider.Azure != nil {\n    cfg, err := BuildCloudConfig(cluster)\n    ...\n}","handlingStrategy":"validation","validationCode":"// Guard the call site: only build Azure cloud config for Azure clusters\nif cluster.Spec.CloudProvider.Azure == nil {\n    return nil // or use the provider-appropriate cloud config builder\n}\ncfg, err := BuildCloudConfig(cluster)\nif err != nil { return err }","typeGuard":"func isAzureCluster(c *kops.Cluster) bool {\n    return c != nil && c.Spec.CloudProvider.Azure != nil\n}","tryCatchPattern":null,"preventionTips":["Dispatch cloud-config building on cluster.Spec.CloudProvider type instead of hardcoding Azure","Validate cluster specs (kops toolkit validate) so cloudProvider is always set before rendering","Keep one cluster manifest per operation; verify --name/state store target the right cluster","When constructing kops.Cluster programmatically, always populate CloudProvider before calling builders"],"tags":["azure","cluster-config","validation","cloud-provider"],"backgroundTag":"wrong-cloud-provider","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}