diff --git a/k8s/crds/kops.k8s.io_instancegroups.yaml b/k8s/crds/kops.k8s.io_instancegroups.yaml index a39656afc2..50336d4d45 100644 --- a/k8s/crds/kops.k8s.io_instancegroups.yaml +++ b/k8s/crds/kops.k8s.io_instancegroups.yaml @@ -695,6 +695,10 @@ spec: NOTE: This setting applies only to the Launch Configuration and does not affect Launch Templates.' type: boolean + rootVolumeEncryption: + description: RootVolumeEncryption enables EBS root volume encryption + for an instance + type: boolean rootVolumeIops: description: If volume type is io1, then we need to specify the number of Iops. diff --git a/pkg/apis/kops/instancegroup.go b/pkg/apis/kops/instancegroup.go index 27665f66ae..8f7e35299e 100644 --- a/pkg/apis/kops/instancegroup.go +++ b/pkg/apis/kops/instancegroup.go @@ -106,6 +106,8 @@ type InstanceGroupSpec struct { // The root volume is deleted by default. Cluster deletion does not remove retained root volumes. // NOTE: This setting applies only to the Launch Configuration and does not affect Launch Templates. RootVolumeDeleteOnTermination *bool `json:"rootVolumeDeleteOnTermination,omitempty"` + // RootVolumeEncryption enables EBS root volume encryption for an instance + RootVolumeEncryption *bool `json:"rootVolumeEncryption,omitempty"` // Volumes is a collection of additional volumes to create for instances within this InstanceGroup Volumes []*VolumeSpec `json:"volumes,omitempty"` // VolumeMounts a collection of volume mounts diff --git a/pkg/apis/kops/v1alpha2/instancegroup.go b/pkg/apis/kops/v1alpha2/instancegroup.go index d3a055814c..017c76de58 100644 --- a/pkg/apis/kops/v1alpha2/instancegroup.go +++ b/pkg/apis/kops/v1alpha2/instancegroup.go @@ -103,6 +103,8 @@ type InstanceGroupSpec struct { // The root volume is deleted by default. Cluster deletion does not remove retained root volumes. // NOTE: This setting applies only to the Launch Configuration and does not affect Launch Templates. RootVolumeDeleteOnTermination *bool `json:"rootVolumeDeleteOnTermination,omitempty"` + // RootVolumeEncryption enables EBS root volume encryption for an instance + RootVolumeEncryption *bool `json:"rootVolumeEncryption,omitempty"` // Volumes is a collection of additional volumes to create for instances within this InstanceGroup Volumes []*VolumeSpec `json:"volumes,omitempty"` // VolumeMounts a collection of volume mounts diff --git a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go index c6878e5f80..3d84ca686e 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.conversion.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.conversion.go @@ -3307,6 +3307,7 @@ func autoConvert_v1alpha2_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *Instan out.RootVolumeIops = in.RootVolumeIops out.RootVolumeOptimization = in.RootVolumeOptimization out.RootVolumeDeleteOnTermination = in.RootVolumeDeleteOnTermination + out.RootVolumeEncryption = in.RootVolumeEncryption if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes *out = make([]*kops.VolumeSpec, len(*in)) @@ -3446,6 +3447,7 @@ func autoConvert_kops_InstanceGroupSpec_To_v1alpha2_InstanceGroupSpec(in *kops.I out.RootVolumeIops = in.RootVolumeIops out.RootVolumeOptimization = in.RootVolumeOptimization out.RootVolumeDeleteOnTermination = in.RootVolumeDeleteOnTermination + out.RootVolumeEncryption = in.RootVolumeEncryption if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes *out = make([]*VolumeSpec, len(*in)) diff --git a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go index 397dd1bd56..bee889f35c 100644 --- a/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/kops/v1alpha2/zz_generated.deepcopy.go @@ -1697,6 +1697,11 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) { *out = new(bool) **out = **in } + if in.RootVolumeEncryption != nil { + in, out := &in.RootVolumeEncryption, &out.RootVolumeEncryption + *out = new(bool) + **out = **in + } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes *out = make([]*VolumeSpec, len(*in)) diff --git a/pkg/apis/kops/zz_generated.deepcopy.go b/pkg/apis/kops/zz_generated.deepcopy.go index 5d4b3c30d5..a2b747a391 100644 --- a/pkg/apis/kops/zz_generated.deepcopy.go +++ b/pkg/apis/kops/zz_generated.deepcopy.go @@ -1863,6 +1863,11 @@ func (in *InstanceGroupSpec) DeepCopyInto(out *InstanceGroupSpec) { *out = new(bool) **out = **in } + if in.RootVolumeEncryption != nil { + in, out := &in.RootVolumeEncryption, &out.RootVolumeEncryption + *out = new(bool) + **out = **in + } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes *out = make([]*VolumeSpec, len(*in)) diff --git a/pkg/model/awsmodel/autoscalinggroup.go b/pkg/model/awsmodel/autoscalinggroup.go index 8156f54a2a..3530d234ff 100644 --- a/pkg/model/awsmodel/autoscalinggroup.go +++ b/pkg/model/awsmodel/autoscalinggroup.go @@ -128,6 +128,7 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.ModelBuilde RootVolumeSize: lc.RootVolumeSize, RootVolumeIops: lc.RootVolumeIops, RootVolumeType: lc.RootVolumeType, + RootVolumeEncryption: lc.RootVolumeEncryption, SSHKey: lc.SSHKey, SecurityGroups: lc.SecurityGroups, Tags: tags, @@ -199,6 +200,7 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchConfigurationTask(c *fi.ModelB RootVolumeOptimization: ig.Spec.RootVolumeOptimization, RootVolumeSize: fi.Int64(int64(volumeSize)), RootVolumeType: fi.String(volumeType), + RootVolumeEncryption: ig.Spec.RootVolumeEncryption, SecurityGroups: []*awstasks.SecurityGroup{sgLink}, } diff --git a/tests/integration/update_cluster/complex/cloudformation.json b/tests/integration/update_cluster/complex/cloudformation.json index 6288c9c3a5..9e40b2886e 100644 --- a/tests/integration/update_cluster/complex/cloudformation.json +++ b/tests/integration/update_cluster/complex/cloudformation.json @@ -226,7 +226,8 @@ "Ebs": { "VolumeType": "gp2", "VolumeSize": 64, - "DeleteOnTermination": true + "DeleteOnTermination": true, + "Encrypted": true } }, { @@ -336,7 +337,8 @@ "Ebs": { "VolumeType": "gp2", "VolumeSize": 128, - "DeleteOnTermination": true + "DeleteOnTermination": true, + "Encrypted": true } }, { diff --git a/tests/integration/update_cluster/complex/in-legacy-v1alpha2.yaml b/tests/integration/update_cluster/complex/in-legacy-v1alpha2.yaml index b976067dfa..d9f1182bec 100644 --- a/tests/integration/update_cluster/complex/in-legacy-v1alpha2.yaml +++ b/tests/integration/update_cluster/complex/in-legacy-v1alpha2.yaml @@ -86,6 +86,7 @@ spec: - us-test-1a detailedInstanceMonitoring: true rootVolumeDeleteOnTermination: false + rootVolumeEncryption: true volumes: - device: /dev/xvdd deleteOnTermination: false @@ -114,6 +115,7 @@ spec: maxSize: 1 minSize: 1 role: Master + rootVolumeEncryption: true subnets: - us-test-1a additionalUserData: diff --git a/tests/integration/update_cluster/complex/in-v1alpha2.yaml b/tests/integration/update_cluster/complex/in-v1alpha2.yaml index 279bb8705e..9386163c96 100644 --- a/tests/integration/update_cluster/complex/in-v1alpha2.yaml +++ b/tests/integration/update_cluster/complex/in-v1alpha2.yaml @@ -86,6 +86,7 @@ spec: - us-test-1a detailedInstanceMonitoring: true rootVolumeDeleteOnTermination: false + rootVolumeEncryption: true volumes: - device: /dev/xvdd deleteOnTermination: false @@ -114,6 +115,7 @@ spec: maxSize: 1 minSize: 1 role: Master + rootVolumeEncryption: true subnets: - us-test-1a additionalUserData: diff --git a/tests/integration/update_cluster/complex/kubernetes.tf b/tests/integration/update_cluster/complex/kubernetes.tf index ab2a130c3b..6f962b158f 100644 --- a/tests/integration/update_cluster/complex/kubernetes.tf +++ b/tests/integration/update_cluster/complex/kubernetes.tf @@ -293,6 +293,7 @@ resource "aws_launch_template" "master-us-test-1a-masters-complex-example-com" { device_name = "/dev/xvda" ebs { delete_on_termination = true + encrypted = true volume_size = 64 volume_type = "gp2" } @@ -356,6 +357,7 @@ resource "aws_launch_template" "nodes-complex-example-com" { device_name = "/dev/xvda" ebs { delete_on_termination = true + encrypted = true volume_size = 128 volume_type = "gp2" } diff --git a/upup/pkg/fi/cloudup/awstasks/launchconfiguration.go b/upup/pkg/fi/cloudup/awstasks/launchconfiguration.go index c6fdbc56c3..7e1a5ba4e3 100644 --- a/upup/pkg/fi/cloudup/awstasks/launchconfiguration.go +++ b/upup/pkg/fi/cloudup/awstasks/launchconfiguration.go @@ -80,6 +80,8 @@ type LaunchConfiguration struct { RootVolumeSize *int64 // RootVolumeType is the type of the EBS root volume to use (e.g. gp2) RootVolumeType *string + // RootVolumeEncryption enables EBS root volume encryption for an instance + RootVolumeEncryption *bool // SSHKey is the ssh key for the instances SSHKey *SSHKey // SecurityGroups is a list of security group associated @@ -201,6 +203,7 @@ func (e *LaunchConfiguration) Find(c *fi.Context) (*LaunchConfiguration, error) actual.RootVolumeSize = b.Ebs.VolumeSize actual.RootVolumeType = b.Ebs.VolumeType actual.RootVolumeIops = b.Ebs.Iops + actual.RootVolumeEncryption = b.Ebs.Encrypted actual.RootVolumeDeleteOnTermination = b.Ebs.DeleteOnTermination } else { _, d := BlockDeviceMappingFromAutoscaling(b) @@ -386,6 +389,7 @@ func (t *LaunchConfiguration) buildRootDevice(cloud awsup.AWSCloud) (map[string] EbsVolumeSize: t.RootVolumeSize, EbsVolumeType: t.RootVolumeType, EbsVolumeIops: t.RootVolumeIops, + EbsEncrypted: t.RootVolumeEncryption, } return bm, nil diff --git a/upup/pkg/fi/cloudup/awstasks/launchtemplate.go b/upup/pkg/fi/cloudup/awstasks/launchtemplate.go index 9a8a95507c..d841538b42 100644 --- a/upup/pkg/fi/cloudup/awstasks/launchtemplate.go +++ b/upup/pkg/fi/cloudup/awstasks/launchtemplate.go @@ -57,6 +57,8 @@ type LaunchTemplate struct { RootVolumeSize *int64 // RootVolumeType is the type of the EBS root volume to use (e.g. gp2) RootVolumeType *string + // RootVolumeEncryption enables EBS root volume encryption for an instance + RootVolumeEncryption *bool // SSHKey is the ssh key for the instances SSHKey *SSHKey // SecurityGroups is a list of security group associated @@ -113,6 +115,7 @@ func (t *LaunchTemplate) buildRootDevice(cloud awsup.AWSCloud) (map[string]*Bloc EbsVolumeSize: t.RootVolumeSize, EbsVolumeType: t.RootVolumeType, EbsVolumeIops: t.RootVolumeIops, + EbsEncrypted: t.RootVolumeEncryption, } return bm, nil diff --git a/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_api.go b/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_api.go index ff9c07d41e..5ecd642d61 100644 --- a/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_api.go +++ b/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_api.go @@ -231,6 +231,7 @@ func (t *LaunchTemplate) Find(c *fi.Context) (*LaunchTemplate, error) { actual.RootVolumeSize = b.Ebs.VolumeSize actual.RootVolumeType = b.Ebs.VolumeType actual.RootVolumeIops = b.Ebs.Iops + actual.RootVolumeEncryption = b.Ebs.Encrypted } else { _, d := BlockDeviceMappingFromLaunchTemplateBootDeviceRequest(b) actual.BlockDeviceMappings = append(actual.BlockDeviceMappings, d) diff --git a/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_cloudformation.go b/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_cloudformation.go index c621f75c2b..c419d68f1c 100644 --- a/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_cloudformation.go +++ b/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_cloudformation.go @@ -234,6 +234,7 @@ func (t *LaunchTemplate) RenderCloudformation(target *cloudformation.Cloudformat IOPS: x.EbsVolumeIops, VolumeSize: x.EbsVolumeSize, VolumeType: x.EbsVolumeType, + Encrypted: x.EbsEncrypted, }, }) } diff --git a/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_terraform.go b/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_terraform.go index 08f4deba7a..ac2af71c09 100644 --- a/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_terraform.go +++ b/upup/pkg/fi/cloudup/awstasks/launchtemplate_target_terraform.go @@ -245,6 +245,7 @@ func (t *LaunchTemplate) RenderTerraform(target *terraform.TerraformTarget, a, e EBS: []*terraformLaunchTemplateBlockDeviceEBS{ { DeleteOnTermination: fi.Bool(true), + Encrypted: x.EbsEncrypted, IOPS: x.EbsVolumeIops, VolumeSize: x.EbsVolumeSize, VolumeType: x.EbsVolumeType,