Skip to content

Commit 1c956d2

Browse files
committed
Add non root volumes to AWSMachinePool
1 parent 63c6635 commit 1c956d2

File tree

8 files changed

+145
-5
lines changed

8 files changed

+145
-5
lines changed

config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,50 @@ spec:
738738
name:
739739
description: The name of the launch template.
740740
type: string
741+
nonRootVolumes:
742+
description: Configuration options for the non root storage volumes.
743+
items:
744+
description: Volume encapsulates the configuration options for
745+
the storage device.
746+
properties:
747+
deviceName:
748+
description: Device name
749+
type: string
750+
encrypted:
751+
description: Encrypted is whether the volume should be encrypted
752+
or not.
753+
type: boolean
754+
encryptionKey:
755+
description: |-
756+
EncryptionKey is the KMS key to use to encrypt the volume. Can be either a KMS key ID or ARN.
757+
If Encrypted is set and this is omitted, the default AWS key will be used.
758+
The key must already exist and be accessible by the controller.
759+
type: string
760+
iops:
761+
description: IOPS is the number of IOPS requested for the
762+
disk. Not applicable to all types.
763+
format: int64
764+
type: integer
765+
size:
766+
description: |-
767+
Size specifies size (in Gi) of the storage device.
768+
Must be greater than the image snapshot size or 8 (whichever is greater).
769+
format: int64
770+
minimum: 8
771+
type: integer
772+
throughput:
773+
description: Throughput to provision in MiB/s supported
774+
for the volume type. Not applicable to all types.
775+
format: int64
776+
type: integer
777+
type:
778+
description: Type is the type of the volume (e.g. gp2, io1,
779+
etc...).
780+
type: string
781+
required:
782+
- size
783+
type: object
784+
type: array
741785
privateDnsName:
742786
description: PrivateDNSName is the options for the instance hostname.
743787
properties:

config/crd/bases/infrastructure.cluster.x-k8s.io_awsmanagedmachinepools.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,50 @@ spec:
730730
name:
731731
description: The name of the launch template.
732732
type: string
733+
nonRootVolumes:
734+
description: Configuration options for the non root storage volumes.
735+
items:
736+
description: Volume encapsulates the configuration options for
737+
the storage device.
738+
properties:
739+
deviceName:
740+
description: Device name
741+
type: string
742+
encrypted:
743+
description: Encrypted is whether the volume should be encrypted
744+
or not.
745+
type: boolean
746+
encryptionKey:
747+
description: |-
748+
EncryptionKey is the KMS key to use to encrypt the volume. Can be either a KMS key ID or ARN.
749+
If Encrypted is set and this is omitted, the default AWS key will be used.
750+
The key must already exist and be accessible by the controller.
751+
type: string
752+
iops:
753+
description: IOPS is the number of IOPS requested for the
754+
disk. Not applicable to all types.
755+
format: int64
756+
type: integer
757+
size:
758+
description: |-
759+
Size specifies size (in Gi) of the storage device.
760+
Must be greater than the image snapshot size or 8 (whichever is greater).
761+
format: int64
762+
minimum: 8
763+
type: integer
764+
throughput:
765+
description: Throughput to provision in MiB/s supported
766+
for the volume type. Not applicable to all types.
767+
format: int64
768+
type: integer
769+
type:
770+
description: Type is the type of the volume (e.g. gp2, io1,
771+
etc...).
772+
type: string
773+
required:
774+
- size
775+
type: object
776+
type: array
733777
privateDnsName:
734778
description: PrivateDNSName is the options for the instance hostname.
735779
properties:

exp/api/v1beta1/conversion.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ package v1beta1
1818

1919
import (
2020
apiconversion "k8s.io/apimachinery/pkg/conversion"
21+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
22+
"sigs.k8s.io/controller-runtime/pkg/conversion"
23+
2124
infrav1beta1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta1"
2225
infrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
2326
infrav1exp "sigs.k8s.io/cluster-api-provider-aws/v2/exp/api/v1beta2"
24-
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
25-
"sigs.k8s.io/controller-runtime/pkg/conversion"
2627
)
2728

2829
// ConvertTo converts the v1beta1 AWSMachinePool receiver to a v1beta2 AWSMachinePool.
@@ -56,6 +57,7 @@ func (src *AWSMachinePool) ConvertTo(dstRaw conversion.Hub) error {
5657
}
5758

5859
dst.Spec.DefaultInstanceWarmup = restored.Spec.DefaultInstanceWarmup
60+
dst.Spec.AWSLaunchTemplate.NonRootVolumes = restored.Spec.AWSLaunchTemplate.NonRootVolumes
5961

6062
return nil
6163
}
@@ -101,6 +103,7 @@ func (src *AWSManagedMachinePool) ConvertTo(dstRaw conversion.Hub) error {
101103
dst.Spec.AWSLaunchTemplate = restored.Spec.AWSLaunchTemplate
102104
}
103105
dst.Spec.AWSLaunchTemplate.InstanceMetadataOptions = restored.Spec.AWSLaunchTemplate.InstanceMetadataOptions
106+
dst.Spec.AWSLaunchTemplate.NonRootVolumes = restored.Spec.AWSLaunchTemplate.NonRootVolumes
104107

105108
if restored.Spec.AWSLaunchTemplate.PrivateDNSName != nil {
106109
dst.Spec.AWSLaunchTemplate.PrivateDNSName = restored.Spec.AWSLaunchTemplate.PrivateDNSName

exp/api/v1beta1/zz_generated.conversion.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exp/api/v1beta2/awsmachinepool_webhook.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,31 @@ func (r *AWSMachinePool) validateRootVolume() field.ErrorList {
8282
return allErrs
8383
}
8484

85+
func (r *AWSMachinePool) validateNonRootVolumes() field.ErrorList {
86+
var allErrs field.ErrorList
87+
88+
for _, volume := range r.Spec.AWSLaunchTemplate.NonRootVolumes {
89+
if v1beta2.VolumeTypesProvisioned.Has(string(volume.Type)) && volume.IOPS == 0 {
90+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.iops"), "iops required if type is 'io1' or 'io2'"))
91+
}
92+
93+
if volume.Throughput != nil {
94+
if volume.Type != v1beta2.VolumeTypeGP3 {
95+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.throughput"), "throughput is valid only for type 'gp3'"))
96+
}
97+
if *volume.Throughput < 0 {
98+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.throughput"), "throughput must be nonnegative"))
99+
}
100+
}
101+
102+
if volume.DeviceName == "" {
103+
allErrs = append(allErrs, field.Required(field.NewPath("spec.template.spec.nonRootVolumes.deviceName"), "non root volume should have device name"))
104+
}
105+
}
106+
107+
return allErrs
108+
}
109+
85110
func (r *AWSMachinePool) validateSubnets() field.ErrorList {
86111
var allErrs field.ErrorList
87112

@@ -124,6 +149,7 @@ func (r *AWSMachinePool) ValidateCreate() (admission.Warnings, error) {
124149

125150
allErrs = append(allErrs, r.validateDefaultCoolDown()...)
126151
allErrs = append(allErrs, r.validateRootVolume()...)
152+
allErrs = append(allErrs, r.validateNonRootVolumes()...)
127153
allErrs = append(allErrs, r.Spec.AdditionalTags.Validate()...)
128154
allErrs = append(allErrs, r.validateSubnets()...)
129155
allErrs = append(allErrs, r.validateAdditionalSecurityGroups()...)

exp/api/v1beta2/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ type AWSLaunchTemplate struct {
9696
// +optional
9797
RootVolume *infrav1.Volume `json:"rootVolume,omitempty"`
9898

99+
// Configuration options for the non root storage volumes.
100+
// +optional
101+
NonRootVolumes []infrav1.Volume `json:"nonRootVolumes,omitempty"`
102+
99103
// SSHKeyName is the name of the ssh key to attach to the instance. Valid values are empty string
100104
// (do not use SSH keys), a valid SSH key name, or omitted (use the default SSH key name)
101105
// +optional

exp/api/v1beta2/zz_generated.deepcopy.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cloud/services/ec2/launchtemplate.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,8 @@ func (s *Service) createLaunchTemplateData(scope scope.LaunchTemplateScope, imag
520520
data.InstanceMarketOptions = getLaunchTemplateInstanceMarketOptionsRequest(scope.GetLaunchTemplate().SpotMarketOptions)
521521
data.PrivateDnsNameOptions = getLaunchTemplatePrivateDNSNameOptionsRequest(scope.GetLaunchTemplate().PrivateDNSName)
522522

523+
blockDeviceMappings := []*ec2.LaunchTemplateBlockDeviceMappingRequest{}
524+
523525
// Set up root volume
524526
if lt.RootVolume != nil {
525527
rootDeviceName, err := s.checkRootVolume(lt.RootVolume, *data.ImageId)
@@ -530,9 +532,18 @@ func (s *Service) createLaunchTemplateData(scope scope.LaunchTemplateScope, imag
530532
lt.RootVolume.DeviceName = aws.StringValue(rootDeviceName)
531533

532534
req := volumeToLaunchTemplateBlockDeviceMappingRequest(lt.RootVolume)
533-
data.BlockDeviceMappings = []*ec2.LaunchTemplateBlockDeviceMappingRequest{
534-
req,
535-
}
535+
blockDeviceMappings = append(blockDeviceMappings, req)
536+
}
537+
538+
for vi := range lt.NonRootVolumes {
539+
nonRootVolume := lt.NonRootVolumes[vi]
540+
541+
blockDeviceMapping := volumeToLaunchTemplateBlockDeviceMappingRequest(&nonRootVolume)
542+
blockDeviceMappings = append(blockDeviceMappings, blockDeviceMapping)
543+
}
544+
545+
if len(blockDeviceMappings) > 0 {
546+
data.BlockDeviceMappings = blockDeviceMappings
536547
}
537548

538549
data.TagSpecifications = s.buildLaunchTemplateTagSpecificationRequest(scope, userDataSecretKey)

0 commit comments

Comments
 (0)