Skip to content

Commit

Permalink
Upgrade nodegroup ASG to LaunchTemplate
Browse files Browse the repository at this point in the history
  • Loading branch information
errordeveloper committed Apr 18, 2019
1 parent d187db2 commit 0ffff8c
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 45 deletions.
85 changes: 57 additions & 28 deletions pkg/cfn/builder/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,20 @@ type Template struct {
Resource interface{}
}
}
BlockDeviceMappings []interface{}
VPCZoneIdentifier interface{}
AssociatePublicIpAddress bool
CidrIp string
CidrIpv6 string
IpProtocol string
FromPort int
ToPort int
LaunchTemplateData struct {
UserData string
BlockDeviceMappings []interface{}
NetworkInterfaces []struct {
AssociatePublicIpAddress bool
}
}
VPCZoneIdentifier interface{}

CidrIp string
CidrIpv6 string
IpProtocol string
FromPort int
ToPort int
}
}
}
Expand Down Expand Up @@ -672,9 +678,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should have correct policies", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

Expect(obj.Resources).To(HaveKey("NodeLaunchConfig"))
Expect(obj.Resources["NodeLaunchConfig"].Properties.BlockDeviceMappings).To(HaveLen(0))
Expect(obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.BlockDeviceMappings).To(HaveLen(0))

Expect(obj.Resources).To(HaveKey("PolicyEBS"))
Expect(obj.Resources["PolicyEBS"].Properties.PolicyDocument.Statement).To(HaveLen(1))
Expand Down Expand Up @@ -714,9 +720,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should have correct policies", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

Expect(obj.Resources).To(HaveKey("NodeLaunchConfig"))
Expect(obj.Resources["NodeLaunchConfig"].Properties.BlockDeviceMappings).To(HaveLen(0))
Expect(obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.BlockDeviceMappings).To(HaveLen(0))

Expect(obj.Resources).To(HaveKey("PolicyFSX"))
Expect(obj.Resources["PolicyFSX"].Properties.PolicyDocument.Statement).To(HaveLen(1))
Expand Down Expand Up @@ -745,9 +751,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should have correct policies", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

Expect(obj.Resources).To(HaveKey("NodeLaunchConfig"))
Expect(obj.Resources["NodeLaunchConfig"].Properties.BlockDeviceMappings).To(HaveLen(0))
Expect(obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.BlockDeviceMappings).To(HaveLen(0))

Expect(obj.Resources).To(HaveKey("PolicyEFS"))
Expect(obj.Resources["PolicyEFS"].Properties.PolicyDocument.Statement).To(HaveLen(1))
Expand Down Expand Up @@ -787,6 +793,8 @@ var _ = Describe("CloudFormation template builder API", func() {
It("should have correct resources and attributes", func() {
Expect(obj.Resources).ToNot(BeEmpty())

Expect(obj.Resources).To(HaveKey("NodeGroup"))

Expect(obj.Resources["NodeGroup"].Properties.VPCZoneIdentifier).ToNot(BeNil())
x, ok := obj.Resources["NodeGroup"].Properties.VPCZoneIdentifier.(map[string]interface{})
Expect(ok).To(BeTrue())
Expand All @@ -800,19 +808,21 @@ var _ = Describe("CloudFormation template builder API", func() {
},
}
Expect(x).To(Equal(refSubnets))
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

Expect(obj.Resources).To(HaveKey("NodeLaunchConfig"))
ltd := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData

Expect(obj.Resources["NodeLaunchConfig"].Properties.BlockDeviceMappings).To(HaveLen(1))
Expect(ltd.BlockDeviceMappings).To(HaveLen(1))

rootVolume := obj.Resources["NodeLaunchConfig"].Properties.BlockDeviceMappings[0].(map[string]interface{})
rootVolume := ltd.BlockDeviceMappings[0].(map[string]interface{})

Expect(rootVolume).To(HaveKeyWithValue("DeviceName", "/dev/xvda"))
Expect(rootVolume).To(HaveKey("Ebs"))
Expect(rootVolume["Ebs"].(map[string]interface{})).To(HaveKeyWithValue("VolumeType", "io1"))
Expect(rootVolume["Ebs"].(map[string]interface{})).To(HaveKeyWithValue("VolumeSize", 2.0))

Expect(obj.Resources["NodeLaunchConfig"].Properties.AssociatePublicIpAddress).To(BeFalse())
Expect(ltd.NetworkInterfaces).To(HaveLen(1))
Expect(ltd.NetworkInterfaces[0].AssociatePublicIpAddress).To(BeFalse())

Expect(obj.Resources["SSHIPv4"].Properties.CidrIp).To(Equal("192.168.0.0/16"))
Expect(obj.Resources["SSHIPv4"].Properties.FromPort).To(Equal(22))
Expand Down Expand Up @@ -844,6 +854,7 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should have correct resources and attributes", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroup"))

Expect(obj.Resources["NodeGroup"].Properties.VPCZoneIdentifier).ToNot(BeNil())
x, ok := obj.Resources["NodeGroup"].Properties.VPCZoneIdentifier.(map[string]interface{})
Expand All @@ -859,7 +870,12 @@ var _ = Describe("CloudFormation template builder API", func() {
}
Expect(x).To(Equal(refSubnets))

Expect(obj.Resources["NodeLaunchConfig"].Properties.AssociatePublicIpAddress).To(BeTrue())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

ltd := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData

Expect(ltd.NetworkInterfaces).To(HaveLen(1))
Expect(ltd.NetworkInterfaces[0].AssociatePublicIpAddress).To(BeTrue())

Expect(obj.Resources["SSHIPv4"].Properties.CidrIp).To(Equal("0.0.0.0/0"))
Expect(obj.Resources["SSHIPv4"].Properties.FromPort).To(Equal(22))
Expand Down Expand Up @@ -936,7 +952,12 @@ var _ = Describe("CloudFormation template builder API", func() {
}
Expect(x).To((Equal(refSubnets)))

Expect(obj.Resources["NodeLaunchConfig"].Properties.AssociatePublicIpAddress).To(BeTrue())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

ltd := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData

Expect(ltd.NetworkInterfaces).To(HaveLen(1))
Expect(ltd.NetworkInterfaces[0].AssociatePublicIpAddress).To(BeTrue())

Expect(obj.Resources).ToNot(HaveKey("SSHIPv4"))

Expand Down Expand Up @@ -988,8 +1009,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down Expand Up @@ -1058,8 +1080,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down Expand Up @@ -1127,8 +1150,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down Expand Up @@ -1194,8 +1218,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should parse JSON without errors and extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down Expand Up @@ -1262,8 +1287,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down Expand Up @@ -1322,8 +1348,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down Expand Up @@ -1396,8 +1423,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down Expand Up @@ -1468,8 +1496,9 @@ var _ = Describe("CloudFormation template builder API", func() {

It("should extract valid cloud-config using our implementation", func() {
Expect(obj.Resources).ToNot(BeEmpty())
Expect(obj.Resources).To(HaveKey("NodeGroupLaunchTemplate"))

userData := obj.Resources["NodeLaunchConfig"].Properties.UserData
userData := obj.Resources["NodeGroupLaunchTemplate"].Properties.LaunchTemplateData.UserData
Expect(userData).ToNot(BeEmpty())

cc, err = cloudconfig.DecodeCloudConfig(userData)
Expand Down
45 changes: 30 additions & 15 deletions pkg/cfn/builder/nodegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,33 +107,48 @@ func (n *NodeGroupResourceSet) newResource(name string, resource interface{}) *g
}

func (n *NodeGroupResourceSet) addResourcesForNodeGroup() error {
lc := &gfn.AWSAutoScalingLaunchConfiguration{
IamInstanceProfile: n.instanceProfile,
SecurityGroups: n.securityGroups,
ImageId: gfn.NewString(n.spec.AMI),
InstanceType: gfn.NewString(n.spec.InstanceType),
UserData: n.userData,
launchTemplateData := &gfn.AWSEC2LaunchTemplate_LaunchTemplateData{
IamInstanceProfile: &gfn.AWSEC2LaunchTemplate_IamInstanceProfile{
Arn: n.instanceProfile,
},
SecurityGroups: n.securityGroups,
ImageId: gfn.NewString(n.spec.AMI),
InstanceType: gfn.NewString(n.spec.InstanceType),
UserData: n.userData,
}

if api.IsEnabled(n.spec.SSH.Allow) && api.IsSetAndNonEmptyString(n.spec.SSH.PublicKeyName) {
lc.KeyName = gfn.NewString(*n.spec.SSH.PublicKeyName)
launchTemplateData.KeyName = gfn.NewString(*n.spec.SSH.PublicKeyName)
}
if n.spec.PrivateNetworking {
lc.AssociatePublicIpAddress = gfn.False()
launchTemplateData.NetworkInterfaces = []gfn.AWSEC2LaunchTemplate_NetworkInterface{
{
AssociatePublicIpAddress: gfn.False(),
},
}
} else {
lc.AssociatePublicIpAddress = gfn.True()
launchTemplateData.NetworkInterfaces = []gfn.AWSEC2LaunchTemplate_NetworkInterface{
{
AssociatePublicIpAddress: gfn.True(),
},
}
}
if n.spec.VolumeSize > 0 {
lc.BlockDeviceMappings = []gfn.AWSAutoScalingLaunchConfiguration_BlockDeviceMapping{
launchTemplateData.BlockDeviceMappings = []gfn.AWSEC2LaunchTemplate_BlockDeviceMapping{
{
DeviceName: gfn.NewString("/dev/xvda"),
Ebs: &gfn.AWSAutoScalingLaunchConfiguration_BlockDevice{
Ebs: &gfn.AWSEC2LaunchTemplate_Ebs{
VolumeSize: gfn.NewInteger(n.spec.VolumeSize),
VolumeType: gfn.NewString(n.spec.VolumeType),
},
},
}
}
refLC := n.newResource("NodeLaunchConfig", lc)
launchTemplateName := gfn.MakeFnSubString(fmt.Sprintf("${%s}", gfn.StackName))
n.newResource("NodeGroupLaunchTemplate", &gfn.AWSEC2LaunchTemplate{
LaunchTemplateName: launchTemplateName,
LaunchTemplateData: launchTemplateData,
})
// currently goformation type system doesn't allow specifying `VPCZoneIdentifier: { "Fn::ImportValue": ... }`,
// and tags don't have `PropagateAtLaunch` field, so we have a custom method here until this gets resolved
var vpcZoneIdentifier interface{}
Expand Down Expand Up @@ -190,9 +205,9 @@ func (n *NodeGroupResourceSet) addResourcesForNodeGroup() error {
)
}
ngProps := map[string]interface{}{
"LaunchConfigurationName": refLC,
"VPCZoneIdentifier": vpcZoneIdentifier,
"Tags": tags,
"LaunchTemplateName": launchTemplateName,
"VPCZoneIdentifier": vpcZoneIdentifier,
"Tags": tags, // TODO: make part of LT
}
if n.spec.DesiredCapacity != nil {
ngProps["DesiredCapacity"] = fmt.Sprintf("%d", *n.spec.DesiredCapacity)
Expand Down
4 changes: 2 additions & 2 deletions pkg/cfn/manager/nodegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const (
desiredCapacityPath = resourcesRootPath + ".NodeGroup.Properties.DesiredCapacity"
maxSizePath = resourcesRootPath + ".NodeGroup.Properties.MaxSize"
minSizePath = resourcesRootPath + ".NodeGroup.Properties.MinSize"
instanceTypePath = resourcesRootPath + ".NodeLaunchConfig.Properties.InstanceType"
imageIDPath = resourcesRootPath + ".NodeLaunchConfig.Properties.ImageId"
instanceTypePath = resourcesRootPath + ".NodeGroupLaunchTemplate.Properties.LaunchTemplateData.InstanceType"
imageIDPath = resourcesRootPath + ".NodeGroupLaunchTemplate.Properties.LaunchTemplateData.ImageId"
)

// NodeGroupSummary represents a summary of a nodegroup stack
Expand Down

0 comments on commit 0ffff8c

Please sign in to comment.