From da761798b7095e5357564ec4837860d25a59cd09 Mon Sep 17 00:00:00 2001 From: Aditya Narayanaswamy Date: Tue, 24 Feb 2026 13:08:17 -0500 Subject: [PATCH] azure: Disallow cross subscription encryption sets Since CAPZ does not support using encryption sets in a subscription not in the current subscription, adding a validation to return error if the subscriptions don't match. --- .../install.openshift.io_installconfigs.yaml | 16 +++++----- pkg/asset/installconfig/azure/client.go | 4 ++- pkg/asset/installconfig/installconfig.go | 31 +++++++++++++++++++ pkg/types/azure/disk.go | 3 ++ pkg/types/azure/validation/disk.go | 3 -- 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/data/data/install.openshift.io_installconfigs.yaml b/data/data/install.openshift.io_installconfigs.yaml index b287fd6f861..dfc7b3bd424 100644 --- a/data/data/install.openshift.io_installconfigs.yaml +++ b/data/data/install.openshift.io_installconfigs.yaml @@ -478,11 +478,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object diskSizeGB: description: DiskSizeGB defines the size of disk in GB. @@ -522,11 +522,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object securityEncryptionType: description: |- @@ -2039,11 +2039,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object diskSizeGB: description: DiskSizeGB defines the size of disk in @@ -2084,11 +2084,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object securityEncryptionType: description: |- @@ -3538,11 +3538,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object diskSizeGB: description: DiskSizeGB defines the size of disk in GB. @@ -3582,11 +3582,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object securityEncryptionType: description: |- @@ -5505,11 +5505,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object diskSizeGB: description: DiskSizeGB defines the size of disk in GB. @@ -5549,11 +5549,11 @@ spec: description: |- SubscriptionID defines the Azure subscription the disk encryption set is in. + Must be the same subscription ID as the resource group of the installer. type: string required: - name - resourceGroup - - subscriptionId type: object securityEncryptionType: description: |- diff --git a/pkg/asset/installconfig/azure/client.go b/pkg/asset/installconfig/azure/client.go index a8c2d2b0904..74a014d8607 100644 --- a/pkg/asset/installconfig/azure/client.go +++ b/pkg/asset/installconfig/azure/client.go @@ -318,6 +318,9 @@ func (c *Client) GetVirtualMachineSku(ctx context.Context, name, region string) // GetDiskEncryptionSet retrieves the specified disk encryption set. func (c *Client) GetDiskEncryptionSet(ctx context.Context, subscriptionID, groupName, diskEncryptionSetName string) (*azenc.DiskEncryptionSet, error) { + if strings.EqualFold(c.ssn.Credentials.SubscriptionID, subscriptionID) { + return nil, fmt.Errorf("different subscription from resource group subscription. Azure does not support cross subscription encryption sets") + } client := azenc.NewDiskEncryptionSetsClientWithBaseURI(c.ssn.Environment.ResourceManagerEndpoint, subscriptionID) client.Authorizer = c.ssn.Authorizer ctx, cancel := context.WithTimeout(ctx, 30*time.Second) @@ -327,7 +330,6 @@ func (c *Client) GetDiskEncryptionSet(ctx context.Context, subscriptionID, group if err != nil { return nil, fmt.Errorf("failed to get disk encryption set: %w", err) } - return &diskEncryptionSet, nil } diff --git a/pkg/asset/installconfig/installconfig.go b/pkg/asset/installconfig/installconfig.go index 00fd2ce00c4..db7553d9f7c 100644 --- a/pkg/asset/installconfig/installconfig.go +++ b/pkg/asset/installconfig/installconfig.go @@ -165,6 +165,34 @@ func (a *InstallConfig) finishGCP() error { return nil } +// finishAzure set defaults for Azure platform. +func (a *InstallConfig) finishAzure() error { + defaultConfig := a.Config.Azure.DefaultMachinePlatform + session, err := a.Azure.Session() + if err != nil { + return err + } + if defaultConfig != nil && defaultConfig.OSDisk.DiskEncryptionSet != nil && + defaultConfig.OSDisk.DiskEncryptionSet.SubscriptionID == "" { + a.Config.Azure.DefaultMachinePlatform.OSDisk.SubscriptionID = session.Credentials.SubscriptionID + } + + if a.Config.ControlPlane != nil && a.Config.ControlPlane.Platform.Azure != nil && + a.Config.ControlPlane.Platform.Azure.OSDisk.DiskEncryptionSet != nil { + if a.Config.ControlPlane.Platform.Azure.OSDisk.SubscriptionID == "" { + a.Config.ControlPlane.Platform.Azure.OSDisk.SubscriptionID = session.Credentials.SubscriptionID + } + } + + for _, compute := range a.Config.Compute { + if compute.Platform.Azure != nil && compute.Platform.Azure.OSDisk.DiskEncryptionSet != nil && + compute.Platform.Azure.OSDisk.SubscriptionID == "" { + compute.Platform.Azure.OSDisk.SubscriptionID = session.Credentials.SubscriptionID + } + } + return nil +} + // finishAWS set defaults for AWS Platform before the config validation. func (a *InstallConfig) finishAWS() error { // Set the Default Edge Compute pool when the subnets in AWS Local Zones are defined, @@ -194,6 +222,9 @@ func (a *InstallConfig) finish(ctx context.Context, filename string) error { } if a.Config.Azure != nil { a.Azure = icazure.NewMetadata(a.Config.Azure, a.Config.ControlPlane, &a.Config.Compute[0]) + if err := a.finishAzure(); err != nil { + return err + } } if a.Config.GCP != nil { if err := a.finishGCP(); err != nil { diff --git a/pkg/types/azure/disk.go b/pkg/types/azure/disk.go index 0dcb87bdaa9..5b07ea8ecc3 100644 --- a/pkg/types/azure/disk.go +++ b/pkg/types/azure/disk.go @@ -50,6 +50,9 @@ type OSDisk struct { type DiskEncryptionSet struct { // SubscriptionID defines the Azure subscription the disk encryption // set is in. + // Must be the same subscription ID as the resource group of the installer. + // + // +optional SubscriptionID string `json:"subscriptionId"` // ResourceGroup defines the Azure resource group used by the disk // encryption set. diff --git a/pkg/types/azure/validation/disk.go b/pkg/types/azure/validation/disk.go index 179e4f9ee91..56a89542aee 100644 --- a/pkg/types/azure/validation/disk.go +++ b/pkg/types/azure/validation/disk.go @@ -31,9 +31,6 @@ func ValidateDiskEncryption(p *azure.MachinePool, cloudName azure.CloudEnvironme if diskEncryptionSet != nil && cloudName == azure.StackCloud { return append(allErrs, field.Invalid(childFldPath.Child("diskEncryptionSet"), diskEncryptionSet, "disk encryption sets are not supported on this platform")) } - if diskEncryptionSet.SubscriptionID == "" { - return append(allErrs, field.Required(childFldPath.Child("subscriptionID"), "subscription ID is required")) - } if !RxSubscriptionID.MatchString(diskEncryptionSet.SubscriptionID) { return append(allErrs, field.Invalid(childFldPath.Child("subscriptionID"), diskEncryptionSet.SubscriptionID, "invalid subscription ID format")) }