diff --git a/.changelog/37740.txt b/.changelog/37740.txt new file mode 100644 index 00000000000..021e9b4aba3 --- /dev/null +++ b/.changelog/37740.txt @@ -0,0 +1,15 @@ +```release-note:enhancement +resource/aws_emr_cluster: Support `io2` as a valid value for `ebs_config.type` +``` + +```release-note:enhancement +resource/aws_emr_instance_fleet: Support `io2` as a valid value for `instance_type_configs.ebs_config.type` +``` + +```release-note:enhancement +resource/aws_emr_instance_group: Support `io2` as a valid value for `instance_type_configs.ebs_config.type` +``` + +```release-note:bug +resource/aws_emr_instance_group: Properly send an `instance_count` value of `0` on create when configured +``` \ No newline at end of file diff --git a/internal/service/emr/instance_group.go b/internal/service/emr/instance_group.go index 36c6b3cc5cb..216ef38ab30 100644 --- a/internal/service/emr/instance_group.go +++ b/internal/service/emr/instance_group.go @@ -185,8 +185,9 @@ func resourceInstanceGroupCreate(ctx context.Context, d *schema.ResourceData, me } } - if v, ok := d.GetOk(names.AttrInstanceCount); ok { - groupConfig.InstanceCount = aws.Int32(int32(v.(int))) + if v := d.GetRawConfig().GetAttr(names.AttrInstanceCount); v.IsKnown() && !v.IsNull() { + v, _ := v.AsBigFloat().Int64() + groupConfig.InstanceCount = aws.Int32(int32(v)) } else { groupConfig.InstanceCount = aws.Int32(1) } diff --git a/internal/service/emr/instance_group_test.go b/internal/service/emr/instance_group_test.go index 2b96b3c2a0e..225619f25f8 100644 --- a/internal/service/emr/instance_group_test.go +++ b/internal/service/emr/instance_group_test.go @@ -33,11 +33,12 @@ func TestAccEMRInstanceGroup_basic(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccInstanceGroupConfig_basic(rName), - Check: resource.ComposeTestCheckFunc( + Check: resource.ComposeAggregateTestCheckFunc( testAccCheckInstanceGroupExists(ctx, resourceName, &v), resource.TestCheckResourceAttr(resourceName, "autoscaling_policy", ""), resource.TestCheckResourceAttr(resourceName, "bid_price", ""), resource.TestCheckResourceAttr(resourceName, "ebs_optimized", acctest.CtFalse), + resource.TestCheckResourceAttr(resourceName, names.AttrInstanceCount, acctest.Ct1), ), }, { @@ -258,8 +259,8 @@ func TestAccEMRInstanceGroup_autoScalingPolicy(t *testing.T) { } // Confirm we can scale down the instance count. -// Regression test for https://github.com/hashicorp/terraform-provider-aws/issues/1264 -func TestAccEMRInstanceGroup_instanceCount(t *testing.T) { +// See https://github.com/hashicorp/terraform-provider-aws/issues/1264. +func TestAccEMRInstanceGroup_instanceCountDecrease(t *testing.T) { ctx := acctest.Context(t) var v awstypes.InstanceGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -272,8 +273,11 @@ func TestAccEMRInstanceGroup_instanceCount(t *testing.T) { CheckDestroy: acctest.CheckDestroyNoop, Steps: []resource.TestStep{ { - Config: testAccInstanceGroupConfig_basic(rName), - Check: testAccCheckInstanceGroupExists(ctx, resourceName, &v), + Config: testAccInstanceGroupConfig_instanceCount(rName, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, names.AttrInstanceCount, acctest.Ct2), + ), }, { ResourceName: resourceName, @@ -283,8 +287,43 @@ func TestAccEMRInstanceGroup_instanceCount(t *testing.T) { ImportStateVerifyIgnore: []string{names.AttrStatus}, }, { - Config: testAccInstanceGroupConfig_zeroCount(rName), - Check: testAccCheckInstanceGroupExists(ctx, resourceName, &v), + Config: testAccInstanceGroupConfig_instanceCount(rName, 0), + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, names.AttrInstanceCount, acctest.Ct0), + ), + }, + }, + }) +} + +// Confirm we can create with a 0 instance count. +// See https://github.com/hashicorp/terraform-provider-aws/issues/38837. +func TestAccEMRInstanceGroup_instanceCountCreateZero(t *testing.T) { + ctx := acctest.Context(t) + var v awstypes.InstanceGroup + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_emr_instance_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EMRServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: acctest.CheckDestroyNoop, + Steps: []resource.TestStep{ + { + Config: testAccInstanceGroupConfig_instanceCount(rName, 0), + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceGroupExists(ctx, resourceName, &v), + resource.TestCheckResourceAttr(resourceName, names.AttrInstanceCount, acctest.Ct0), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccInstanceGroupResourceImportStateIdFunc(resourceName), + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{names.AttrStatus}, }, }, }) @@ -518,12 +557,12 @@ resource "aws_emr_instance_group" "test" { `, o)) } -func testAccInstanceGroupConfig_zeroCount(rName string) string { - return acctest.ConfigCompose(testAccInstanceGroupConfig_base(rName), ` +func testAccInstanceGroupConfig_instanceCount(rName string, count int) string { + return acctest.ConfigCompose(testAccInstanceGroupConfig_base(rName), fmt.Sprintf(` resource "aws_emr_instance_group" "test" { cluster_id = aws_emr_cluster.test.id - instance_count = 0 + instance_count = %[1]d instance_type = "c4.large" } -`) +`, count)) } diff --git a/internal/service/emr/managed_scaling_policy.go b/internal/service/emr/managed_scaling_policy.go index e7feb7710be..50874d65520 100644 --- a/internal/service/emr/managed_scaling_policy.go +++ b/internal/service/emr/managed_scaling_policy.go @@ -151,6 +151,7 @@ func resourceManagedScalingPolicyDelete(ctx context.Context, d *schema.ResourceD }) if tfawserr.ErrMessageContains(err, errCodeValidationException, "A job flow that is shutting down, terminated, or finished may not be modified") || + tfawserr.ErrMessageContains(err, errCodeValidationException, "is not valid") || errs.IsAErrorMessageContains[*awstypes.InvalidRequestException](err, "does not exist") { return diags } @@ -174,6 +175,7 @@ func findManagedScalingPolicy(ctx context.Context, conn *emr.Client, input *emr. output, err := conn.GetManagedScalingPolicy(ctx, input) if tfawserr.ErrMessageContains(err, errCodeValidationException, "A job flow that is shutting down, terminated, or finished may not be modified") || + tfawserr.ErrMessageContains(err, errCodeValidationException, "is not valid") || errs.IsAErrorMessageContains[*awstypes.InvalidRequestException](err, "does not exist") { return nil, &retry.NotFoundError{ LastError: err, diff --git a/internal/service/emr/validate.go b/internal/service/emr/validate.go index 8e0e4fd979a..150beb645bf 100644 --- a/internal/service/emr/validate.go +++ b/internal/service/emr/validate.go @@ -30,6 +30,7 @@ func validEBSVolumeType() schema.SchemaValidateFunc { "gp3", "gp2", "io1", + "io2", "standard", "st1", "sc1", diff --git a/website/docs/cdktf/python/r/emr_cluster.html.markdown b/website/docs/cdktf/python/r/emr_cluster.html.markdown index dbf8376c5b8..18abeb355ea 100644 --- a/website/docs/cdktf/python/r/emr_cluster.html.markdown +++ b/website/docs/cdktf/python/r/emr_cluster.html.markdown @@ -583,7 +583,7 @@ The launch specification for Spot instances in the fleet, which determines the d * `iops` - (Optional) Number of I/O operations per second (IOPS) that the volume supports. * `size` - (Required) Volume size, in gibibytes (GiB). -* `type` - (Required) Volume type. Valid options are `gp3`, `gp2`, `io1`, `standard`, `st1` and `sc1`. See [EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). +* `type` - (Required) Volume type. Valid options are `gp3`, `gp2`, `io1`, `io2`, `standard`, `st1` and `sc1`. See [EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). * `throughput` - (Optional) The throughput, in mebibyte per second (MiB/s). * `volumes_per_instance` - (Optional) Number of EBS volumes with this configuration to attach to each EC2 instance in the instance group (default is 1). diff --git a/website/docs/cdktf/typescript/r/emr_cluster.html.markdown b/website/docs/cdktf/typescript/r/emr_cluster.html.markdown index 19ddee30250..e8255616f62 100644 --- a/website/docs/cdktf/typescript/r/emr_cluster.html.markdown +++ b/website/docs/cdktf/typescript/r/emr_cluster.html.markdown @@ -757,7 +757,7 @@ The launch specification for Spot instances in the fleet, which determines the d * `iops` - (Optional) Number of I/O operations per second (IOPS) that the volume supports. * `size` - (Required) Volume size, in gibibytes (GiB). -* `type` - (Required) Volume type. Valid options are `gp3`, `gp2`, `io1`, `standard`, `st1` and `sc1`. See [EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). +* `type` - (Required) Volume type. Valid options are `gp3`, `gp2`, `io1`, `io2`, `standard`, `st1` and `sc1`. See [EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). * `throughput` - (Optional) The throughput, in mebibyte per second (MiB/s). * `volumesPerInstance` - (Optional) Number of EBS volumes with this configuration to attach to each EC2 instance in the instance group (default is 1). diff --git a/website/docs/r/emr_cluster.html.markdown b/website/docs/r/emr_cluster.html.markdown index 6ad4ecead66..6ef7c984e88 100644 --- a/website/docs/r/emr_cluster.html.markdown +++ b/website/docs/r/emr_cluster.html.markdown @@ -734,7 +734,7 @@ The launch specification for Spot instances in the fleet, which determines the d * `iops` - (Optional) Number of I/O operations per second (IOPS) that the volume supports. * `size` - (Required) Volume size, in gibibytes (GiB). -* `type` - (Required) Volume type. Valid options are `gp3`, `gp2`, `io1`, `standard`, `st1` and `sc1`. See [EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). +* `type` - (Required) Volume type. Valid options are `gp3`, `gp2`, `io1`, `io2`, `standard`, `st1` and `sc1`. See [EBS Volume Types](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html). * `throughput` - (Optional) The throughput, in mebibyte per second (MiB/s). * `volumes_per_instance` - (Optional) Number of EBS volumes with this configuration to attach to each EC2 instance in the instance group (default is 1).