Skip to content

Commit

Permalink
Merge pull request #2525 from dlipovetsky/dlipovetsky/prune-launchtem…
Browse files Browse the repository at this point in the history
…plateversion

🐛 AWSMachinePool: Prune old Launch Template versions
  • Loading branch information
k8s-ci-robot committed Jun 22, 2021
2 parents b555916 + 9c8e025 commit 6297c7d
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
5 changes: 5 additions & 0 deletions exp/controllers/awsmachinepool_controller.go
Expand Up @@ -455,6 +455,11 @@ func (r *AWSMachinePoolReconciler) reconcileLaunchTemplate(machinePoolScope *sco
// userdata, OR we've discovered a new AMI ID.
if needsUpdate || tagsChanged || *imageID != *launchTemplate.AMI.ID || launchTemplateUserDataHash != bootstrapDataHash {
machinePoolScope.Info("creating new version for launch template", "existing", launchTemplate, "incoming", machinePoolScope.AWSMachinePool.Spec.AWSLaunchTemplate)
// There is a limit to the number of Launch Template Versions.
// We ensure that the number of versions does not grow without bound by following a simple rule: Before we create a new version, we delete one old version, if there is at least one old version that is not in use.
if err := ec2svc.PruneLaunchTemplateVersions(machinePoolScope.AWSMachinePool.Status.LaunchTemplateID); err != nil {
return err
}
if err := ec2svc.CreateLaunchTemplateVersion(machinePoolScope, imageID, bootstrapData); err != nil {
return err
}
Expand Down
58 changes: 58 additions & 0 deletions pkg/cloud/services/ec2/launchtemplate.go
Expand Up @@ -20,6 +20,7 @@ import (
"encoding/base64"
"reflect"
"sort"
"strconv"
"strings"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -245,6 +246,63 @@ func (s *Service) DeleteLaunchTemplate(id string) error {
return nil
}

// PruneLaunchTemplateVersions deletes one old launch template version.
// It does not delete the "latest" version, because that version may still be in use.
// It does not delete the "default" version, because that version cannot be deleted.
// It does not assume that versions are sequential. Versions may be deleted out of band.
func (s *Service) PruneLaunchTemplateVersions(id string) error {
// When there is one version available, it is the default and the latest.
// When there are two versions available, one the is the default, the other is the latest.
// Therefore we only prune when there are at least 3 versions available.
const minCountToAllowPrune = 3

input := &ec2.DescribeLaunchTemplateVersionsInput{
LaunchTemplateId: aws.String(id),
MinVersion: aws.String("0"),
MaxVersion: aws.String(expinfrav1.LaunchTemplateLatestVersion),
MaxResults: aws.Int64(minCountToAllowPrune),
}

out, err := s.EC2Client.DescribeLaunchTemplateVersions(input)
if err != nil {
s.scope.Info("", "aerr", err.Error())
return err
}

// len(out.LaunchTemplateVersions) | items
// -------------------------------- + -----------------------
// 1 | [default/latest]
// 2 | [default, latest]
// 3 | [default, versionToPrune, latest]
if len(out.LaunchTemplateVersions) < minCountToAllowPrune {
return nil
}
versionToPrune := out.LaunchTemplateVersions[1].VersionNumber
return s.deleteLaunchTemplateVersion(id, versionToPrune)
}

func (s *Service) deleteLaunchTemplateVersion(id string, version *int64) error {
s.scope.V(2).Info("Deleting launch template version", "id", id)

if version == nil {
return errors.New("version is a nil pointer")
}
versions := []string{strconv.FormatInt(*version, 10)}

input := &ec2.DeleteLaunchTemplateVersionsInput{
LaunchTemplateId: aws.String(id),
Versions: aws.StringSlice(versions),
}

_, err := s.EC2Client.DeleteLaunchTemplateVersions(input)
if err != nil {
return err
}

s.scope.V(2).Info("Deleted launch template", "id", id, "version", *version)
return nil
}

// SDKToLaunchTemplate converts an AWS EC2 SDK instance to the CAPA instance type.
func (s *Service) SDKToLaunchTemplate(d *ec2.LaunchTemplateVersion) (*expinfrav1.AWSLaunchTemplate, string, error) {
v := d.LaunchTemplateData
Expand Down
1 change: 1 addition & 0 deletions pkg/cloud/services/interfaces.go
Expand Up @@ -64,6 +64,7 @@ type EC2MachineInterface interface {
GetLaunchTemplateID(id string) (string, error)
CreateLaunchTemplate(scope *scope.MachinePoolScope, imageID *string, userData []byte) (string, error)
CreateLaunchTemplateVersion(scope *scope.MachinePoolScope, imageID *string, userData []byte) error
PruneLaunchTemplateVersions(id string) error
DeleteLaunchTemplate(id string) error
LaunchTemplateNeedsUpdate(scope *scope.MachinePoolScope, incoming *expinfrav1.AWSLaunchTemplate, existing *expinfrav1.AWSLaunchTemplate) (bool, error)
}
Expand Down
14 changes: 14 additions & 0 deletions pkg/cloud/services/mock_services/ec2_machine_interface_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6297c7d

Please sign in to comment.