Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resource/aws_eks_node_group: Add launch_template configuration block #14639

Merged
merged 1 commit into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 106 additions & 2 deletions aws/resource_aws_eks_node_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,36 @@ func resourceAwsEksNodeGroup() *schema.Resource {
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"launch_template": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"launch_template.0.name"},
ValidateFunc: validateLaunchTemplateId,
},
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UpdateNodegroupVersion API currently returns an error if the name changes. 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah i guess that's what they meant in You can update a node group using a launch template only if the node group was originally deployed with a launch template...on first pass, wording here made it seem like a launch template could mean the presence of 1 not necessarily the same one used at creation time

ConflictsWith: []string{"launch_template.0.id"},
ValidateFunc: validateLaunchTemplateName,
},
"version": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringLenBetween(1, 255),
},
},
},
},
"node_group_name": {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -213,6 +243,10 @@ func resourceAwsEksNodeGroupCreate(d *schema.ResourceData, meta interface{}) err
input.Labels = stringMapToPointers(v)
}

if v := d.Get("launch_template").([]interface{}); len(v) > 0 {
input.LaunchTemplate = expandEksLaunchTemplateSpecification(v)
}

if v, ok := d.GetOk("release_version"); ok {
input.ReleaseVersion = aws.String(v.(string))
}
Expand Down Expand Up @@ -303,6 +337,10 @@ func resourceAwsEksNodeGroupRead(d *schema.ResourceData, meta interface{}) error
return fmt.Errorf("error setting labels: %s", err)
}

if err := d.Set("launch_template", flattenEksLaunchTemplateSpecification(nodeGroup.LaunchTemplate)); err != nil {
return fmt.Errorf("error setting launch_template: %s", err)
}

d.Set("node_group_name", nodeGroup.NodegroupName)
d.Set("node_role_arn", nodeGroup.NodeRole)
d.Set("release_version", nodeGroup.ReleaseVersion)
Expand Down Expand Up @@ -374,19 +412,39 @@ func resourceAwsEksNodeGroupUpdate(d *schema.ResourceData, meta interface{}) err
}
}

if d.HasChanges("release_version", "version") {
if d.HasChanges("launch_template", "release_version", "version") {
input := &eks.UpdateNodegroupVersionInput{
ClientRequestToken: aws.String(resource.UniqueId()),
ClusterName: aws.String(clusterName),
Force: aws.Bool(d.Get("force_update_version").(bool)),
NodegroupName: aws.String(nodeGroupName),
}

if v := d.Get("launch_template").([]interface{}); len(v) > 0 {
input.LaunchTemplate = expandEksLaunchTemplateSpecification(v)

// When returning Launch Template information, the API returns all
// fields. Since both the id and name are saved to the Terraform
// state for drift detection and the API returns the following
// error if both are present during update:
// InvalidParameterException: Either provide launch template ID or launch template name in the request.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will reach out to the EKS service team to see if they can remove this restriction.


// Remove the name if there are no changes, to prefer the ID.
if input.LaunchTemplate.Id != nil && input.LaunchTemplate.Name != nil && !d.HasChange("launch_template.0.name") {
input.LaunchTemplate.Name = nil
}

// Otherwise, remove the ID, but only if both are present still.
if input.LaunchTemplate.Id != nil && input.LaunchTemplate.Name != nil && !d.HasChange("launch_template.0.id") {
input.LaunchTemplate.Id = nil
}
}

if v, ok := d.GetOk("release_version"); ok && d.HasChange("release_version") {
input.ReleaseVersion = aws.String(v.(string))
}

if v, ok := d.GetOk("version"); ok {
if v, ok := d.GetOk("version"); ok && d.HasChange("version") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UpdateNodegroupVersion API does not allow specifying the Kubernetes version when Launch Templates are being updated, however we save it in state for drift detection so its present during update here. This follows the similar conditional as above to prevent the error, unless there is an errant configuration change by an operator.

Copy link
Contributor

@anGie44 anGie44 Aug 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, my only follow-up to this would be if we need to check for !d.HasChange("launch_template") here along with the check for changes in version to satisfy the condition that the "API does not allow specifying the Kubernetes version when Launch Templates are being updated" since we're still inside the outer if d.HasChanges("launch_template", "release_version", "version") at this point? an example i'm thinking is in the case where a node group version is updated/rolled-back to a previous one and the launch_template version also changes. though I'm not certain if that's a valid condition..

Copy link
Contributor

@anGie44 anGie44 Aug 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah i see TestAccAWSEksNodeGroup_LaunchTemplate_Version would cover something similar in Step#3...at first i didn't catch it's the instance_type arg in the launch_template resource that causes changes downstream 👍

input.Version = aws.String(v.(string))
}

Expand Down Expand Up @@ -448,6 +506,30 @@ func resourceAwsEksNodeGroupDelete(d *schema.ResourceData, meta interface{}) err
return nil
}

func expandEksLaunchTemplateSpecification(l []interface{}) *eks.LaunchTemplateSpecification {
if len(l) == 0 || l[0] == nil {
return nil
}

m := l[0].(map[string]interface{})

config := &eks.LaunchTemplateSpecification{}

if v, ok := m["id"].(string); ok && v != "" {
config.Id = aws.String(v)
}

if v, ok := m["name"].(string); ok && v != "" {
config.Name = aws.String(v)
}

if v, ok := m["version"].(string); ok && v != "" {
config.Version = aws.String(v)
}

return config
}

func expandEksNodegroupScalingConfig(l []interface{}) *eks.NodegroupScalingConfig {
if len(l) == 0 || l[0] == nil {
return nil
Expand Down Expand Up @@ -535,6 +617,28 @@ func flattenEksAutoScalingGroups(autoScalingGroups []*eks.AutoScalingGroup) []ma
return l
}

func flattenEksLaunchTemplateSpecification(config *eks.LaunchTemplateSpecification) []map[string]interface{} {
if config == nil {
return nil
}

m := map[string]interface{}{}

if v := config.Id; v != nil {
m["id"] = aws.StringValue(v)
}

if v := config.Name; v != nil {
m["name"] = aws.StringValue(v)
}

if v := config.Version; v != nil {
m["version"] = aws.StringValue(v)
}

return []map[string]interface{}{m}
}

func flattenEksNodeGroupResources(resources *eks.NodegroupResources) []map[string]interface{} {
if resources == nil {
return []map[string]interface{}{}
Expand Down
Loading