Skip to content

Commit 7cc0810

Browse files
authored
resource/aws_eks_node_group: Add capacity_type argument and support multiple instance_types (#16510)
Output from acceptance testing (see #16146 for unrelated failure triage on the main branch): ``` --- FAIL: TestAccAWSEksNodeGroup_LaunchTemplate_Version (2588.15s) --- FAIL: TestAccAWSEksNodeGroup_ReleaseVersion (4116.90s) --- PASS: TestAccAWSEksNodeGroup_AmiType (1739.66s) --- PASS: TestAccAWSEksNodeGroup_basic (1263.54s) --- PASS: TestAccAWSEksNodeGroup_CapacityType_Spot (1397.33s) --- PASS: TestAccAWSEksNodeGroup_disappears (1359.08s) --- PASS: TestAccAWSEksNodeGroup_DiskSize (1284.23s) --- PASS: TestAccAWSEksNodeGroup_ForceUpdateVersion (5320.15s) --- PASS: TestAccAWSEksNodeGroup_InstanceTypes_Multiple (1232.97s) --- PASS: TestAccAWSEksNodeGroup_InstanceTypes_Single (1490.11s) --- PASS: TestAccAWSEksNodeGroup_Labels (1268.53s) --- PASS: TestAccAWSEksNodeGroup_LaunchTemplate_Id (1711.11s) --- PASS: TestAccAWSEksNodeGroup_LaunchTemplate_Name (1661.18s) --- PASS: TestAccAWSEksNodeGroup_RemoteAccess_Ec2SshKey (1292.95s) --- PASS: TestAccAWSEksNodeGroup_RemoteAccess_SourceSecurityGroupIds (1306.54s) --- PASS: TestAccAWSEksNodeGroup_ScalingConfig_DesiredSize (1189.50s) --- PASS: TestAccAWSEksNodeGroup_ScalingConfig_MaxSize (1358.88s) --- PASS: TestAccAWSEksNodeGroup_ScalingConfig_MinSize (1428.47s) --- PASS: TestAccAWSEksNodeGroup_Tags (1366.22s) --- PASS: TestAccAWSEksNodeGroup_Version (5252.66s) ```
1 parent f0bbb99 commit 7cc0810

3 files changed

Lines changed: 142 additions & 10 deletions

File tree

aws/resource_aws_eks_node_group.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ func resourceAwsEksNodeGroup() *schema.Resource {
4747
Type: schema.TypeString,
4848
Computed: true,
4949
},
50+
"capacity_type": {
51+
Type: schema.TypeString,
52+
Optional: true,
53+
ForceNew: true,
54+
Default: eks.CapacityTypesOnDemand,
55+
ValidateFunc: validation.StringInSlice(eks.CapacityTypes_Values(), false),
56+
},
5057
"cluster_name": {
5158
Type: schema.TypeString,
5259
Required: true,
@@ -68,9 +75,6 @@ func resourceAwsEksNodeGroup() *schema.Resource {
6875
Optional: true,
6976
Computed: true,
7077
ForceNew: true,
71-
// Multiple instance types returns an API error currently:
72-
// InvalidParameterException: Instance type list not valid, only one instance type is supported!
73-
MaxItems: 1,
7478
Elem: &schema.Schema{Type: schema.TypeString},
7579
},
7680
"labels": {
@@ -232,6 +236,10 @@ func resourceAwsEksNodeGroupCreate(d *schema.ResourceData, meta interface{}) err
232236
input.AmiType = aws.String(v.(string))
233237
}
234238

239+
if v, ok := d.GetOk("capacity_type"); ok {
240+
input.CapacityType = aws.String(v.(string))
241+
}
242+
235243
if v, ok := d.GetOk("disk_size"); ok {
236244
input.DiskSize = aws.Int64(int64(v.(int)))
237245
}
@@ -327,6 +335,7 @@ func resourceAwsEksNodeGroupRead(d *schema.ResourceData, meta interface{}) error
327335

328336
d.Set("ami_type", nodeGroup.AmiType)
329337
d.Set("arn", nodeGroup.NodegroupArn)
338+
d.Set("capacity_type", nodeGroup.CapacityType)
330339
d.Set("cluster_name", nodeGroup.ClusterName)
331340
d.Set("disk_size", nodeGroup.DiskSize)
332341

aws/resource_aws_eks_node_group_test.go

Lines changed: 128 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ func TestAccAWSEksNodeGroup_basic(t *testing.T) {
9696
resource.TestCheckResourceAttr(resourceName, "ami_type", eks.AMITypesAl2X8664),
9797
testAccMatchResourceAttrRegionalARN(resourceName, "arn", "eks", regexp.MustCompile(fmt.Sprintf("nodegroup/%[1]s/%[1]s/.+", rName))),
9898
resource.TestCheckResourceAttrPair(resourceName, "cluster_name", eksClusterResourceName, "name"),
99+
resource.TestCheckResourceAttr(resourceName, "capacity_type", eks.CapacityTypesOnDemand),
99100
resource.TestCheckResourceAttr(resourceName, "disk_size", "20"),
100101
resource.TestCheckResourceAttr(resourceName, "instance_types.#", "1"),
101102
resource.TestCheckResourceAttr(resourceName, "labels.%", "0"),
@@ -179,6 +180,32 @@ func TestAccAWSEksNodeGroup_AmiType(t *testing.T) {
179180
})
180181
}
181182

183+
func TestAccAWSEksNodeGroup_CapacityType_Spot(t *testing.T) {
184+
var nodeGroup1 eks.Nodegroup
185+
rName := acctest.RandomWithPrefix("tf-acc-test")
186+
resourceName := "aws_eks_node_group.test"
187+
188+
resource.ParallelTest(t, resource.TestCase{
189+
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEks(t) },
190+
Providers: testAccProviders,
191+
CheckDestroy: testAccCheckAWSEksNodeGroupDestroy,
192+
Steps: []resource.TestStep{
193+
{
194+
Config: testAccAWSEksNodeGroupConfigCapacityType(rName, eks.CapacityTypesSpot),
195+
Check: resource.ComposeTestCheckFunc(
196+
testAccCheckAWSEksNodeGroupExists(resourceName, &nodeGroup1),
197+
resource.TestCheckResourceAttr(resourceName, "capacity_type", eks.CapacityTypesSpot),
198+
),
199+
},
200+
{
201+
ResourceName: resourceName,
202+
ImportState: true,
203+
ImportStateVerify: true,
204+
},
205+
},
206+
})
207+
}
208+
182209
func TestAccAWSEksNodeGroup_DiskSize(t *testing.T) {
183210
var nodeGroup1 eks.Nodegroup
184211
rName := acctest.RandomWithPrefix("tf-acc-test")
@@ -239,9 +266,10 @@ func TestAccAWSEksNodeGroup_ForceUpdateVersion(t *testing.T) {
239266
})
240267
}
241268

242-
func TestAccAWSEksNodeGroup_InstanceTypes(t *testing.T) {
269+
func TestAccAWSEksNodeGroup_InstanceTypes_Multiple(t *testing.T) {
243270
var nodeGroup1 eks.Nodegroup
244271
rName := acctest.RandomWithPrefix("tf-acc-test")
272+
ec2InstanceTypeOfferingsDataSourceName := "data.aws_ec2_instance_type_offerings.available"
245273
resourceName := "aws_eks_node_group.test"
246274

247275
resource.ParallelTest(t, resource.TestCase{
@@ -250,7 +278,33 @@ func TestAccAWSEksNodeGroup_InstanceTypes(t *testing.T) {
250278
CheckDestroy: testAccCheckAWSEksNodeGroupDestroy,
251279
Steps: []resource.TestStep{
252280
{
253-
Config: testAccAWSEksNodeGroupConfigInstanceTypes1(rName, "t3.large"),
281+
Config: testAccAWSEksNodeGroupConfigInstanceTypesMultiple(rName),
282+
Check: resource.ComposeTestCheckFunc(
283+
testAccCheckAWSEksNodeGroupExists(resourceName, &nodeGroup1),
284+
resource.TestCheckResourceAttrPair(resourceName, "instance_types.#", ec2InstanceTypeOfferingsDataSourceName, "instance_types.#"),
285+
),
286+
},
287+
{
288+
ResourceName: resourceName,
289+
ImportState: true,
290+
ImportStateVerify: true,
291+
},
292+
},
293+
})
294+
}
295+
296+
func TestAccAWSEksNodeGroup_InstanceTypes_Single(t *testing.T) {
297+
var nodeGroup1 eks.Nodegroup
298+
rName := acctest.RandomWithPrefix("tf-acc-test")
299+
resourceName := "aws_eks_node_group.test"
300+
301+
resource.ParallelTest(t, resource.TestCase{
302+
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEks(t) },
303+
Providers: testAccProviders,
304+
CheckDestroy: testAccCheckAWSEksNodeGroupDestroy,
305+
Steps: []resource.TestStep{
306+
{
307+
Config: testAccAWSEksNodeGroupConfigInstanceTypesSingle(rName),
254308
Check: resource.ComposeTestCheckFunc(
255309
testAccCheckAWSEksNodeGroupExists(resourceName, &nodeGroup1),
256310
resource.TestCheckResourceAttr(resourceName, "instance_types.#", "1"),
@@ -1051,6 +1105,30 @@ resource "aws_eks_node_group" "test" {
10511105
`, rName, amiType)
10521106
}
10531107

1108+
func testAccAWSEksNodeGroupConfigCapacityType(rName, capacityType string) string {
1109+
return testAccAWSEksNodeGroupConfigBase(rName) + fmt.Sprintf(`
1110+
resource "aws_eks_node_group" "test" {
1111+
capacity_type = %[2]q
1112+
cluster_name = aws_eks_cluster.test.name
1113+
node_group_name = %[1]q
1114+
node_role_arn = aws_iam_role.node.arn
1115+
subnet_ids = aws_subnet.test[*].id
1116+
1117+
scaling_config {
1118+
desired_size = 1
1119+
max_size = 1
1120+
min_size = 1
1121+
}
1122+
1123+
depends_on = [
1124+
"aws_iam_role_policy_attachment.node-AmazonEKSWorkerNodePolicy",
1125+
"aws_iam_role_policy_attachment.node-AmazonEKS_CNI_Policy",
1126+
"aws_iam_role_policy_attachment.node-AmazonEC2ContainerRegistryReadOnly",
1127+
]
1128+
}
1129+
`, rName, capacityType)
1130+
}
1131+
10541132
func testAccAWSEksNodeGroupConfigDiskSize(rName string, diskSize int) string {
10551133
return testAccAWSEksNodeGroupConfigBase(rName) + fmt.Sprintf(`
10561134
resource "aws_eks_node_group" "test" {
@@ -1100,11 +1178,55 @@ resource "aws_eks_node_group" "test" {
11001178
`, rName)
11011179
}
11021180

1103-
func testAccAWSEksNodeGroupConfigInstanceTypes1(rName, instanceType1 string) string {
1104-
return testAccAWSEksNodeGroupConfigBase(rName) + fmt.Sprintf(`
1181+
func testAccAWSEksNodeGroupConfigInstanceTypesMultiple(rName string) string {
1182+
return composeConfig(
1183+
testAccAWSEksNodeGroupConfigBase(rName),
1184+
fmt.Sprintf(`
1185+
data "aws_ec2_instance_type_offerings" "available" {
1186+
filter {
1187+
name = "instance-type"
1188+
values = ["t3.medium", "t3.large", "t2.medium", "t2.large"]
1189+
}
1190+
}
1191+
1192+
resource "aws_eks_node_group" "test" {
1193+
cluster_name = aws_eks_cluster.test.name
1194+
instance_types = data.aws_ec2_instance_type_offerings.available.instance_types
1195+
node_group_name = %[1]q
1196+
node_role_arn = aws_iam_role.node.arn
1197+
subnet_ids = aws_subnet.test[*].id
1198+
1199+
scaling_config {
1200+
desired_size = 1
1201+
max_size = 1
1202+
min_size = 1
1203+
}
1204+
1205+
depends_on = [
1206+
"aws_iam_role_policy_attachment.node-AmazonEKSWorkerNodePolicy",
1207+
"aws_iam_role_policy_attachment.node-AmazonEKS_CNI_Policy",
1208+
"aws_iam_role_policy_attachment.node-AmazonEC2ContainerRegistryReadOnly",
1209+
]
1210+
}
1211+
`, rName))
1212+
}
1213+
1214+
func testAccAWSEksNodeGroupConfigInstanceTypesSingle(rName string) string {
1215+
return composeConfig(
1216+
testAccAWSEksNodeGroupConfigBase(rName),
1217+
fmt.Sprintf(`
1218+
data "aws_ec2_instance_type_offering" "available" {
1219+
filter {
1220+
name = "instance-type"
1221+
values = ["t3.large", "t2.large"]
1222+
}
1223+
1224+
preferred_instance_types = ["t3.large", "t2.large"]
1225+
}
1226+
11051227
resource "aws_eks_node_group" "test" {
11061228
cluster_name = aws_eks_cluster.test.name
1107-
instance_types = [%[2]q]
1229+
instance_types = [data.aws_ec2_instance_type_offering.available.instance_type]
11081230
node_group_name = %[1]q
11091231
node_role_arn = aws_iam_role.node.arn
11101232
subnet_ids = aws_subnet.test[*].id
@@ -1121,7 +1243,7 @@ resource "aws_eks_node_group" "test" {
11211243
"aws_iam_role_policy_attachment.node-AmazonEC2ContainerRegistryReadOnly",
11221244
]
11231245
}
1124-
`, rName, instanceType1)
1246+
`, rName))
11251247
}
11261248

11271249
func testAccAWSEksNodeGroupConfigLabels1(rName, labelKey1, labelValue1 string) string {

website/docs/r/eks_node_group.html.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,10 @@ The following arguments are required:
124124
The following arguments are optional:
125125

126126
* `ami_type` - (Optional) Type of Amazon Machine Image (AMI) associated with the EKS Node Group. Defaults to `AL2_x86_64`. Valid values: `AL2_x86_64`, `AL2_x86_64_GPU`, `AL2_ARM_64`. Terraform will only perform drift detection if a configuration value is provided.
127+
* `capacity_type` - (Optional) Type of capacity associated with the EKS Node Group. Defaults to `ON_DEMAND`. Valid values: `ON_DEMAND`, `SPOT`.
127128
* `disk_size` - (Optional) Disk size in GiB for worker nodes. Defaults to `20`. Terraform will only perform drift detection if a configuration value is provided.
128129
* `force_update_version` - (Optional) Force version update if existing pods are unable to be drained due to a pod disruption budget issue.
129-
* `instance_types` - (Optional) Set of instance types associated with the EKS Node Group. Defaults to `["t3.medium"]`. Terraform will only perform drift detection if a configuration value is provided. Currently, the EKS API only accepts a single value in the set.
130+
* `instance_types` - (Optional) List of instance types associated with the EKS Node Group. Defaults to `["t3.medium"]`. Terraform will only perform drift detection if a configuration value is provided.
130131
* `labels` - (Optional) Key-value map of Kubernetes labels. Only labels that are applied with the EKS API are managed by this argument. Other Kubernetes labels applied to the EKS Node Group will not be managed.
131132
* `launch_template` - (Optional) Configuration block with Launch Template settings. Detailed below.
132133
* `release_version` – (Optional) AMI version of the EKS Node Group. Defaults to latest version for Kubernetes version.

0 commit comments

Comments
 (0)