Skip to content

Commit

Permalink
Merge pull request #21565 from ijin/f-aws_batch_compute_environment-e…
Browse files Browse the repository at this point in the history
…c2-configuration

r/aws_batch_compute_environment: Add `ec2_configuration`
  • Loading branch information
ewbankkit authored Nov 3, 2021
2 parents aa38005 + b279d04 commit 8715cae
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .changelog/21565.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_batch_compute_environment: Add `ec2_configuration` argument to `compute_resources` configuration block
```
144 changes: 128 additions & 16 deletions internal/service/batch/compute_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func ResourceComputeEnvironment() *schema.Resource {
),

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"compute_environment_name": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -78,6 +82,30 @@ func ResourceComputeEnvironment() *schema.Resource {
Optional: true,
Computed: true,
},
"ec2_configuration": {
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"image_id_override": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 256),
},
"image_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 256),
},
},
},
},
"ec2_key_pair": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -164,6 +192,10 @@ func ResourceComputeEnvironment() *schema.Resource {
},
},
},
"ecs_cluster_arn": {
Type: schema.TypeString,
Computed: true,
},
"service_role": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -179,6 +211,14 @@ func ResourceComputeEnvironment() *schema.Resource {
ValidateFunc: validation.StringInSlice(batch.CEState_Values(), true),
Default: batch.CEStateEnabled,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"status_reason": {
Type: schema.TypeString,
Computed: true,
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
"type": {
Expand All @@ -190,22 +230,6 @@ func ResourceComputeEnvironment() *schema.Resource {
},
ValidateFunc: validation.StringInSlice(batch.CEType_Values(), true),
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"ecs_cluster_arn": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"status_reason": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -461,6 +485,10 @@ func expandBatchComputeResource(tfMap map[string]interface{}) *batch.ComputeReso
apiObject.DesiredvCpus = aws.Int64(int64(v))
}

if v, ok := tfMap["ec2_configuration"].([]interface{}); ok && len(v) > 0 {
apiObject.Ec2Configuration = expandBatchEc2Configurations(v)
}

if v, ok := tfMap["ec2_key_pair"].(string); ok && v != "" {
apiObject.Ec2KeyPair = aws.String(v)
}
Expand Down Expand Up @@ -514,6 +542,50 @@ func expandBatchComputeResource(tfMap map[string]interface{}) *batch.ComputeReso
return apiObject
}

func expandBatchEc2Configuration(tfMap map[string]interface{}) *batch.Ec2Configuration {
if tfMap == nil {
return nil
}

apiObject := &batch.Ec2Configuration{}

if v, ok := tfMap["image_id_override"].(string); ok && v != "" {
apiObject.ImageIdOverride = aws.String(v)
}

if v, ok := tfMap["image_type"].(string); ok && v != "" {
apiObject.ImageType = aws.String(v)
}

return apiObject
}

func expandBatchEc2Configurations(tfList []interface{}) []*batch.Ec2Configuration {
if len(tfList) == 0 {
return nil
}

var apiObjects []*batch.Ec2Configuration

for _, tfMapRaw := range tfList {
tfMap, ok := tfMapRaw.(map[string]interface{})

if !ok {
continue
}

apiObject := expandBatchEc2Configuration(tfMap)

if apiObject == nil {
continue
}

apiObjects = append(apiObjects, apiObject)
}

return apiObjects
}

func expandBatchLaunchTemplateSpecification(tfMap map[string]interface{}) *batch.LaunchTemplateSpecification {
if tfMap == nil {
return nil
Expand Down Expand Up @@ -555,6 +627,10 @@ func flattenBatchComputeResource(apiObject *batch.ComputeResource) map[string]in
tfMap["desired_vcpus"] = aws.Int64Value(v)
}

if v := apiObject.Ec2Configuration; v != nil {
tfMap["ec2_configuration"] = flattenBatchEc2Configurations(v)
}

if v := apiObject.Ec2KeyPair; v != nil {
tfMap["ec2_key_pair"] = aws.StringValue(v)
}
Expand Down Expand Up @@ -606,6 +682,42 @@ func flattenBatchComputeResource(apiObject *batch.ComputeResource) map[string]in
return tfMap
}

func flattenBatchEc2Configuration(apiObject *batch.Ec2Configuration) map[string]interface{} {
if apiObject == nil {
return nil
}

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

if v := apiObject.ImageIdOverride; v != nil {
tfMap["image_id_override"] = aws.StringValue(v)
}

if v := apiObject.ImageType; v != nil {
tfMap["image_type"] = aws.StringValue(v)
}

return tfMap
}

func flattenBatchEc2Configurations(apiObjects []*batch.Ec2Configuration) []interface{} {
if len(apiObjects) == 0 {
return nil
}

var tfList []interface{}

for _, apiObject := range apiObjects {
if apiObject == nil {
continue
}

tfList = append(tfList, flattenBatchEc2Configuration(apiObject))
}

return tfList
}

func flattenBatchLaunchTemplateSpecification(apiObject *batch.LaunchTemplateSpecification) map[string]interface{} {
if apiObject == nil {
return nil
Expand Down
100 changes: 100 additions & 0 deletions internal/service/batch/compute_environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ func TestAccBatchComputeEnvironment_createEC2(t *testing.T) {
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_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "compute_resources.0.ec2_configuration.0.image_type", "ECS_AL2"),
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"),
Expand Down Expand Up @@ -953,6 +955,68 @@ func TestAccBatchComputeEnvironment_ComputeResources_maxVCPUs(t *testing.T) {
})
}

func TestAccBatchComputeEnvironment_ec2Configuration(t *testing.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(t); testAccPreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, batch.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccComputeEnvironmentEC2Configuration(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeEnvironmentExists(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.#", "1"),
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.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "16"),
resource.TestCheckResourceAttr(resourceName, "compute_resources.0.min_vcpus", "0"),
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) {
var ce batch.ComputeEnvironmentDetail
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
Expand Down Expand Up @@ -2080,3 +2144,39 @@ resource "aws_batch_compute_environment" "test" {
}
`, rName, tagKey1, tagValue1, tagKey2, tagValue2))
}

func testAccComputeEnvironmentEC2Configuration(rName string) string {
return acctest.ConfigCompose(
testAccComputeEnvironmentBaseConfig(rName),
acctest.ConfigLatestAmazonLinuxHvmEbsAmi(),
fmt.Sprintf(`
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"
}
max_vcpus = 16
min_vcpus = 0
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))
}
10 changes: 9 additions & 1 deletion website/docs/r/batch_compute_environment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,9 @@ resource "aws_batch_compute_environment" "sample" {
* `allocation_strategy` - (Optional) The allocation strategy to use for the compute resource in case not enough instances of the best fitting instance type can be allocated. Valid items are `BEST_FIT_PROGRESSIVE`, `SPOT_CAPACITY_OPTIMIZED` or `BEST_FIT`. Defaults to `BEST_FIT`. See [AWS docs](https://docs.aws.amazon.com/batch/latest/userguide/allocation-strategies.html) for details. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `bid_percentage` - (Optional) Integer of minimum percentage that a Spot Instance price must be when compared with the On-Demand price for that instance type before instances are launched. For example, if your bid percentage is 20% (`20`), then the Spot price must be below 20% of the current On-Demand price for that EC2 instance. This parameter is required for SPOT compute environments. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `desired_vcpus` - (Optional) The desired number of EC2 vCPUS in the compute environment. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `ec2_configuration` - (Optional) Provides information used to select Amazon Machine Images (AMIs) for EC2 instances in the compute environment. If Ec2Configuration isn't specified, the default is ECS_AL2. This parameter isn't applicable to jobs that are running on Fargate resources, and shouldn't be specified.
* `ec2_key_pair` - (Optional) The EC2 key pair that is used for instances launched in the compute environment. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `image_id` - (Optional) The Amazon Machine Image (AMI) ID used for instances launched in the compute environment. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `image_id` - (Optional) The Amazon Machine Image (AMI) ID used for instances launched in the compute environment. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified. (Deprecated, use [`image_id_override`](#image_id_override) instead)
* `instance_role` - (Optional) The Amazon ECS instance role applied to Amazon EC2 instances in a compute environment. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `instance_type` - (Optional) A list of instance types that may be launched. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `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.
Expand All @@ -178,6 +179,13 @@ resource "aws_batch_compute_environment" "sample" {
* `tags` - (Optional) Key-value pair tags to be applied to resources that are launched in the compute environment. This parameter isn't applicable to jobs running on Fargate resources, and shouldn't be specified.
* `type` - (Required) The type of compute environment. Valid items are `EC2`, `SPOT`, `FARGATE` or `FARGATE_SPOT`.

### ec2_configuration

`ec2_configuration` supports the following:

* `image_id_override` - (Optional) The AMI ID used for instances launched in the compute environment that match the image type. This setting overrides the [`image_id` argument](#image_id) in the `compute_resourcess block.
* `image_type` - (Optional) The image type to match with the instance type to select an AMI. If the `image_id_override` parameter isn't specified, then a recent [Amazon ECS-optimized Amazon Linux 2 AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html#al2ami) (`ECS_AL2`) is used.

### launch_template

`launch_template` supports the following:
Expand Down

0 comments on commit 8715cae

Please sign in to comment.