Skip to content

Commit

Permalink
Add platform capability to Batch job definition (#16850)
Browse files Browse the repository at this point in the history
* Add platform capability to job definition

* Update base test case

* Add platform capability EC2 test case

* Add platform capability Fargate test case

* Add platform_capability doc reference and examples

* Fix linter warnings

* Platform capability validation simplification

* Add CHANGELOG entry.

* r/aws_batch_job_definition: Rename 'platform_capability' -> 'platform_capabilities'.

* r/aws_batch_job_definition: Rename 'platform_capability' -> 'platform_capabilities'.

Acceptance test output:

% make testacc TEST=./aws TESTARGS='-run=TestAccAWSBatchJobDefinition_'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSBatchJobDefinition_ -timeout 180m
=== RUN   TestAccAWSBatchJobDefinition_basic
=== PAUSE TestAccAWSBatchJobDefinition_basic
=== RUN   TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2
=== PAUSE TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2
=== RUN   TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate
=== PAUSE TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate
=== RUN   TestAccAWSBatchJobDefinition_ContainerProperties_Advanced
=== PAUSE TestAccAWSBatchJobDefinition_ContainerProperties_Advanced
=== RUN   TestAccAWSBatchJobDefinition_updateForcesNewResource
=== PAUSE TestAccAWSBatchJobDefinition_updateForcesNewResource
=== RUN   TestAccAWSBatchJobDefinition_Tags
=== PAUSE TestAccAWSBatchJobDefinition_Tags
=== CONT  TestAccAWSBatchJobDefinition_basic
=== CONT  TestAccAWSBatchJobDefinition_Tags
=== CONT  TestAccAWSBatchJobDefinition_updateForcesNewResource
=== CONT  TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate
=== CONT  TestAccAWSBatchJobDefinition_ContainerProperties_Advanced
=== CONT  TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2
--- PASS: TestAccAWSBatchJobDefinition_basic (15.37s)
--- PASS: TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2 (15.44s)
--- PASS: TestAccAWSBatchJobDefinition_ContainerProperties_Advanced (19.44s)
--- PASS: TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate (19.81s)
--- PASS: TestAccAWSBatchJobDefinition_updateForcesNewResource (24.59s)
--- PASS: TestAccAWSBatchJobDefinition_Tags (30.90s)
PASS
ok  	github.com/terraform-providers/terraform-provider-aws/aws	33.926s

* Fix awsproviderlint 'XAT001: missing ErrorCheck' errors.

* r/aws_batch_job_definition: Add '_disappears' test (#13826).

Acceptance test output:

% make testacc TEST=./aws TESTARGS='-run=TestAccAWSBatchJobDefinition_disappears'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSBatchJobDefinition_disappears -timeout 180m
=== RUN   TestAccAWSBatchJobDefinition_disappears
=== PAUSE TestAccAWSBatchJobDefinition_disappears
=== CONT  TestAccAWSBatchJobDefinition_disappears
--- PASS: TestAccAWSBatchJobDefinition_disappears (9.67s)
PASS
ok  	github.com/terraform-providers/terraform-provider-aws/aws	14.046s

* r/aws_batch_job_definition: Simplify import handling

Acceptance test output:

% make testacc TEST=./aws TESTARGS='-run=TestAccAWSBatchJobDefinition_basic'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSBatchJobDefinition_basic -timeout 180m
=== RUN   TestAccAWSBatchJobDefinition_basic
=== PAUSE TestAccAWSBatchJobDefinition_basic
=== CONT  TestAccAWSBatchJobDefinition_basic
--- PASS: TestAccAWSBatchJobDefinition_basic (12.62s)
PASS
ok  	github.com/terraform-providers/terraform-provider-aws/aws	15.829s

* r/aws_batch_job_definition: Add and use internal batch/finder package.

Acceptance test output:

% make testacc TEST=./aws TESTARGS='-run=TestAccAWSBatchJobDefinition_'
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSBatchJobDefinition_ -timeout 180m
=== RUN   TestAccAWSBatchJobDefinition_basic
=== PAUSE TestAccAWSBatchJobDefinition_basic
=== RUN   TestAccAWSBatchJobDefinition_disappears
=== PAUSE TestAccAWSBatchJobDefinition_disappears
=== RUN   TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2
=== PAUSE TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2
=== RUN   TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate
=== PAUSE TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate
=== RUN   TestAccAWSBatchJobDefinition_ContainerProperties_Advanced
=== PAUSE TestAccAWSBatchJobDefinition_ContainerProperties_Advanced
=== RUN   TestAccAWSBatchJobDefinition_updateForcesNewResource
=== PAUSE TestAccAWSBatchJobDefinition_updateForcesNewResource
=== RUN   TestAccAWSBatchJobDefinition_Tags
=== PAUSE TestAccAWSBatchJobDefinition_Tags
=== CONT  TestAccAWSBatchJobDefinition_basic
=== CONT  TestAccAWSBatchJobDefinition_ContainerProperties_Advanced
=== CONT  TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2
=== CONT  TestAccAWSBatchJobDefinition_disappears
=== CONT  TestAccAWSBatchJobDefinition_Tags
=== CONT  TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate
=== CONT  TestAccAWSBatchJobDefinition_updateForcesNewResource
--- PASS: TestAccAWSBatchJobDefinition_disappears (13.05s)
--- PASS: TestAccAWSBatchJobDefinition_ContainerProperties_Advanced (15.72s)
--- PASS: TestAccAWSBatchJobDefinition_basic (15.84s)
--- PASS: TestAccAWSBatchJobDefinition_PlatformCapabilities_EC2 (16.82s)
--- PASS: TestAccAWSBatchJobDefinition_PlatformCapabilities_Fargate (18.69s)
--- PASS: TestAccAWSBatchJobDefinition_updateForcesNewResource (25.88s)
--- PASS: TestAccAWSBatchJobDefinition_Tags (31.97s)
PASS
ok  	github.com/terraform-providers/terraform-provider-aws/aws	35.037s

Co-authored-by: Kit Ewbank <[email protected]>
  • Loading branch information
gmazelier and ewbankkit authored Apr 19, 2021
1 parent 5c130d7 commit b7c1c57
Show file tree
Hide file tree
Showing 6 changed files with 382 additions and 103 deletions.
3 changes: 3 additions & 0 deletions .changelog/16850.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-notes:enhancement
resource/aws_batch_job_definition: Add `platform_capabilities` attribute
```
5 changes: 5 additions & 0 deletions aws/internal/service/batch/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package batch

const (
JobDefinitionStatusInactive = "INACTIVE"
)
42 changes: 42 additions & 0 deletions aws/internal/service/batch/finder/finder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package finder

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/batch"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
tfbatch "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/batch"
)

func JobDefinitionByARN(conn *batch.Batch, arn string) (*batch.JobDefinition, error) {
input := &batch.DescribeJobDefinitionsInput{
JobDefinitions: aws.StringSlice([]string{arn}),
}

return JobDefinition(conn, input)
}

func JobDefinition(conn *batch.Batch, input *batch.DescribeJobDefinitionsInput) (*batch.JobDefinition, error) {
output, err := conn.DescribeJobDefinitions(input)

if err != nil {
return nil, err
}

if output == nil || len(output.JobDefinitions) == 0 || output.JobDefinitions[0] == nil {
return nil, &resource.NotFoundError{
Message: "Empty result",
LastRequest: input,
}
}

jobDefinition := output.JobDefinitions[0]

if status := aws.StringValue(jobDefinition.Status); status == tfbatch.JobDefinitionStatusInactive {
return nil, &resource.NotFoundError{
Message: status,
LastRequest: input,
}
}

return jobDefinition, nil
}
116 changes: 56 additions & 60 deletions aws/resource_aws_batch_job_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package aws
import (
"encoding/json"
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
Expand All @@ -12,6 +13,8 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/batch/equivalency"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/batch/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

func resourceAwsBatchJobDefinition() *schema.Resource {
Expand All @@ -20,12 +23,8 @@ func resourceAwsBatchJobDefinition() *schema.Resource {
Read: resourceAwsBatchJobDefinitionRead,
Update: resourceAwsBatchJobDefinitionUpdate,
Delete: resourceAwsBatchJobDefinitionDelete,

Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
d.Set("arn", d.Id())
return []*schema.ResourceData{d}, nil
},
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -56,6 +55,15 @@ func resourceAwsBatchJobDefinition() *schema.Resource {
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"platform_capabilities": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice(batch.PlatformCapability_Values(), true),
},
},
"retry_strategy": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -119,15 +127,20 @@ func resourceAwsBatchJobDefinitionCreate(d *schema.ResourceData, meta interface{
if v, ok := d.GetOk("container_properties"); ok {
props, err := expandBatchJobContainerProperties(v.(string))
if err != nil {
return fmt.Errorf("%s %q", err, name)
return err
}

input.ContainerProperties = props
}

if v, ok := d.GetOk("parameters"); ok {
input.Parameters = expandJobDefinitionParameters(v.(map[string]interface{}))
}

if v, ok := d.GetOk("platform_capabilities"); ok && v.(*schema.Set).Len() > 0 {
input.PlatformCapabilities = expandStringSet(v.(*schema.Set))
}

if v, ok := d.GetOk("retry_strategy"); ok {
input.RetryStrategy = expandJobDefinitionRetryStrategy(v.([]interface{}))
}
Expand All @@ -140,58 +153,64 @@ func resourceAwsBatchJobDefinitionCreate(d *schema.ResourceData, meta interface{
input.Timeout = expandJobDefinitionTimeout(v.([]interface{}))
}

out, err := conn.RegisterJobDefinition(input)
output, err := conn.RegisterJobDefinition(input)

if err != nil {
return fmt.Errorf("%s %q", err, name)
return fmt.Errorf("error creating Batch Job Definition (%s): %w", name, err)
}
d.SetId(aws.StringValue(out.JobDefinitionArn))
d.Set("arn", out.JobDefinitionArn)

d.SetId(aws.StringValue(output.JobDefinitionArn))

return resourceAwsBatchJobDefinitionRead(d, meta)
}

func resourceAwsBatchJobDefinitionRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).batchconn
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

arn := d.Get("arn").(string)
job, err := getJobDefinition(conn, arn)
if err != nil {
return fmt.Errorf("%s %q", err, arn)
}
if job == nil {
jobDefinition, err := finder.JobDefinitionByARN(conn, d.Id())

if !d.IsNewResource() && tfresource.NotFound(err) {
log.Printf("[WARN] Batch Job Definition (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
d.Set("arn", job.JobDefinitionArn)

containerProperties, err := flattenBatchContainerProperties(job.ContainerProperties)
if err != nil {
return fmt.Errorf("error reading Batch Job Definition (%s): %w", d.Id(), err)
}

d.Set("arn", jobDefinition.JobDefinitionArn)

containerProperties, err := flattenBatchContainerProperties(jobDefinition.ContainerProperties)

if err != nil {
return fmt.Errorf("error converting Batch Container Properties to JSON: %s", err)
return fmt.Errorf("error converting Batch Container Properties to JSON: %w", err)
}

if err := d.Set("container_properties", containerProperties); err != nil {
return fmt.Errorf("error setting container_properties: %s", err)
return fmt.Errorf("error setting container_properties: %w", err)
}

d.Set("name", job.JobDefinitionName)

d.Set("parameters", aws.StringValueMap(job.Parameters))
d.Set("name", jobDefinition.JobDefinitionName)
d.Set("parameters", aws.StringValueMap(jobDefinition.Parameters))
d.Set("platform_capabilities", aws.StringValueSlice(jobDefinition.PlatformCapabilities))

if err := d.Set("retry_strategy", flattenBatchRetryStrategy(job.RetryStrategy)); err != nil {
return fmt.Errorf("error setting retry_strategy: %s", err)
if err := d.Set("retry_strategy", flattenBatchRetryStrategy(jobDefinition.RetryStrategy)); err != nil {
return fmt.Errorf("error setting retry_strategy: %w", err)
}

if err := d.Set("tags", keyvaluetags.BatchKeyValueTags(job.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %s", err)
if err := d.Set("tags", keyvaluetags.BatchKeyValueTags(jobDefinition.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %w", err)
}

if err := d.Set("timeout", flattenBatchJobTimeout(job.Timeout)); err != nil {
return fmt.Errorf("error setting timeout: %s", err)
if err := d.Set("timeout", flattenBatchJobTimeout(jobDefinition.Timeout)); err != nil {
return fmt.Errorf("error setting timeout: %w", err)
}

d.Set("revision", job.Revision)
d.Set("type", job.Type)
d.Set("revision", jobDefinition.Revision)
d.Set("type", jobDefinition.Type)

return nil
}

Expand All @@ -201,8 +220,8 @@ func resourceAwsBatchJobDefinitionUpdate(d *schema.ResourceData, meta interface{
if d.HasChange("tags") {
o, n := d.GetChange("tags")

if err := keyvaluetags.BatchUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating tags: %s", err)
if err := keyvaluetags.BatchUpdateTags(conn, d.Id(), o, n); err != nil {
return fmt.Errorf("error updating tags: %w", err)
}
}

Expand All @@ -211,39 +230,16 @@ func resourceAwsBatchJobDefinitionUpdate(d *schema.ResourceData, meta interface{

func resourceAwsBatchJobDefinitionDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).batchconn
arn := d.Get("arn").(string)

_, err := conn.DeregisterJobDefinition(&batch.DeregisterJobDefinitionInput{
JobDefinition: aws.String(arn),
JobDefinition: aws.String(d.Id()),
})
if err != nil {
return fmt.Errorf("%s %q", err, arn)
}

return nil
}

func getJobDefinition(conn *batch.Batch, arn string) (*batch.JobDefinition, error) {
describeOpts := &batch.DescribeJobDefinitionsInput{
JobDefinitions: []*string{aws.String(arn)},
}
resp, err := conn.DescribeJobDefinitions(describeOpts)
if err != nil {
return nil, err
return fmt.Errorf("error deleting Batch Job Definition (%s): %w", d.Id(), err)
}

numJobDefinitions := len(resp.JobDefinitions)
switch {
case numJobDefinitions == 0:
return nil, nil
case numJobDefinitions == 1:
if aws.StringValue(resp.JobDefinitions[0].Status) == "ACTIVE" {
return resp.JobDefinitions[0], nil
}
return nil, nil
case numJobDefinitions > 1:
return nil, fmt.Errorf("Multiple Job Definitions with name %s", arn)
}
return nil, nil
return nil
}

func validateAwsBatchJobContainerProperties(v interface{}, k string) (ws []string, errors []error) {
Expand Down
Loading

0 comments on commit b7c1c57

Please sign in to comment.