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

fix: Properly normalize allocation_strategy values for aws_emr_cluster #34367

Merged
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
3 changes: 3 additions & 0 deletions .changelog/34367.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_emr_cluster: Properly normalize `launch_specifications.on_demand_specification.allocation_strategy` and `launch_specifications.spot_specification.allocation_strategy` values to fix perpetual state differences
```
12 changes: 6 additions & 6 deletions internal/service/emr/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -2082,9 +2082,9 @@ func flattenOnDemandSpecification(onDemandSpecification *emr.OnDemandProvisionin
return []interface{}{}
}
m := map[string]interface{}{
// The return value from api is wrong. it return "LOWEST_PRICE" instead of "lowest-price"
// "allocation_strategy": aws.StringValue(onDemandSpecification.AllocationStrategy),
"allocation_strategy": emr.OnDemandProvisioningAllocationStrategyLowestPrice,
// The return value from api is wrong. it return the value with uppercase letters and '_' vs. '-'
// The value needs to be normalized to avoid perpetual difference in the Terraform plan
"allocation_strategy": strings.Replace(strings.ToLower(aws.StringValue(onDemandSpecification.AllocationStrategy)), "_", "-", -1),
}
return []interface{}{m}
}
Expand All @@ -2101,9 +2101,9 @@ func flattenSpotSpecification(spotSpecification *emr.SpotProvisioningSpecificati
m["block_duration_minutes"] = aws.Int64Value(spotSpecification.BlockDurationMinutes)
}
if spotSpecification.AllocationStrategy != nil {
// The return value from api is wrong. It return "CAPACITY_OPTIMIZED" instead of "capacity-optimized"
// m["allocation_strategy"] = aws.StringValue(spotSpecification.AllocationStrategy)
m["allocation_strategy"] = emr.SpotProvisioningAllocationStrategyCapacityOptimized
// The return value from api is wrong. it return the value with uppercase letters and '_' vs. '-'
// The value needs to be normalized to avoid perpetual difference in the Terraform plan
m["allocation_strategy"] = strings.Replace(strings.ToLower(aws.StringValue(spotSpecification.AllocationStrategy)), "_", "-", -1)
}

return []interface{}{m}
Expand Down
6 changes: 5 additions & 1 deletion internal/service/emr/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1622,6 +1622,7 @@ func TestAccEMRCluster_InstanceFleet_basic(t *testing.T) {
resource.TestCheckTypeSetElemAttrPair(resourceName, "ec2_attributes.0.subnet_ids.*", subnetResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "master_instance_group.#", "0"),
resource.TestCheckResourceAttr(resourceName, "core_instance_group.#", "0"),
resource.TestCheckResourceAttr(resourceName, "core_instance_fleet.0.launch_specifications.0.spot_specification.0.allocation_strategy", "capacity-optimized"),
),
},
{
Expand All @@ -1631,6 +1632,7 @@ func TestAccEMRCluster_InstanceFleet_basic(t *testing.T) {
ImportStateVerifyIgnore: []string{
"cluster_state", // Ignore RUNNING versus WAITING changes
"configurations",
"core_instance_fleet",
"keep_job_flow_alive_when_no_steps",
},
},
Expand All @@ -1647,6 +1649,7 @@ func TestAccEMRCluster_InstanceFleet_basic(t *testing.T) {
resource.TestCheckTypeSetElemAttrPair(resourceName, "ec2_attributes.0.subnet_ids.*", subnet2ResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "master_instance_group.#", "0"),
resource.TestCheckResourceAttr(resourceName, "core_instance_group.#", "0"),
resource.TestCheckResourceAttr(resourceName, "core_instance_fleet.0.launch_specifications.0.spot_specification.0.allocation_strategy", "price-capacity-optimized"),
),
},
{
Expand All @@ -1656,6 +1659,7 @@ func TestAccEMRCluster_InstanceFleet_basic(t *testing.T) {
ImportStateVerifyIgnore: []string{
"cluster_state", // Ignore RUNNING versus WAITING changes
"configurations",
"core_instance_fleet",
"keep_job_flow_alive_when_no_steps",
},
},
Expand Down Expand Up @@ -3980,7 +3984,7 @@ resource "aws_emr_cluster" "test" {
}
launch_specifications {
spot_specification {
allocation_strategy = "capacity-optimized"
allocation_strategy = "price-capacity-optimized"
block_duration_minutes = 0
timeout_action = "SWITCH_TO_ON_DEMAND"
timeout_duration_minutes = 10
Expand Down
18 changes: 10 additions & 8 deletions internal/service/emr/instance_fleet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,11 @@ func TestAccEMRInstanceFleet_ebsBasic(t *testing.T) {
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateIdFunc: testAccInstanceFleetResourceImportStateIdFunc(resourceName),
ImportStateVerify: true,
ResourceName: resourceName,
ImportState: true,
ImportStateIdFunc: testAccInstanceFleetResourceImportStateIdFunc(resourceName),
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type_configs"},
},
},
})
Expand All @@ -136,10 +137,11 @@ func TestAccEMRInstanceFleet_full(t *testing.T) {
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateIdFunc: testAccInstanceFleetResourceImportStateIdFunc(resourceName),
ImportStateVerify: true,
ResourceName: resourceName,
ImportState: true,
ImportStateIdFunc: testAccInstanceFleetResourceImportStateIdFunc(resourceName),
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"instance_type_configs"},
},
},
})
Expand Down
1 change: 1 addition & 0 deletions internal/service/emr/managed_scaling_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func testAccErrorCheckSkip(t *testing.T) resource.ErrorCheckFunc {
"Managed scaling is not available",
"SSO is not enabled",
"Account is not whitelisted to use this feature",
"IAM Identity Center is not enabled",
)
}

Expand Down
6 changes: 3 additions & 3 deletions website/docs/r/emr_instance_fleet.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,18 @@ Attributes for the EBS volumes attached to each EC2 instance in the `master_inst
* `on_demand_specification` - (Optional) Configuration block for on demand instances launch specifications
* `spot_specification` - (Optional) Configuration block for spot instances launch specifications

## on_demand_specification Configuration Block
## on_demand_specification Configuration Block

The launch specification for On-Demand instances in the instance fleet, which determines the allocation strategy.
The instance fleet configuration is available only in Amazon EMR versions 4.8.0 and later, excluding 5.0.x versions. On-Demand instances allocation strategy is available in Amazon EMR version 5.12.1 and later.

* `allocation_strategy` - (Required) Specifies the strategy to use in launching On-Demand instance fleets. Currently, the only option is `lowest-price` (the default), which launches the lowest price first.

## spot_specification Configuration Block
## spot_specification Configuration Block

The launch specification for Spot instances in the fleet, which determines the defined duration, provisioning timeout behavior, and allocation strategy.

* `allocation_strategy` - (Required) Specifies the strategy to use in launching Spot instance fleets. Currently, the only option is `capacity-optimized` (the default), which launches instances from Spot instance pools with optimal capacity for the number of instances that are launching.
* `allocation_strategy` - (Required) Specifies one of the following strategies to launch Spot Instance fleets: `price-capacity-optimized`, `capacity-optimized`, `lowest-price`, or `diversified`. For more information on the provisioning strategies, see [Allocation strategies for Spot Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet-allocation-strategy.html).
* `block_duration_minutes` - (Optional) The defined duration for Spot instances (also known as Spot blocks) in minutes. When specified, the Spot instance does not terminate before the defined duration expires, and defined duration pricing for Spot instances applies. Valid values are 60, 120, 180, 240, 300, or 360. The duration period starts as soon as a Spot instance receives its instance ID. At the end of the duration, Amazon EC2 marks the Spot instance for termination and provides a Spot instance termination notice, which gives the instance a two-minute warning before it terminates.
* `timeout_action` - (Required) The action to take when TargetSpotCapacity has not been fulfilled when the TimeoutDurationMinutes has expired; that is, when all Spot instances could not be provisioned within the Spot provisioning timeout. Valid values are `TERMINATE_CLUSTER` and `SWITCH_TO_ON_DEMAND`. SWITCH_TO_ON_DEMAND specifies that if no Spot instances are available, On-Demand Instances should be provisioned to fulfill any remaining Spot capacity.
* `timeout_duration_minutes` - (Required) The spot provisioning timeout period in minutes. If Spot instances are not provisioned within this time period, the TimeOutAction is taken. Minimum value is 5 and maximum value is 1440. The timeout applies only during initial provisioning, when the cluster is first created.
Expand Down
Loading