Skip to content

Commit 081b579

Browse files
committed
Support SEV_SNP instance type configuration
Only SEV machines could be configured by using the former confidentialCompute Enabled/Disabled. GCP allows now to also configure the confidential instance type as well by using the appropriate parameter, see [0]. This commit enables passing confidential instance type values to the confidentialCompute field. "Enable" will keep just turning the GCP EnableConfidentialCompute flag to true, while relying on GCP's compute API's mechanisms to choose a confidential computing technology [1]. AMDEncryptedVirtualization and AMDEncryptedVirtualizationNestedPaging will now also be supported and apart from setting EnableConfidentialCompute to true, they will configure the confidential instance type to be AMD SEV or AMD SEV-SNP repectively. Meanwhile, add c3d as a machine that supports AMD SEV. [0] https://cloud.google.com/confidential-computing/confidential-vm/docs/create-a-confidential-vm-instance#rest [1] https://pkg.go.dev/google.golang.org/[email protected]/compute/v1#ConfidentialInstanceConfig
1 parent f24b413 commit 081b579

File tree

8 files changed

+376
-13
lines changed

8 files changed

+376
-13
lines changed

api/v1beta1/gcpmachine_types.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,18 @@ const (
135135
ConfidentialComputePolicyEnabled ConfidentialComputePolicy = "Enabled"
136136
// ConfidentialComputePolicyDisabled disables confidential compute for the GCP machine.
137137
ConfidentialComputePolicyDisabled ConfidentialComputePolicy = "Disabled"
138+
// ConfidentialComputePolicySEV sets AMD SEV as the VM instance's confidential computing technology of choice.
139+
ConfidentialComputePolicySEV ConfidentialComputePolicy = "AMDEncrytedVirtualization"
140+
// ConfidentialComputePolicySEVSNP sets AMD SEV-SNP as the VM instance's confidential computing technology of choice.
141+
ConfidentialComputePolicySEVSNP ConfidentialComputePolicy = "AMDEncrytedVirtualizationNestedPaging"
138142
)
139143

140-
// Confidential VM supports Compute Engine machine types in the following series:
144+
// Confidential VM Technology support depends on the configured machine types.
141145
// reference: https://cloud.google.com/compute/confidential-vm/docs/os-and-machine-type#machine-type
142-
var confidentialComputeSupportedMachineSeries = []string{"n2d", "c2d"}
146+
var (
147+
confidentialMachineSeriesSupportingSev = []string{"n2d", "c2d", "c3d"}
148+
confidentialMachineSeriesSupportingSevsnp = []string{"n2d"}
149+
)
143150

144151
// HostMaintenancePolicy represents the desired behavior ase of a host maintenance event.
145152
type HostMaintenancePolicy string
@@ -336,10 +343,14 @@ type GCPMachineSpec struct {
336343
// +optional
337344
OnHostMaintenance *HostMaintenancePolicy `json:"onHostMaintenance,omitempty"`
338345

339-
// ConfidentialCompute Defines whether the instance should have confidential compute enabled.
340-
// If enabled OnHostMaintenance is required to be set to "Terminate".
346+
// ConfidentialCompute Defines whether the instance should have confidential compute enabled or not, and the confidential computing technology of choice.
347+
// If Disabled, the machine will not be configured to be a confidential computing instance.
348+
// If Enabled, confidential computing will be configured and AMD Secure Encrypted Virtualization will be configured by default. That is subject to change over time. If using AMD Secure Encrypted Virtualization is vital, use AMDEncryptedVirtualization explicitly instead.
349+
// If AMDEncryptedVirtualization, it will configure AMD Secure Encrypted Virtualization (AMD SEV) as the confidential computing technology.
350+
// If AMDEncryptedVirtualizationNestedPaging, it will configure AMD Secure Encrypted Virtualization Secure Nested Paging (AMD SEV-SNP) as the confidential computing technology.
351+
// If enabled (any value other than Disabled) OnHostMaintenance is required to be set to "Terminate".
341352
// If omitted, the platform chooses a default, which is subject to change over time, currently that default is false.
342-
// +kubebuilder:validation:Enum=Enabled;Disabled
353+
// +kubebuilder:validation:Enum=Enabled;Disabled;AMDEncrytedVirtualization;AMDEncrytedVirtualizationNestedPaging
343354
// +optional
344355
ConfidentialCompute *ConfidentialComputePolicy `json:"confidentialCompute,omitempty"`
345356

api/v1beta1/gcpmachine_webhook.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,23 @@ func (m *GCPMachine) Default() {
109109
}
110110

111111
func validateConfidentialCompute(spec GCPMachineSpec) error {
112-
if spec.ConfidentialCompute != nil && *spec.ConfidentialCompute == ConfidentialComputePolicyEnabled {
112+
if spec.ConfidentialCompute != nil && *spec.ConfidentialCompute != ConfidentialComputePolicyDisabled {
113113
if spec.OnHostMaintenance == nil || *spec.OnHostMaintenance == HostMaintenancePolicyMigrate {
114114
return fmt.Errorf("ConfidentialCompute require OnHostMaintenance to be set to %s, the current value is: %s", HostMaintenancePolicyTerminate, HostMaintenancePolicyMigrate)
115115
}
116116

117117
machineSeries := strings.Split(spec.InstanceType, "-")[0]
118-
if !slices.Contains(confidentialComputeSupportedMachineSeries, machineSeries) {
119-
return fmt.Errorf("ConfidentialCompute require instance type in the following series: %s", confidentialComputeSupportedMachineSeries)
118+
switch *spec.ConfidentialCompute {
119+
case ConfidentialComputePolicyEnabled, ConfidentialComputePolicySEV:
120+
if !slices.Contains(confidentialMachineSeriesSupportingSev, machineSeries) {
121+
return fmt.Errorf("ConfidentialCompute %s requires any of the following machine series: %s. %s was found instead", *spec.ConfidentialCompute, strings.Join(confidentialMachineSeriesSupportingSev, ", "), spec.InstanceType)
122+
}
123+
case ConfidentialComputePolicySEVSNP:
124+
if !slices.Contains(confidentialMachineSeriesSupportingSevsnp, machineSeries) {
125+
return fmt.Errorf("ConfidentialCompute %s requires any of the following machine series: %s. %s was found instead", *spec.ConfidentialCompute, strings.Join(confidentialMachineSeriesSupportingSevsnp, ", "), spec.InstanceType)
126+
}
127+
default:
128+
return fmt.Errorf("invalid ConfidentialCompute %s", *spec.ConfidentialCompute)
120129
}
121130
}
122131
return nil

api/v1beta1/gcpmachine_webhook_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import (
2525
func TestGCPMachine_ValidateCreate(t *testing.T) {
2626
g := NewWithT(t)
2727
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
28+
confidentialComputeSEV := ConfidentialComputePolicySEV
29+
confidentialComputeSEVSNP := ConfidentialComputePolicySEVSNP
30+
confidentialComputeFooBar := ConfidentialComputePolicy("foobar")
2831
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
2932
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
3033
tests := []struct {
@@ -85,6 +88,83 @@ func TestGCPMachine_ValidateCreate(t *testing.T) {
8588
},
8689
wantErr: true,
8790
},
91+
{
92+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and supported instance type - valid",
93+
GCPMachine: &GCPMachine{
94+
Spec: GCPMachineSpec{
95+
InstanceType: "c3d-standard-4",
96+
ConfidentialCompute: &confidentialComputeSEV,
97+
OnHostMaintenance: &onHostMaintenanceTerminate,
98+
},
99+
},
100+
wantErr: false,
101+
},
102+
{
103+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and unsupported instance type - invalid",
104+
GCPMachine: &GCPMachine{
105+
Spec: GCPMachineSpec{
106+
InstanceType: "e2-standard-4",
107+
ConfidentialCompute: &confidentialComputeSEV,
108+
OnHostMaintenance: &onHostMaintenanceTerminate,
109+
},
110+
},
111+
wantErr: true,
112+
},
113+
{
114+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualization and OnHostMaintenance Migrate - invalid",
115+
GCPMachine: &GCPMachine{
116+
Spec: GCPMachineSpec{
117+
InstanceType: "c2d-standard-4",
118+
ConfidentialCompute: &confidentialComputeSEV,
119+
OnHostMaintenance: &onHostMaintenanceMigrate,
120+
},
121+
},
122+
wantErr: true,
123+
},
124+
{
125+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and supported instance type - valid",
126+
GCPMachine: &GCPMachine{
127+
Spec: GCPMachineSpec{
128+
InstanceType: "n2d-standard-4",
129+
ConfidentialCompute: &confidentialComputeSEVSNP,
130+
OnHostMaintenance: &onHostMaintenanceTerminate,
131+
},
132+
},
133+
wantErr: false,
134+
},
135+
{
136+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and unsupported instance type - invalid",
137+
GCPMachine: &GCPMachine{
138+
Spec: GCPMachineSpec{
139+
InstanceType: "e2-standard-4",
140+
ConfidentialCompute: &confidentialComputeSEVSNP,
141+
OnHostMaintenance: &onHostMaintenanceTerminate,
142+
},
143+
},
144+
wantErr: true,
145+
},
146+
{
147+
name: "GCPMachine with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and OnHostMaintenance Migrate - invalid",
148+
GCPMachine: &GCPMachine{
149+
Spec: GCPMachineSpec{
150+
InstanceType: "n2d-standard-4",
151+
ConfidentialCompute: &confidentialComputeSEVSNP,
152+
OnHostMaintenance: &onHostMaintenanceMigrate,
153+
},
154+
},
155+
wantErr: true,
156+
},
157+
{
158+
name: "GCPMachine with ConfidentialCompute foobar - invalid",
159+
GCPMachine: &GCPMachine{
160+
Spec: GCPMachineSpec{
161+
InstanceType: "n2d-standard-4",
162+
ConfidentialCompute: &confidentialComputeFooBar,
163+
OnHostMaintenance: &onHostMaintenanceTerminate,
164+
},
165+
},
166+
wantErr: true,
167+
},
88168
{
89169
name: "GCPMachine with RootDiskEncryptionKey KeyType Managed and Managed field set",
90170
GCPMachine: &GCPMachine{

api/v1beta1/gcpmachinetemplate_webhook_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
2626
g := NewWithT(t)
2727
confidentialComputeEnabled := ConfidentialComputePolicyEnabled
28+
confidentialComputeSEV := ConfidentialComputePolicySEV
29+
confidentialComputeSEVSNP := ConfidentialComputePolicySEVSNP
2830
onHostMaintenanceTerminate := HostMaintenancePolicyTerminate
2931
onHostMaintenanceMigrate := HostMaintenancePolicyMigrate
3032
tests := []struct {
@@ -105,6 +107,96 @@ func TestGCPMachineTemplate_ValidateCreate(t *testing.T) {
105107
},
106108
wantErr: true,
107109
},
110+
{
111+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and unsupported instance type - invalid",
112+
template: &GCPMachineTemplate{
113+
Spec: GCPMachineTemplateSpec{
114+
Template: GCPMachineTemplateResource{
115+
Spec: GCPMachineSpec{
116+
InstanceType: "e2-standard-4",
117+
ConfidentialCompute: &confidentialComputeSEV,
118+
OnHostMaintenance: &onHostMaintenanceTerminate,
119+
},
120+
},
121+
},
122+
},
123+
wantErr: true,
124+
},
125+
{
126+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and supported instance type - valid",
127+
template: &GCPMachineTemplate{
128+
Spec: GCPMachineTemplateSpec{
129+
Template: GCPMachineTemplateResource{
130+
Spec: GCPMachineSpec{
131+
InstanceType: "c2d-standard-4",
132+
ConfidentialCompute: &confidentialComputeSEV,
133+
OnHostMaintenance: &onHostMaintenanceTerminate,
134+
},
135+
},
136+
},
137+
},
138+
wantErr: false,
139+
},
140+
{
141+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualization and OnHostMaintenance Migrate - invalid",
142+
template: &GCPMachineTemplate{
143+
Spec: GCPMachineTemplateSpec{
144+
Template: GCPMachineTemplateResource{
145+
Spec: GCPMachineSpec{
146+
InstanceType: "c2d-standard-4",
147+
ConfidentialCompute: &confidentialComputeSEV,
148+
OnHostMaintenance: &onHostMaintenanceMigrate,
149+
},
150+
},
151+
},
152+
},
153+
wantErr: true,
154+
},
155+
{
156+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and unsupported instance type - invalid",
157+
template: &GCPMachineTemplate{
158+
Spec: GCPMachineTemplateSpec{
159+
Template: GCPMachineTemplateResource{
160+
Spec: GCPMachineSpec{
161+
InstanceType: "c2d-standard-4",
162+
ConfidentialCompute: &confidentialComputeSEVSNP,
163+
OnHostMaintenance: &onHostMaintenanceTerminate,
164+
},
165+
},
166+
},
167+
},
168+
wantErr: true,
169+
},
170+
{
171+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and supported instance type - valid",
172+
template: &GCPMachineTemplate{
173+
Spec: GCPMachineTemplateSpec{
174+
Template: GCPMachineTemplateResource{
175+
Spec: GCPMachineSpec{
176+
InstanceType: "n2d-standard-4",
177+
ConfidentialCompute: &confidentialComputeSEVSNP,
178+
OnHostMaintenance: &onHostMaintenanceTerminate,
179+
},
180+
},
181+
},
182+
},
183+
wantErr: false,
184+
},
185+
{
186+
name: "GCPMachineTemplate with ConfidentialCompute AMDEncryptedVirtualizationNestedPaging and OnHostMaintenance Migrate - invalid",
187+
template: &GCPMachineTemplate{
188+
Spec: GCPMachineTemplateSpec{
189+
Template: GCPMachineTemplateResource{
190+
Spec: GCPMachineSpec{
191+
InstanceType: "c2d-standard-4",
192+
ConfidentialCompute: &confidentialComputeSEVSNP,
193+
OnHostMaintenance: &onHostMaintenanceMigrate,
194+
},
195+
},
196+
},
197+
},
198+
wantErr: true,
199+
},
108200
}
109201
for _, test := range tests {
110202
t.Run(test.name, func(t *testing.T) {

cloud/scope/machine.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,10 +446,17 @@ func (m *MachineScope) InstanceSpec(log logr.Logger) *compute.Instance {
446446
instance.Scheduling.OnHostMaintenance = strings.ToUpper(string(*m.GCPMachine.Spec.OnHostMaintenance))
447447
}
448448
if m.GCPMachine.Spec.ConfidentialCompute != nil {
449-
enabled := *m.GCPMachine.Spec.ConfidentialCompute == infrav1.ConfidentialComputePolicyEnabled
449+
enabled := *m.GCPMachine.Spec.ConfidentialCompute != infrav1.ConfidentialComputePolicyDisabled
450450
instance.ConfidentialInstanceConfig = &compute.ConfidentialInstanceConfig{
451451
EnableConfidentialCompute: enabled,
452452
}
453+
switch *m.GCPMachine.Spec.ConfidentialCompute {
454+
case infrav1.ConfidentialComputePolicySEV:
455+
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV"
456+
case infrav1.ConfidentialComputePolicySEVSNP:
457+
instance.ConfidentialInstanceConfig.ConfidentialInstanceType = "SEV_SNP"
458+
default:
459+
}
453460
}
454461

455462
instance.Disks = append(instance.Disks, m.InstanceImageSpec())

0 commit comments

Comments
 (0)