diff --git a/.changelog/32200.txt b/.changelog/32200.txt new file mode 100644 index 000000000000..abf4dbd87801 --- /dev/null +++ b/.changelog/32200.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_batch_compute_environment: Add `placement_group` attribute to the `compute_resources` configuration block +``` \ No newline at end of file diff --git a/internal/service/batch/compute_environment.go b/internal/service/batch/compute_environment.go index 9a5fcaf5f753..9b957ec84ea2 100644 --- a/internal/service/batch/compute_environment.go +++ b/internal/service/batch/compute_environment.go @@ -172,6 +172,11 @@ func ResourceComputeEnvironment() *schema.Resource { Type: schema.TypeInt, Optional: true, }, + "placement_group": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, "security_group_ids": { Type: schema.TypeSet, Optional: true, @@ -674,6 +679,10 @@ func expandComputeResource(ctx context.Context, tfMap map[string]interface{}) *b apiObject.MinvCpus = aws.Int64(0) } + if v, ok := tfMap["placement_group"].(string); ok && v != "" { + apiObject.PlacementGroup = aws.String(v) + } + if v, ok := tfMap["security_group_ids"].(*schema.Set); ok && v.Len() > 0 { apiObject.SecurityGroupIds = flex.ExpandStringSet(v) } @@ -832,6 +841,10 @@ func flattenComputeResource(ctx context.Context, apiObject *batch.ComputeResourc tfMap["min_vcpus"] = aws.Int64Value(v) } + if v := apiObject.PlacementGroup; v != nil { + tfMap["placement_group"] = aws.StringValue(v) + } + if v := apiObject.SecurityGroupIds; v != nil { tfMap["security_group_ids"] = aws.StringValueSlice(v) } diff --git a/internal/service/batch/compute_environment_test.go b/internal/service/batch/compute_environment_test.go index 65cd172ccf12..6a39abc2bb84 100644 --- a/internal/service/batch/compute_environment_test.go +++ b/internal/service/batch/compute_environment_test.go @@ -202,6 +202,7 @@ func TestAccBatchComputeEnvironment_createEC2(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.#", "0"), resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "16"), resource.TestCheckResourceAttr(resourceName, "compute_resources.0.min_vcpus", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.placement_group", ""), resource.TestCheckResourceAttr(resourceName, "compute_resources.0.security_group_ids.#", "1"), resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.security_group_ids.*", securityGroupResourceName, "id"), resource.TestCheckResourceAttr(resourceName, "compute_resources.0.spot_iam_fleet_role", ""), @@ -1068,6 +1069,72 @@ func TestAccBatchComputeEnvironment_ec2Configuration(t *testing.T) { }) } +func TestAccBatchComputeEnvironment_ec2ConfigurationPlacementGroup(t *testing.T) { + ctx := acctest.Context(t) + var ce batch.ComputeEnvironmentDetail + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_batch_compute_environment.test" + instanceProfileResourceName := "aws_iam_instance_profile.ecs_instance" + securityGroupResourceName := "aws_security_group.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + spotFleetRoleResourceName := "aws_iam_role.ec2_spot_fleet" + subnetResourceName := "aws_subnet.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, batch.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckComputeEnvironmentDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccComputeEnvironmentConfig_ec2ConfigurationPlacementGroup(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckComputeEnvironmentExists(ctx, resourceName, &ce), + acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "batch", fmt.Sprintf("compute-environment/%s", rName)), + resource.TestCheckResourceAttr(resourceName, "compute_environment_name", rName), + resource.TestCheckResourceAttr(resourceName, "compute_environment_name_prefix", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.#", "1"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.allocation_strategy", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.bid_percentage", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.desired_vcpus", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.ec2_key_pair", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.image_id", ""), + resource.TestCheckResourceAttrPair(resourceName, "compute_resources.0.instance_role", instanceProfileResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_type.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "compute_resources.0.instance_type.*", "optimal"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.ec2_configuration.#", "2"), + resource.TestCheckResourceAttrSet(resourceName, "compute_resources.0.ec2_configuration.0.image_id_override"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.ec2_configuration.0.image_type", "ECS_AL2"), + resource.TestCheckResourceAttrSet(resourceName, "compute_resources.0.ec2_configuration.1.image_id_override"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.ec2_configuration.1.image_type", "ECS_AL2_NVIDIA"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "16"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.min_vcpus", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.placement_group", rName), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.security_group_ids.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.security_group_ids.*", securityGroupResourceName, "id"), + resource.TestCheckResourceAttrPair(resourceName, "compute_resources.0.spot_iam_fleet_role", spotFleetRoleResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.subnets.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.subnets.*", subnetResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.type", "SPOT"), + resource.TestCheckResourceAttrSet(resourceName, "ecs_cluster_arn"), + resource.TestCheckResourceAttrPair(resourceName, "service_role", serviceRoleResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "state", "ENABLED"), + resource.TestCheckResourceAttrSet(resourceName, "status"), + resource.TestCheckResourceAttrSet(resourceName, "status_reason"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "type", "MANAGED"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccBatchComputeEnvironment_launchTemplate(t *testing.T) { ctx := acctest.Context(t) var ce batch.ComputeEnvironmentDetail @@ -2493,3 +2560,49 @@ resource "aws_batch_compute_environment" "test" { } `, rName)) } + +func testAccComputeEnvironmentConfig_ec2ConfigurationPlacementGroup(rName string) string { + return acctest.ConfigCompose(testAccComputeEnvironmentConfig_base(rName), acctest.ConfigLatestAmazonLinuxHVMEBSAMI(), fmt.Sprintf(` +resource "aws_placement_group" "test" { + name = %[1]q + strategy = "cluster" +} + +resource "aws_batch_compute_environment" "test" { + compute_environment_name = %[1]q + + compute_resources { + instance_role = aws_iam_instance_profile.ecs_instance.arn + instance_type = ["optimal"] + + ec2_configuration { + image_id_override = data.aws_ami.amzn-ami-minimal-hvm-ebs.id + image_type = "ECS_AL2" + } + + ec2_configuration { + image_id_override = data.aws_ami.amzn-ami-minimal-hvm-ebs.id + image_type = "ECS_AL2_NVIDIA" + } + + max_vcpus = 16 + min_vcpus = 0 + + placement_group = aws_placement_group.test.name + + security_group_ids = [ + aws_security_group.test.id + ] + spot_iam_fleet_role = aws_iam_role.ec2_spot_fleet.arn + subnets = [ + aws_subnet.test.id + ] + type = "SPOT" + } + + service_role = aws_iam_role.batch_service.arn + type = "MANAGED" + depends_on = [aws_iam_role_policy_attachment.batch_service] +} +`, rName)) +} diff --git a/website/docs/r/batch_compute_environment.html.markdown b/website/docs/r/batch_compute_environment.html.markdown index e760f901edc7..314d0f0430e8 100644 --- a/website/docs/r/batch_compute_environment.html.markdown +++ b/website/docs/r/batch_compute_environment.html.markdown @@ -92,6 +92,11 @@ resource "aws_subnet" "sample" { cidr_block = "10.1.1.0/24" } +resource "aws_placement_group" "sample" { + name = "sample" + strategy = "cluster" +} + resource "aws_batch_compute_environment" "sample" { compute_environment_name = "sample" @@ -105,6 +110,8 @@ resource "aws_batch_compute_environment" "sample" { max_vcpus = 16 min_vcpus = 0 + placement_group = aws_placement_group.sample.name + security_group_ids = [ aws_security_group.sample.id, ] @@ -172,6 +179,7 @@ resource "aws_batch_compute_environment" "sample" { * `launch_template` - (Optional) The launch template to use for your compute resources. See details below. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified. * `max_vcpus` - (Required) The maximum number of EC2 vCPUs that an environment can reach. * `min_vcpus` - (Optional) The minimum number of EC2 vCPUs that an environment should maintain. For `EC2` or `SPOT` compute environments, if the parameter is not explicitly defined, a `0` default value will be set. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified. +* `placement_group` - (Optional) The Amazon EC2 placement group to associate with your compute resources. * `security_group_ids` - (Optional) A list of EC2 security group that are associated with instances launched in the compute environment. This parameter is required for Fargate compute environments. * `spot_iam_fleet_role` - (Optional) The Amazon Resource Name (ARN) of the Amazon EC2 Spot Fleet IAM role applied to a SPOT compute environment. This parameter is required for SPOT compute environments. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified. * `subnets` - (Required) A list of VPC subnets into which the compute resources are launched.