diff --git a/.changelog/16819.txt b/.changelog/16819.txt new file mode 100644 index 00000000000..6b544eb76b0 --- /dev/null +++ b/.changelog/16819.txt @@ -0,0 +1,11 @@ +```release-note:enhancement +resource/aws_batch_compute_environment: Additional supported value `FARGATE` and `FARGATE_SPOT` for the `type` argument in the `compute_resources` configuration block +``` + +```release-note:enhancement +resource/aws_batch_compute_environment: The `instance_role`, `instance_type` and `min_vcpus` arguments in the `compute_resources` configuration block are now optional +``` + +```release-note:enhancement +resource/aws_batch_compute_environment: The `security_group_ids` and `subnets` arguments in the `compute_resources` configuration block can now be updated in-place for Fargate compute resources +``` \ No newline at end of file diff --git a/aws/internal/service/batch/finder/finder.go b/aws/internal/service/batch/finder/finder.go index 05d88cd6e3c..6c56156993d 100644 --- a/aws/internal/service/batch/finder/finder.go +++ b/aws/internal/service/batch/finder/finder.go @@ -7,29 +7,56 @@ import ( 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}), +func ComputeEnvironmentDetailByName(conn *batch.Batch, name string) (*batch.ComputeEnvironmentDetail, error) { + input := &batch.DescribeComputeEnvironmentsInput{ + ComputeEnvironments: aws.StringSlice([]string{name}), + } + + computeEnvironmentDetail, err := ComputeEnvironmentDetail(conn, input) + + if err != nil { + return nil, err } - return JobDefinition(conn, input) + if status := aws.StringValue(computeEnvironmentDetail.Status); status == batch.CEStatusDeleted { + return nil, &resource.NotFoundError{ + Message: status, + LastRequest: input, + } + } + + return computeEnvironmentDetail, nil } -func JobDefinition(conn *batch.Batch, input *batch.DescribeJobDefinitionsInput) (*batch.JobDefinition, error) { - output, err := conn.DescribeJobDefinitions(input) +func ComputeEnvironmentDetail(conn *batch.Batch, input *batch.DescribeComputeEnvironmentsInput) (*batch.ComputeEnvironmentDetail, error) { + output, err := conn.DescribeComputeEnvironments(input) if err != nil { return nil, err } - if output == nil || len(output.JobDefinitions) == 0 || output.JobDefinitions[0] == nil { + if output == nil || len(output.ComputeEnvironments) == 0 || output.ComputeEnvironments[0] == nil { return nil, &resource.NotFoundError{ Message: "Empty result", LastRequest: input, } } - jobDefinition := output.JobDefinitions[0] + // TODO if len(output.ComputeEnvironments) > 1 + + return output.ComputeEnvironments[0], nil +} + +func JobDefinitionByARN(conn *batch.Batch, arn string) (*batch.JobDefinition, error) { + input := &batch.DescribeJobDefinitionsInput{ + JobDefinitions: aws.StringSlice([]string{arn}), + } + + jobDefinition, err := JobDefinition(conn, input) + + if err != nil { + return nil, err + } if status := aws.StringValue(jobDefinition.Status); status == tfbatch.JobDefinitionStatusInactive { return nil, &resource.NotFoundError{ @@ -40,3 +67,22 @@ func JobDefinition(conn *batch.Batch, input *batch.DescribeJobDefinitionsInput) return jobDefinition, nil } + +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, + } + } + + // TODO if len(output.JobDefinitions) > 1 + + return output.JobDefinitions[0], nil +} diff --git a/aws/internal/service/batch/waiter/status.go b/aws/internal/service/batch/waiter/status.go new file mode 100644 index 00000000000..819b3898811 --- /dev/null +++ b/aws/internal/service/batch/waiter/status.go @@ -0,0 +1,25 @@ +package waiter + +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" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/batch/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" +) + +func ComputeEnvironmentStatus(conn *batch.Batch, name string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + computeEnvironmentDetail, err := finder.ComputeEnvironmentDetailByName(conn, name) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return computeEnvironmentDetail, aws.StringValue(computeEnvironmentDetail.Status), nil + } +} diff --git a/aws/internal/service/batch/waiter/waiter.go b/aws/internal/service/batch/waiter/waiter.go new file mode 100644 index 00000000000..a42a37d35a9 --- /dev/null +++ b/aws/internal/service/batch/waiter/waiter.go @@ -0,0 +1,76 @@ +package waiter + +import ( + "time" + + "github.com/aws/aws-sdk-go/service/batch" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func ComputeEnvironmentCreated(conn *batch.Batch, name string, timeout time.Duration) (*batch.ComputeEnvironmentDetail, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{batch.CEStatusCreating}, + Target: []string{batch.CEStatusValid}, + Refresh: ComputeEnvironmentStatus(conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*batch.ComputeEnvironmentDetail); ok { + return v, err + } + + return nil, err +} + +func ComputeEnvironmentDeleted(conn *batch.Batch, name string, timeout time.Duration) (*batch.ComputeEnvironmentDetail, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{batch.CEStatusDeleting}, + Target: []string{}, + Refresh: ComputeEnvironmentStatus(conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*batch.ComputeEnvironmentDetail); ok { + return v, err + } + + return nil, err +} + +func ComputeEnvironmentDisabled(conn *batch.Batch, name string, timeout time.Duration) (*batch.ComputeEnvironmentDetail, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{batch.CEStatusUpdating}, + Target: []string{batch.CEStatusValid, batch.CEStatusInvalid}, + Refresh: ComputeEnvironmentStatus(conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*batch.ComputeEnvironmentDetail); ok { + return v, err + } + + return nil, err +} + +func ComputeEnvironmentUpdated(conn *batch.Batch, name string, timeout time.Duration) (*batch.ComputeEnvironmentDetail, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{batch.CEStatusUpdating}, + Target: []string{batch.CEStatusValid}, + Refresh: ComputeEnvironmentStatus(conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*batch.ComputeEnvironmentDetail); ok { + return v, err + } + + return nil, err +} diff --git a/aws/resource_aws_batch_compute_environment.go b/aws/resource_aws_batch_compute_environment.go index 31214767fcc..74cb2169efa 100644 --- a/aws/resource_aws_batch_compute_environment.go +++ b/aws/resource_aws_batch_compute_environment.go @@ -1,16 +1,21 @@ package aws import ( + "context" "fmt" "log" - "time" + "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/batch" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "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/naming" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/batch/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/batch/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func resourceAwsBatchComputeEnvironment() *schema.Resource { @@ -19,13 +24,15 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { Read: resourceAwsBatchComputeEnvironmentRead, Update: resourceAwsBatchComputeEnvironmentUpdate, Delete: resourceAwsBatchComputeEnvironmentDelete, - Importer: &schema.ResourceImporter{ - State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - d.Set("compute_environment_name", d.Id()) - return []*schema.ResourceData{d}, nil - }, + State: schema.ImportStatePassthrough, }, + + CustomizeDiff: customdiff.Sequence( + resourceAwsBatchComputeEnvironmentCustomizeDiff, + SetTagsDiff, + ), + Schema: map[string]*schema.Schema{ "compute_environment_name": { Type: schema.TypeString, @@ -38,6 +45,7 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { "compute_environment_name_prefix": { Type: schema.TypeString, Optional: true, + Computed: true, ForceNew: true, ConflictsWith: []string{"compute_environment_name"}, ValidateFunc: validateBatchPrefix, @@ -45,6 +53,7 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { "compute_resources": { Type: schema.TypeList, Optional: true, + ForceNew: true, MinItems: 0, MaxItems: 1, Elem: &schema.Resource{ @@ -53,10 +62,10 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ - batch.CRAllocationStrategyBestFit, - batch.CRAllocationStrategyBestFitProgressive, - batch.CRAllocationStrategySpotCapacityOptimized}, true), + StateFunc: func(val interface{}) string { + return strings.ToUpper(val.(string)) + }, + ValidateFunc: validation.StringInSlice(batch.CRAllocationStrategy_Values(), true), }, "bid_percentage": { Type: schema.TypeInt, @@ -80,13 +89,13 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { }, "instance_role": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, ValidateFunc: validateArn, }, "instance_type": { Type: schema.TypeSet, - Required: true, + Optional: true, ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, @@ -100,14 +109,14 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { "launch_template_id": { Type: schema.TypeString, Optional: true, - ConflictsWith: []string{"compute_resources.0.launch_template.0.launch_template_name"}, ForceNew: true, + ConflictsWith: []string{"compute_resources.0.launch_template.0.launch_template_name"}, }, "launch_template_name": { Type: schema.TypeString, Optional: true, - ConflictsWith: []string{"compute_resources.0.launch_template.0.launch_template_id"}, ForceNew: true, + ConflictsWith: []string{"compute_resources.0.launch_template.0.launch_template_id"}, }, "version": { Type: schema.TypeString, @@ -123,12 +132,11 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { }, "min_vcpus": { Type: schema.TypeInt, - Required: true, + Optional: true, }, "security_group_ids": { Type: schema.TypeSet, Required: true, - ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "spot_iam_fleet_role": { @@ -140,15 +148,17 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { "subnets": { Type: schema.TypeSet, Required: true, - ForceNew: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "tags": tagsSchemaForceNew(), "type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{batch.CRTypeEc2, batch.CRTypeSpot}, true), + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: func(val interface{}) string { + return strings.ToUpper(val.(string)) + }, + ValidateFunc: validation.StringInSlice(batch.CRType_Values(), true), }, }, }, @@ -159,18 +169,24 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { ValidateFunc: validateArn, }, "state": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{batch.CEStateEnabled, batch.CEStateDisabled}, true), + Type: schema.TypeString, + Optional: true, + StateFunc: func(val interface{}) string { + return strings.ToUpper(val.(string)) + }, + ValidateFunc: validation.StringInSlice(batch.CEState_Values(), true), Default: batch.CEStateEnabled, }, "tags": tagsSchema(), "tags_all": tagsSchemaComputed(), "type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{batch.CETypeManaged, batch.CETypeUnmanaged}, true), + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: func(val interface{}) string { + return strings.ToUpper(val.(string)) + }, + ValidateFunc: validation.StringInSlice(batch.CEType_Values(), true), }, "arn": { Type: schema.TypeString, @@ -189,8 +205,6 @@ func resourceAwsBatchComputeEnvironment() *schema.Resource { Computed: true, }, }, - - CustomizeDiff: SetTagsDiff, } } @@ -199,26 +213,23 @@ func resourceAwsBatchComputeEnvironmentCreate(d *schema.ResourceData, meta inter defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) - // Build the compute environment name. - var computeEnvironmentName string - if v, ok := d.GetOk("compute_environment_name"); ok { - computeEnvironmentName = v.(string) - } else if v, ok := d.GetOk("compute_environment_name_prefix"); ok { - computeEnvironmentName = resource.PrefixedUniqueId(v.(string)) - } else { - computeEnvironmentName = resource.UniqueId() - } - d.Set("compute_environment_name", computeEnvironmentName) - - serviceRole := d.Get("service_role").(string) + computeEnvironmentName := naming.Generate(d.Get("compute_environment_name").(string), d.Get("compute_environment_name_prefix").(string)) computeEnvironmentType := d.Get("type").(string) input := &batch.CreateComputeEnvironmentInput{ ComputeEnvironmentName: aws.String(computeEnvironmentName), - ServiceRole: aws.String(serviceRole), + ServiceRole: aws.String(d.Get("service_role").(string)), Type: aws.String(computeEnvironmentType), } + // TODO Check in CustomizeDiff that UNMANAGED compute environment has no compute_resources. + // TODO This would be a breaking change. + if computeEnvironmentType := strings.ToUpper(computeEnvironmentType); computeEnvironmentType == batch.CETypeManaged { + if v, ok := d.GetOk("compute_resources"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.ComputeResources = expandBatchComputeResource(v.([]interface{})[0].(map[string]interface{})) + } + } + if v, ok := d.GetOk("state"); ok { input.State = aws.String(v.(string)) } @@ -227,97 +238,17 @@ func resourceAwsBatchComputeEnvironmentCreate(d *schema.ResourceData, meta inter input.Tags = tags.IgnoreAws().BatchTags() } - if computeEnvironmentType == batch.CETypeManaged { - computeResources := d.Get("compute_resources").([]interface{}) - if len(computeResources) == 0 { - return fmt.Errorf("One compute environment is expected, but no compute environments are set") - } - computeResource := computeResources[0].(map[string]interface{}) - - instanceRole := computeResource["instance_role"].(string) - maxvCpus := int64(computeResource["max_vcpus"].(int)) - minvCpus := int64(computeResource["min_vcpus"].(int)) - computeResourceType := computeResource["type"].(string) - - var instanceTypes []*string - for _, v := range computeResource["instance_type"].(*schema.Set).List() { - instanceTypes = append(instanceTypes, aws.String(v.(string))) - } - - var securityGroupIds []*string - for _, v := range computeResource["security_group_ids"].(*schema.Set).List() { - securityGroupIds = append(securityGroupIds, aws.String(v.(string))) - } - - var subnets []*string - for _, v := range computeResource["subnets"].(*schema.Set).List() { - subnets = append(subnets, aws.String(v.(string))) - } - - input.ComputeResources = &batch.ComputeResource{ - InstanceRole: aws.String(instanceRole), - InstanceTypes: instanceTypes, - MaxvCpus: aws.Int64(maxvCpus), - MinvCpus: aws.Int64(minvCpus), - SecurityGroupIds: securityGroupIds, - Subnets: subnets, - Type: aws.String(computeResourceType), - } - - if v, ok := computeResource["allocation_strategy"]; ok { - input.ComputeResources.AllocationStrategy = aws.String(v.(string)) - } - if v, ok := computeResource["bid_percentage"]; ok { - input.ComputeResources.BidPercentage = aws.Int64(int64(v.(int))) - } - if v, ok := computeResource["desired_vcpus"]; ok && v.(int) > 0 { - input.ComputeResources.DesiredvCpus = aws.Int64(int64(v.(int))) - } - if v, ok := computeResource["ec2_key_pair"]; ok { - input.ComputeResources.Ec2KeyPair = aws.String(v.(string)) - } - if v, ok := computeResource["image_id"]; ok { - input.ComputeResources.ImageId = aws.String(v.(string)) - } - if v, ok := computeResource["spot_iam_fleet_role"]; ok { - input.ComputeResources.SpotIamFleetRole = aws.String(v.(string)) - } - if v, ok := computeResource["tags"]; ok { - input.ComputeResources.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().BatchTags() - } - - if raw, ok := computeResource["launch_template"]; ok && len(raw.([]interface{})) > 0 { - input.ComputeResources.LaunchTemplate = &batch.LaunchTemplateSpecification{} - launchTemplate := raw.([]interface{})[0].(map[string]interface{}) - if v, ok := launchTemplate["launch_template_id"]; ok { - input.ComputeResources.LaunchTemplate.LaunchTemplateId = aws.String(v.(string)) - } - if v, ok := launchTemplate["launch_template_name"]; ok { - input.ComputeResources.LaunchTemplate.LaunchTemplateName = aws.String(v.(string)) - } - if v, ok := launchTemplate["version"]; ok { - input.ComputeResources.LaunchTemplate.Version = aws.String(v.(string)) - } - } - } - - log.Printf("[DEBUG] Create compute environment %s.\n", input) + log.Printf("[DEBUG] Creating Batch Compute Environment: %s", input) + output, err := conn.CreateComputeEnvironment(input) - if _, err := conn.CreateComputeEnvironment(input); err != nil { - return err + if err != nil { + return fmt.Errorf("error creating Batch Compute Environment (%s): %w", computeEnvironmentName, err) } - d.SetId(computeEnvironmentName) + d.SetId(aws.StringValue(output.ComputeEnvironmentName)) - stateConf := &resource.StateChangeConf{ - Pending: []string{batch.CEStatusCreating}, - Target: []string{batch.CEStatusValid}, - Refresh: resourceAwsBatchComputeEnvironmentStatusRefreshFunc(computeEnvironmentName, conn), - Timeout: d.Timeout(schema.TimeoutCreate), - MinTimeout: 5 * time.Second, - } - if _, err := stateConf.WaitForState(); err != nil { - return err + if _, err := waiter.ComputeEnvironmentCreated(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return fmt.Errorf("error waiting for Batch Compute Environment (%s) create: %w", d.Id(), err) } return resourceAwsBatchComputeEnvironmentRead(d, meta) @@ -328,32 +259,40 @@ func resourceAwsBatchComputeEnvironmentRead(d *schema.ResourceData, meta interfa defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - computeEnvironmentName := d.Get("compute_environment_name").(string) + computeEnvironment, err := finder.ComputeEnvironmentDetailByName(conn, d.Id()) - input := &batch.DescribeComputeEnvironmentsInput{ - ComputeEnvironments: []*string{ - aws.String(computeEnvironmentName), - }, + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Batch Compute Environment (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil } - log.Printf("[DEBUG] Read compute environment %s.\n", input) - - result, err := conn.DescribeComputeEnvironments(input) - if err != nil { return fmt.Errorf("error reading Batch Compute Environment (%s): %w", d.Id(), err) } - if len(result.ComputeEnvironments) == 0 { - log.Printf("[WARN] Batch Compute Environment (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } - - computeEnvironment := result.ComputeEnvironments[0] + computeEnvironmentType := aws.StringValue(computeEnvironment.Type) + d.Set("arn", computeEnvironment.ComputeEnvironmentArn) + d.Set("compute_environment_name", computeEnvironment.ComputeEnvironmentName) + d.Set("compute_environment_name_prefix", naming.NamePrefixFromName(aws.StringValue(computeEnvironment.ComputeEnvironmentName))) + d.Set("ecs_cluster_arn", computeEnvironment.EcsClusterArn) d.Set("service_role", computeEnvironment.ServiceRole) d.Set("state", computeEnvironment.State) + d.Set("status", computeEnvironment.Status) + d.Set("status_reason", computeEnvironment.StatusReason) + d.Set("type", computeEnvironmentType) + + // TODO See above on how to remove check on type. + if computeEnvironmentType == batch.CETypeManaged { + if computeEnvironment.ComputeResources != nil { + if err := d.Set("compute_resources", []interface{}{flattenBatchComputeResource(computeEnvironment.ComputeResources)}); err != nil { + return fmt.Errorf("error setting compute_resources: %w", err) + } + } else { + d.Set("compute_resources", nil) + } + } tags := keyvaluetags.BatchKeyValueTags(computeEnvironment.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) @@ -366,120 +305,60 @@ func resourceAwsBatchComputeEnvironmentRead(d *schema.ResourceData, meta interfa return fmt.Errorf("error setting tags_all: %w", err) } - d.Set("type", computeEnvironment.Type) - - if aws.StringValue(computeEnvironment.Type) == batch.CETypeManaged { - if err := d.Set("compute_resources", flattenBatchComputeResources(computeEnvironment.ComputeResources)); err != nil { - return fmt.Errorf("error setting compute_resources: %s", err) - } - } - - d.Set("arn", computeEnvironment.ComputeEnvironmentArn) - d.Set("ecs_cluster_arn", computeEnvironment.EcsClusterArn) - d.Set("status", computeEnvironment.Status) - d.Set("status_reason", computeEnvironment.StatusReason) - - return nil -} - -func flattenBatchComputeResources(computeResource *batch.ComputeResource) []map[string]interface{} { - result := make([]map[string]interface{}, 0) - m := make(map[string]interface{}) - - m["allocation_strategy"] = aws.StringValue(computeResource.AllocationStrategy) - m["bid_percentage"] = int(aws.Int64Value(computeResource.BidPercentage)) - m["desired_vcpus"] = int(aws.Int64Value(computeResource.DesiredvCpus)) - m["ec2_key_pair"] = aws.StringValue(computeResource.Ec2KeyPair) - m["image_id"] = aws.StringValue(computeResource.ImageId) - m["instance_role"] = aws.StringValue(computeResource.InstanceRole) - m["instance_type"] = flattenStringSet(computeResource.InstanceTypes) - m["max_vcpus"] = int(aws.Int64Value(computeResource.MaxvCpus)) - m["min_vcpus"] = int(aws.Int64Value(computeResource.MinvCpus)) - m["security_group_ids"] = flattenStringSet(computeResource.SecurityGroupIds) - m["spot_iam_fleet_role"] = aws.StringValue(computeResource.SpotIamFleetRole) - m["subnets"] = flattenStringSet(computeResource.Subnets) - m["tags"] = keyvaluetags.BatchKeyValueTags(computeResource.Tags).IgnoreAws().Map() - m["type"] = aws.StringValue(computeResource.Type) - - if launchTemplate := computeResource.LaunchTemplate; launchTemplate != nil { - lt := make(map[string]interface{}) - lt["launch_template_id"] = aws.StringValue(launchTemplate.LaunchTemplateId) - lt["launch_template_name"] = aws.StringValue(launchTemplate.LaunchTemplateName) - lt["version"] = aws.StringValue(launchTemplate.Version) - m["launch_template"] = []map[string]interface{}{lt} - } - - result = append(result, m) - return result -} - -func resourceAwsBatchComputeEnvironmentDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).batchconn - computeEnvironmentName := d.Get("compute_environment_name").(string) - - log.Printf("[DEBUG] Disabling Batch Compute Environment: %s", computeEnvironmentName) - err := disableBatchComputeEnvironment(computeEnvironmentName, d.Timeout(schema.TimeoutDelete), conn) - if err != nil { - return fmt.Errorf("error disabling Batch Compute Environment (%s): %s", computeEnvironmentName, err) - } - - log.Printf("[DEBUG] Deleting Batch Compute Environment: %s", computeEnvironmentName) - err = deleteBatchComputeEnvironment(computeEnvironmentName, d.Timeout(schema.TimeoutDelete), conn) - if err != nil { - return fmt.Errorf("error deleting Batch Compute Environment (%s): %s", computeEnvironmentName, err) - } - return nil } func resourceAwsBatchComputeEnvironmentUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).batchconn - if d.HasChanges("compute_resources", "service_role", "state") { - computeEnvironmentName := d.Get("compute_environment_name").(string) - + if d.HasChangesExcept("tags", "tags_all") { input := &batch.UpdateComputeEnvironmentInput{ - ComputeEnvironment: aws.String(computeEnvironmentName), - ComputeResources: &batch.ComputeResourceUpdate{}, + ComputeEnvironment: aws.String(d.Id()), } if d.HasChange("service_role") { input.ServiceRole = aws.String(d.Get("service_role").(string)) } + if d.HasChange("state") { input.State = aws.String(d.Get("state").(string)) } - if d.HasChange("compute_resources") { - computeResources := d.Get("compute_resources").([]interface{}) - if len(computeResources) == 0 { - return fmt.Errorf("One compute environment is expected, but no compute environments are set") - } - computeResource := computeResources[0].(map[string]interface{}) + // TODO See above on how to remove check on type. + if computeEnvironmentType := strings.ToUpper(d.Get("type").(string)); computeEnvironmentType == batch.CETypeManaged { + if d.HasChange("compute_resources") { + computeResourceUpdate := &batch.ComputeResourceUpdate{} - if d.HasChange("compute_resources.0.desired_vcpus") { - input.ComputeResources.DesiredvCpus = aws.Int64(int64(computeResource["desired_vcpus"].(int))) - } + if d.HasChange("compute_resources.0.desired_vcpus") { + computeResourceUpdate.DesiredvCpus = aws.Int64(int64(d.Get("compute_resources.0.desired_vcpus").(int))) + } - input.ComputeResources.MaxvCpus = aws.Int64(int64(computeResource["max_vcpus"].(int))) - input.ComputeResources.MinvCpus = aws.Int64(int64(computeResource["min_vcpus"].(int))) - } + if d.HasChange("compute_resources.0.max_vcpus") { + computeResourceUpdate.MaxvCpus = aws.Int64(int64(d.Get("compute_resources.0.max_vcpus").(int))) + } - log.Printf("[DEBUG] Update compute environment %s.\n", input) + if d.HasChange("compute_resources.0.min_vcpus") { + computeResourceUpdate.MinvCpus = aws.Int64(int64(d.Get("compute_resources.0.min_vcpus").(int))) + } - if _, err := conn.UpdateComputeEnvironment(input); err != nil { - return fmt.Errorf("error updating Batch Compute Environment (%s): %w", d.Id(), err) + if d.HasChange("compute_resources.0.security_group_ids") { + computeResourceUpdate.SecurityGroupIds = expandStringSet(d.Get("compute_resources.0.security_group_ids").(*schema.Set)) + } + + if d.HasChange("compute_resources.0.subnets") { + computeResourceUpdate.Subnets = expandStringSet(d.Get("compute_resources.0.subnets").(*schema.Set)) + } + + input.ComputeResources = computeResourceUpdate + } } - stateConf := &resource.StateChangeConf{ - Pending: []string{batch.CEStatusUpdating}, - Target: []string{batch.CEStatusValid}, - Refresh: resourceAwsBatchComputeEnvironmentStatusRefreshFunc(computeEnvironmentName, conn), - Timeout: d.Timeout(schema.TimeoutUpdate), - MinTimeout: 5 * time.Second, + log.Printf("[DEBUG] Updating Batch Compute Environment: %s", input) + if _, err := conn.UpdateComputeEnvironment(input); err != nil { + return fmt.Errorf("error updating Batch Compute Environment (%s): %w", d.Id(), err) } - if _, err := stateConf.WaitForState(); err != nil { + if _, err := waiter.ComputeEnvironmentUpdated(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { return fmt.Errorf("error waiting for Batch Compute Environment (%s) update: %w", d.Id(), err) } } @@ -488,90 +367,264 @@ func resourceAwsBatchComputeEnvironmentUpdate(d *schema.ResourceData, meta inter o, n := d.GetChange("tags_all") if err := keyvaluetags.BatchUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating tags: %s", err) + return fmt.Errorf("error updating tags: %w", err) } } return resourceAwsBatchComputeEnvironmentRead(d, meta) } -func resourceAwsBatchComputeEnvironmentStatusRefreshFunc(computeEnvironmentName string, conn *batch.Batch) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - result, err := conn.DescribeComputeEnvironments(&batch.DescribeComputeEnvironmentsInput{ - ComputeEnvironments: []*string{ - aws.String(computeEnvironmentName), - }, - }) - if err != nil { - return nil, "failed", err +func resourceAwsBatchComputeEnvironmentDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).batchconn + + log.Printf("[DEBUG] Disabling Batch Compute Environment (%s)", d.Id()) + { + input := &batch.UpdateComputeEnvironmentInput{ + ComputeEnvironment: aws.String(d.Id()), + State: aws.String(batch.CEStateDisabled), } - if len(result.ComputeEnvironments) == 0 { - return nil, "failed", fmt.Errorf("One compute environment is expected, but AWS return no compute environment") + if _, err := conn.UpdateComputeEnvironment(input); err != nil { + return fmt.Errorf("error disabling Batch Compute Environment (%s): %w", d.Id(), err) } - computeEnvironment := result.ComputeEnvironments[0] - return result, *(computeEnvironment.Status), nil + if _, err := waiter.ComputeEnvironmentDisabled(conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return fmt.Errorf("error waiting for Batch Compute Environment (%s) disable: %w", d.Id(), err) + } } + + log.Printf("[DEBUG] Deleting Batch Compute Environment (%s)", d.Id()) + { + input := &batch.DeleteComputeEnvironmentInput{ + ComputeEnvironment: aws.String(d.Id()), + } + + if _, err := conn.DeleteComputeEnvironment(input); err != nil { + return fmt.Errorf("error deleting Batch Compute Environment (%s): %w", d.Id(), err) + } + + if _, err := waiter.ComputeEnvironmentDeleted(conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return fmt.Errorf("error waiting for Batch Compute Environment (%s) delete: %w", d.Id(), err) + } + } + + return nil } -func resourceAwsBatchComputeEnvironmentDeleteRefreshFunc(computeEnvironmentName string, conn *batch.Batch) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - result, err := conn.DescribeComputeEnvironments(&batch.DescribeComputeEnvironmentsInput{ - ComputeEnvironments: []*string{ - aws.String(computeEnvironmentName), - }, - }) - if err != nil { - return nil, "failed", err +func resourceAwsBatchComputeEnvironmentCustomizeDiff(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { + if diff.Id() != "" { + // Update. + + computeResourceType := strings.ToUpper(diff.Get("compute_resources.0.type").(string)) + fargateComputeResources := false + if computeResourceType == batch.CRTypeFargate || computeResourceType == batch.CRTypeFargateSpot { + fargateComputeResources = true } - if len(result.ComputeEnvironments) == 0 { - return result, batch.CEStatusDeleted, nil + if diff.HasChange("compute_resources.0.security_group_ids") && !fargateComputeResources { + if err := diff.ForceNew("compute_resources.0.security_group_ids"); err != nil { + return err + } } - computeEnvironment := result.ComputeEnvironments[0] - return result, *(computeEnvironment.Status), nil + if diff.HasChange("compute_resources.0.subnets") && !fargateComputeResources { + if err := diff.ForceNew("compute_resources.0.subnets"); err != nil { + return err + } + } + } + + return nil +} + +func expandBatchComputeResource(tfMap map[string]interface{}) *batch.ComputeResource { + if tfMap == nil { + return nil + } + + var computeResourceType string + + if v, ok := tfMap["type"].(string); ok && v != "" { + computeResourceType = v + } + + apiObject := &batch.ComputeResource{} + + if v, ok := tfMap["allocation_strategy"].(string); ok && v != "" { + apiObject.AllocationStrategy = aws.String(v) + } + + if v, ok := tfMap["bid_percentage"].(int); ok && v != 0 { + apiObject.BidPercentage = aws.Int64(int64(v)) + } + + if v, ok := tfMap["desired_vcpus"].(int); ok && v != 0 { + apiObject.DesiredvCpus = aws.Int64(int64(v)) + } + + if v, ok := tfMap["ec2_key_pair"].(string); ok && v != "" { + apiObject.Ec2KeyPair = aws.String(v) + } + + if v, ok := tfMap["image_id"].(string); ok && v != "" { + apiObject.ImageId = aws.String(v) + } + + if v, ok := tfMap["instance_role"].(string); ok && v != "" { + apiObject.InstanceRole = aws.String(v) + } + + if v, ok := tfMap["instance_type"].(*schema.Set); ok && v.Len() > 0 { + apiObject.InstanceTypes = expandStringSet(v) + } + + if v, ok := tfMap["launch_template"].([]interface{}); ok && len(v) > 0 { + apiObject.LaunchTemplate = expandBatchLaunchTemplateSpecification(v[0].(map[string]interface{})) + } + + if v, ok := tfMap["max_vcpus"].(int); ok && v != 0 { + apiObject.MaxvCpus = aws.Int64(int64(v)) + } + + if v, ok := tfMap["min_vcpus"].(int); ok && v != 0 { + apiObject.MinvCpus = aws.Int64(int64(v)) + } else if computeResourceType := strings.ToUpper(computeResourceType); computeResourceType == batch.CRTypeEc2 || computeResourceType == batch.CRTypeSpot { + apiObject.MinvCpus = aws.Int64(0) } + + if v, ok := tfMap["security_group_ids"].(*schema.Set); ok && v.Len() > 0 { + apiObject.SecurityGroupIds = expandStringSet(v) + } + + if v, ok := tfMap["spot_iam_fleet_role"].(string); ok && v != "" { + apiObject.SpotIamFleetRole = aws.String(v) + } + + if v, ok := tfMap["subnets"].(*schema.Set); ok && v.Len() > 0 { + apiObject.Subnets = expandStringSet(v) + } + + if v, ok := tfMap["tags"].(map[string]interface{}); ok && len(v) > 0 { + apiObject.Tags = keyvaluetags.New(v).IgnoreAws().BatchTags() + } + + if computeResourceType != "" { + apiObject.Type = aws.String(computeResourceType) + } + + return apiObject } -func deleteBatchComputeEnvironment(computeEnvironment string, timeout time.Duration, conn *batch.Batch) error { - input := &batch.DeleteComputeEnvironmentInput{ - ComputeEnvironment: aws.String(computeEnvironment), +func expandBatchLaunchTemplateSpecification(tfMap map[string]interface{}) *batch.LaunchTemplateSpecification { + if tfMap == nil { + return nil + } + + apiObject := &batch.LaunchTemplateSpecification{} + + if v, ok := tfMap["launch_template_id"].(string); ok && v != "" { + apiObject.LaunchTemplateId = aws.String(v) } - if _, err := conn.DeleteComputeEnvironment(input); err != nil { - return err + if v, ok := tfMap["launch_template_name"].(string); ok && v != "" { + apiObject.LaunchTemplateName = aws.String(v) } - stateChangeConf := &resource.StateChangeConf{ - Pending: []string{batch.CEStatusDeleting}, - Target: []string{batch.CEStatusDeleted}, - Refresh: resourceAwsBatchComputeEnvironmentDeleteRefreshFunc(computeEnvironment, conn), - Timeout: timeout, - MinTimeout: 5 * time.Second, + if v, ok := tfMap["version"].(string); ok && v != "" { + apiObject.Version = aws.String(v) } - _, err := stateChangeConf.WaitForState() - return err + + return apiObject } -func disableBatchComputeEnvironment(computeEnvironment string, timeout time.Duration, conn *batch.Batch) error { - input := &batch.UpdateComputeEnvironmentInput{ - ComputeEnvironment: aws.String(computeEnvironment), - State: aws.String(batch.CEStateDisabled), +func flattenBatchComputeResource(apiObject *batch.ComputeResource) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.AllocationStrategy; v != nil { + tfMap["allocation_strategy"] = aws.StringValue(v) + } + + if v := apiObject.BidPercentage; v != nil { + tfMap["bid_percentage"] = aws.Int64Value(v) } - if _, err := conn.UpdateComputeEnvironment(input); err != nil { - return err + if v := apiObject.DesiredvCpus; v != nil { + tfMap["desired_vcpus"] = aws.Int64Value(v) } - stateChangeConf := &resource.StateChangeConf{ - Pending: []string{batch.CEStatusUpdating}, - Target: []string{batch.CEStatusValid}, - Refresh: resourceAwsBatchComputeEnvironmentStatusRefreshFunc(computeEnvironment, conn), - Timeout: timeout, - MinTimeout: 5 * time.Second, + if v := apiObject.Ec2KeyPair; v != nil { + tfMap["ec2_key_pair"] = aws.StringValue(v) } - _, err := stateChangeConf.WaitForState() - return err + + if v := apiObject.ImageId; v != nil { + tfMap["image_id"] = aws.StringValue(v) + } + + if v := apiObject.InstanceRole; v != nil { + tfMap["instance_role"] = aws.StringValue(v) + } + + if v := apiObject.InstanceTypes; v != nil { + tfMap["instance_type"] = aws.StringValueSlice(v) + } + + if v := apiObject.LaunchTemplate; v != nil { + tfMap["launch_template"] = []interface{}{flattenBatchLaunchTemplateSpecification(v)} + } + + if v := apiObject.MaxvCpus; v != nil { + tfMap["max_vcpus"] = aws.Int64Value(v) + } + + if v := apiObject.MinvCpus; v != nil { + tfMap["min_vcpus"] = aws.Int64Value(v) + } + + if v := apiObject.SecurityGroupIds; v != nil { + tfMap["security_group_ids"] = aws.StringValueSlice(v) + } + + if v := apiObject.SpotIamFleetRole; v != nil { + tfMap["spot_iam_fleet_role"] = aws.StringValue(v) + } + + if v := apiObject.Subnets; v != nil { + tfMap["subnets"] = aws.StringValueSlice(v) + } + + if v := apiObject.Tags; v != nil { + tfMap["tags"] = keyvaluetags.BatchKeyValueTags(v).IgnoreAws().Map() + } + + if v := apiObject.Type; v != nil { + tfMap["type"] = aws.StringValue(v) + } + + return tfMap +} + +func flattenBatchLaunchTemplateSpecification(apiObject *batch.LaunchTemplateSpecification) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.LaunchTemplateId; v != nil { + tfMap["launch_template_id"] = aws.StringValue(v) + } + + if v := apiObject.LaunchTemplateName; v != nil { + tfMap["launch_template_name"] = aws.StringValue(v) + } + + if v := apiObject.Version; v != nil { + tfMap["version"] = aws.StringValue(v) + } + + return tfMap } diff --git a/aws/resource_aws_batch_compute_environment_test.go b/aws/resource_aws_batch_compute_environment_test.go index e133af5641b..63e04501c05 100644 --- a/aws/resource_aws_batch_compute_environment_test.go +++ b/aws/resource_aws_batch_compute_environment_test.go @@ -15,6 +15,9 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/naming" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/batch/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func init() { @@ -151,9 +154,11 @@ func testSweepBatchComputeEnvironments(region string) error { return sweeperErrs.ErrorOrNil() } -func TestAccAWSBatchComputeEnvironment_disappears(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_basic(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + serviceRoleResourceName := "aws_iam_role.batch_service" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -162,20 +167,30 @@ func TestAccAWSBatchComputeEnvironment_disappears(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigEC2(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigBasic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - testAccCheckResourceDisappears(testAccProvider, resourceAwsBatchComputeEnvironment(), resourceName), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.#", "0"), + 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", "UNMANAGED"), ), - ExpectNonEmptyPlan: true, }, }, }) } -func TestAccAWSBatchComputeEnvironment_createEc2(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_disappears(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -184,18 +199,21 @@ func TestAccAWSBatchComputeEnvironment_createEc2(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigEC2(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigBasic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceDisappears(testAccProvider, resourceAwsBatchComputeEnvironment(), resourceName), ), + ExpectNonEmptyPlan: true, }, }, }) } -func TestAccAWSBatchComputeEnvironment_createWithNamePrefix(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSBatchComputeEnvironment_NameGenerated(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -204,21 +222,27 @@ func TestAccAWSBatchComputeEnvironment_createWithNamePrefix(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigNamePrefix(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigNameGenerated(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestMatchResourceAttr( - "aws_batch_compute_environment.ec2", "compute_environment_name", regexp.MustCompile("^tf_acc_test"), - ), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + naming.TestCheckResourceAttrNameGenerated(resourceName, "compute_environment_name"), + resource.TestCheckResourceAttr(resourceName, "compute_environment_name_prefix", "terraform-"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAWSBatchComputeEnvironment_createEc2WithTags(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_NamePrefix(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, ErrorCheck: testAccErrorCheck(t, batch.EndpointsID), @@ -226,11 +250,11 @@ func TestAccAWSBatchComputeEnvironment_createEc2WithTags(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigEC2WithTags(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigNamePrefix(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.tags.Key1", "Value1"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + naming.TestCheckResourceAttrNameFromPrefix(resourceName, "compute_environment_name", rName), + resource.TestCheckResourceAttr(resourceName, "compute_environment_name_prefix", rName), ), }, { @@ -242,8 +266,14 @@ func TestAccAWSBatchComputeEnvironment_createEc2WithTags(t *testing.T) { }) } -func TestAccAWSBatchComputeEnvironment_createSpot(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSBatchComputeEnvironment_createEc2(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + instanceProfileResourceName := "aws_iam_instance_profile.ecs_instance" + securityGroupResourceName := "aws_security_group.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + subnetResourceName := "aws_subnet.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -252,17 +282,59 @@ func TestAccAWSBatchComputeEnvironment_createSpot(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigSpot(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigEC2(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.*", "c4.large"), + 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.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", ""), + 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", "EC2"), + 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 TestAccAWSBatchComputeEnvironment_createUnmanaged(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSBatchComputeEnvironment_createEc2_DesiredVcpus_Ec2KeyPair_ImageId_ComputeResourcesTags(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + amiDatasourceName := "data.aws_ami.amzn-ami-minimal-hvm-ebs" + instanceProfileResourceName := "aws_iam_instance_profile.ecs_instance" + keyPairResourceName := "aws_key_pair.test" + securityGroupResourceName := "aws_security_group.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + subnetResourceName := "aws_subnet.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -271,18 +343,59 @@ func TestAccAWSBatchComputeEnvironment_createUnmanaged(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigUnmanaged(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigEC2WithDesiredVcpusEc2KeyPairImageIdAndComputeResourcesTags(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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", "8"), + resource.TestCheckResourceAttrPair(resourceName, "compute_resources.0.ec2_key_pair", keyPairResourceName, "id"), + resource.TestCheckResourceAttrPair(resourceName, "compute_resources.0.image_id", amiDatasourceName, "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.*", "c4.large"), + 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", "4"), + 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", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.subnets.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.subnets.*", subnetResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.tags.key1", "value1"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.type", "EC2"), + 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 TestAccAWSBatchComputeEnvironment_ComputeResources_DesiredVcpus_Computed(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_createSpot(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + 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() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -291,21 +404,38 @@ func TestAccAWSBatchComputeEnvironment_ComputeResources_DesiredVcpus_Computed(t CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 8, 4), + Config: testAccAWSBatchComputeEnvironmentConfigSpot(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - ), - }, - { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 4, 2), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - ), - }, - { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 8, 8), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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", "2"), + 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.*", "c4.large"), + 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", "2"), + 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"), ), }, { @@ -317,9 +447,15 @@ func TestAccAWSBatchComputeEnvironment_ComputeResources_DesiredVcpus_Computed(t }) } -func TestAccAWSBatchComputeEnvironment_ComputeResources_MinVcpus(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_createSpot_AllocationStrategy_BidPercentage(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + 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() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -328,24 +464,38 @@ func TestAccAWSBatchComputeEnvironment_ComputeResources_MinVcpus(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 4, 0), + Config: testAccAWSBatchComputeEnvironmentConfigSpotWithAllocationStrategyAndBidPercentage(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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", "BEST_FIT"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.bid_percentage", "60"), + 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.*", "c4.large"), + 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"), - ), - }, - { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 4, 4), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.min_vcpus", "4"), - ), - }, - { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 4, 2), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.min_vcpus", "2"), + 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"), ), }, { @@ -357,9 +507,13 @@ func TestAccAWSBatchComputeEnvironment_ComputeResources_MinVcpus(t *testing.T) { }) } -func TestAccAWSBatchComputeEnvironment_ComputeResources_MaxVcpus(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_createFargate(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + securityGroupResourceName := "aws_security_group.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + subnetResourceName := "aws_subnet.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -368,24 +522,37 @@ func TestAccAWSBatchComputeEnvironment_ComputeResources_MaxVcpus(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 4, 0), + Config: testAccAWSBatchComputeEnvironmentConfigFargate(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "4"), - ), - }, - { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 8, 0), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "8"), - ), - }, - { - Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rInt, 2, 0), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "2"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_role", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_type.#", "0"), + 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.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", ""), + 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", "FARGATE"), + 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"), ), }, { @@ -397,9 +564,13 @@ func TestAccAWSBatchComputeEnvironment_ComputeResources_MaxVcpus(t *testing.T) { }) } -func TestAccAWSBatchComputeEnvironment_updateInstanceType(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_createFargateSpot(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + securityGroupResourceName := "aws_security_group.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + subnetResourceName := "aws_subnet.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -408,17 +579,37 @@ func TestAccAWSBatchComputeEnvironment_updateInstanceType(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigEC2(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigFargateSpot(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_type.#", "1"), - ), - }, - { - Config: testAccAWSBatchComputeEnvironmentConfigEC2UpdateInstanceType(rInt), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_type.#", "2"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_role", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_type.#", "0"), + 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.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", ""), + 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", "FARGATE_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"), ), }, { @@ -430,11 +621,11 @@ func TestAccAWSBatchComputeEnvironment_updateInstanceType(t *testing.T) { }) } -func TestAccAWSBatchComputeEnvironment_updateComputeEnvironmentName(t *testing.T) { - rInt := acctest.RandInt() - expectedName := fmt.Sprintf("tf_acc_test_%d", rInt) - expectedUpdatedName := fmt.Sprintf("tf_acc_test_updated_%d", rInt) - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_updateState(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + serviceRoleResourceName := "aws_iam_role.batch_service" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -443,17 +634,37 @@ func TestAccAWSBatchComputeEnvironment_updateComputeEnvironmentName(t *testing.T CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigEC2(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigState(rName, "ENABLED"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_environment_name", expectedName), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.#", "0"), + 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", "UNMANAGED"), ), }, { - Config: testAccAWSBatchComputeEnvironmentConfigEC2UpdateComputeEnvironmentName(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigState(rName, "disabled"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_environment_name", expectedUpdatedName), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "ecs_cluster_arn"), + resource.TestCheckResourceAttrPair(resourceName, "service_role", serviceRoleResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "state", "DISABLED"), + resource.TestCheckResourceAttrSet(resourceName, "status"), + resource.TestCheckResourceAttrSet(resourceName, "status_reason"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "type", "UNMANAGED"), ), }, { @@ -465,8 +676,12 @@ func TestAccAWSBatchComputeEnvironment_updateComputeEnvironmentName(t *testing.T }) } -func TestAccAWSBatchComputeEnvironment_createEc2WithoutComputeResources(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSBatchComputeEnvironment_updateServiceRole(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + serviceRoleResourceName1 := "aws_iam_role.batch_service" + serviceRoleResourceName2 := "aws_iam_role.batch_service_2" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -475,36 +690,56 @@ func TestAccAWSBatchComputeEnvironment_createEc2WithoutComputeResources(t *testi CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigEC2WithoutComputeResources(rInt), - ExpectError: regexp.MustCompile(`One compute environment is expected, but no compute environments are set`), + Config: testAccAWSBatchComputeEnvironmentConfigBasic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "ecs_cluster_arn"), + resource.TestCheckResourceAttrPair(resourceName, "service_role", serviceRoleResourceName1, "arn"), + resource.TestCheckResourceAttr(resourceName, "state", "ENABLED"), + resource.TestCheckResourceAttrSet(resourceName, "status"), + resource.TestCheckResourceAttrSet(resourceName, "status_reason"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "type", "UNMANAGED"), + ), }, - }, - }) -} - -func TestAccAWSBatchComputeEnvironment_createUnmanagedWithComputeResources(t *testing.T) { - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, - ErrorCheck: testAccErrorCheck(t, batch.EndpointsID), - Providers: testAccProviders, - CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, - Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigUnmanagedWithComputeResources(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigUpdatedServiceRole(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr("aws_batch_compute_environment.unmanaged", "type", "UNMANAGED"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "ecs_cluster_arn"), + resource.TestCheckResourceAttrPair(resourceName, "service_role", serviceRoleResourceName2, "arn"), + resource.TestCheckResourceAttr(resourceName, "state", "ENABLED"), + resource.TestCheckResourceAttrSet(resourceName, "status"), + resource.TestCheckResourceAttrSet(resourceName, "status_reason"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "type", "UNMANAGED"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } -func TestAccAWSBatchComputeEnvironment_launchTemplate(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_ComputeResources_MinVcpus(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + instanceProfileResourceName := "aws_iam_instance_profile.ecs_instance" + securityGroupResourceName := "aws_security_group.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + subnetResourceName := "aws_subnet.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -513,15 +748,108 @@ func TestAccAWSBatchComputeEnvironment_launchTemplate(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigLaunchTemplate(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rName, 4, 0), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, - "compute_resources.0.launch_template.#", - "1"), - resource.TestCheckResourceAttr(resourceName, - "compute_resources.0.launch_template.0.launch_template_name", - fmt.Sprintf("tf_acc_test_%d", rInt)), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.launch_template.#", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "4"), + 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.TestCheckResourceAttr(resourceName, "compute_resources.0.spot_iam_fleet_role", ""), + 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", "EC2"), + 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"), + ), + }, + { + Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rName, 4, 4), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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", "4"), + 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.launch_template.#", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "4"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.min_vcpus", "4"), + 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", ""), + 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", "EC2"), + 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"), + ), + }, + { + Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rName, 4, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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", "4"), + 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.launch_template.#", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "4"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.min_vcpus", "2"), + 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", ""), + 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", "EC2"), + 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"), ), }, { @@ -533,9 +861,14 @@ func TestAccAWSBatchComputeEnvironment_launchTemplate(t *testing.T) { }) } -func TestAccAWSBatchComputeEnvironment_UpdateLaunchTemplate(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_ComputeResources_MaxVcpus(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + instanceProfileResourceName := "aws_iam_instance_profile.ecs_instance" + securityGroupResourceName := "aws_security_group.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + subnetResourceName := "aws_subnet.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -544,17 +877,108 @@ func TestAccAWSBatchComputeEnvironment_UpdateLaunchTemplate(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentUpdateLaunchTemplateInExistingComputeEnvironment(rInt, "$Default"), + Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rName, 4, 0), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.version", "$Default"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.launch_template.#", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "4"), + 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.TestCheckResourceAttr(resourceName, "compute_resources.0.spot_iam_fleet_role", ""), + 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", "EC2"), + 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"), ), }, { - Config: testAccAWSBatchComputeEnvironmentUpdateLaunchTemplateInExistingComputeEnvironment(rInt, "$Latest"), + Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rName, 8, 0), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.version", "$Latest"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.launch_template.#", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "8"), + 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.TestCheckResourceAttr(resourceName, "compute_resources.0.spot_iam_fleet_role", ""), + 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", "EC2"), + 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"), + ), + }, + { + Config: testAccAWSBatchComputeEnvironmentConfigComputeResourcesMaxVcpusMinVcpus(rName, 2, 0), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.launch_template.#", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.max_vcpus", "2"), + 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.TestCheckResourceAttr(resourceName, "compute_resources.0.spot_iam_fleet_role", ""), + 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", "EC2"), + 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"), ), }, { @@ -566,8 +990,16 @@ func TestAccAWSBatchComputeEnvironment_UpdateLaunchTemplate(t *testing.T) { }) } -func TestAccAWSBatchComputeEnvironment_createSpotWithAllocationStrategy(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSBatchComputeEnvironment_launchTemplate(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + instanceProfileResourceName := "aws_iam_instance_profile.ecs_instance" + launchTemplateResourceName := "aws_launch_template.test" + 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() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -576,18 +1008,62 @@ func TestAccAWSBatchComputeEnvironment_createSpotWithAllocationStrategy(t *testi CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigSpotWithAllocationStrategy(rInt), + Config: testAccAWSBatchComputeEnvironmentConfigLaunchTemplate(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr("aws_batch_compute_environment.ec2", "compute_resources.0.allocation_strategy", "BEST_FIT"), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.*", "c4.large"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.#", "1"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.launch_template_id", ""), + resource.TestCheckResourceAttrPair(resourceName, "compute_resources.0.launch_template.0.launch_template_name", launchTemplateResourceName, "name"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.version", ""), + 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 TestAccAWSBatchComputeEnvironment_createSpotWithoutBidPercentage(t *testing.T) { - rInt := acctest.RandInt() +func TestAccAWSBatchComputeEnvironment_UpdateLaunchTemplate(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + instanceProfileResourceName := "aws_iam_instance_profile.ecs_instance" + launchTemplateResourceName := "aws_launch_template.test" + 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() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -596,16 +1072,100 @@ func TestAccAWSBatchComputeEnvironment_createSpotWithoutBidPercentage(t *testing CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigSpotWithoutBidPercentage(rInt), - ExpectError: regexp.MustCompile(`ComputeResources.spotIamFleetRole cannot not be null or empty`), + Config: testAccAWSBatchComputeEnvironmentUpdateLaunchTemplateInExistingComputeEnvironment(rName, "$Default"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.*", "c4.large"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.#", "1"), + resource.TestCheckResourceAttrPair(resourceName, "compute_resources.0.launch_template.0.launch_template_id", launchTemplateResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.launch_template_name", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.version", "$Default"), + 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"), + ), + }, + { + Config: testAccAWSBatchComputeEnvironmentUpdateLaunchTemplateInExistingComputeEnvironment(rName, "$Latest"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.*", "c4.large"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.#", "1"), + resource.TestCheckResourceAttrPair(resourceName, "compute_resources.0.launch_template.0.launch_template_id", launchTemplateResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.launch_template_name", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.launch_template.0.version", "$Latest"), + 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 TestAccAWSBatchComputeEnvironment_updateState(t *testing.T) { - rInt := acctest.RandInt() - resourceName := "aws_batch_compute_environment.ec2" +func TestAccAWSBatchComputeEnvironment_UpdateSecurityGroupsAndSubnets_Fargate(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + securityGroupResourceName1 := "aws_security_group.test" + securityGroupResourceName2 := "aws_security_group.test_2" + securityGroupResourceName3 := "aws_security_group.test_3" + serviceRoleResourceName := "aws_iam_role.batch_service" + subnetResourceName1 := "aws_subnet.test" + subnetResourceName2 := "aws_subnet.test_2" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, @@ -614,17 +1174,72 @@ func TestAccAWSBatchComputeEnvironment_updateState(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigEC2UpdateState(rInt, batch.CEStateEnabled), + Config: testAccAWSBatchComputeEnvironmentConfigFargate(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "state", batch.CEStateEnabled), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_role", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_type.#", "0"), + 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.security_group_ids.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.security_group_ids.*", securityGroupResourceName1, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.spot_iam_fleet_role", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.subnets.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.subnets.*", subnetResourceName1, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.type", "FARGATE"), + 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"), ), }, { - Config: testAccAWSBatchComputeEnvironmentConfigEC2UpdateState(rInt, batch.CEStateDisabled), + Config: testAccAWSBatchComputeEnvironmentConfigFargateUpdatedSecurityGroupsAndSubnets(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), - resource.TestCheckResourceAttr(resourceName, "state", batch.CEStateDisabled), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_role", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.instance_type.#", "0"), + 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.security_group_ids.#", "2"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.security_group_ids.*", securityGroupResourceName2, "id"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.security_group_ids.*", securityGroupResourceName3, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.spot_iam_fleet_role", ""), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.subnets.#", "1"), + resource.TestCheckTypeSetElemAttrPair(resourceName, "compute_resources.0.subnets.*", subnetResourceName2, "id"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "compute_resources.0.type", "FARGATE"), + 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"), ), }, { @@ -637,7 +1252,8 @@ func TestAccAWSBatchComputeEnvironment_updateState(t *testing.T) { } func TestAccAWSBatchComputeEnvironment_Tags(t *testing.T) { - rInt := acctest.RandInt() + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_batch_compute_environment.test" resource.ParallelTest(t, resource.TestCase{ @@ -647,9 +1263,9 @@ func TestAccAWSBatchComputeEnvironment_Tags(t *testing.T) { CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSBatchComputeEnvironmentConfigTags1(rInt, "key1", "value1"), + Config: testAccAWSBatchComputeEnvironmentConfigTags1(rName, "key1", "value1"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), @@ -660,18 +1276,18 @@ func TestAccAWSBatchComputeEnvironment_Tags(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSBatchComputeEnvironmentConfigTags2(rInt, "key1", "value1updated", "key2", "value2"), + Config: testAccAWSBatchComputeEnvironmentConfigTags2(rName, "key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), }, { - Config: testAccAWSBatchComputeEnvironmentConfigTags1(rInt, "key2", "value2"), + Config: testAccAWSBatchComputeEnvironmentConfigTags1(rName, "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsBatchComputeEnvironmentExists(), + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), @@ -680,6 +1296,76 @@ func TestAccAWSBatchComputeEnvironment_Tags(t *testing.T) { }) } +func TestAccAWSBatchComputeEnvironment_createUnmanagedWithComputeResources(t *testing.T) { + var ce batch.ComputeEnvironmentDetail + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_batch_compute_environment.test" + serviceRoleResourceName := "aws_iam_role.batch_service" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, + ErrorCheck: testAccErrorCheck(t, batch.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSBatchComputeEnvironmentConfigUnmanagedWithComputeResources(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsBatchComputeEnvironmentExists(resourceName, &ce), + testAccCheckResourceAttrRegionalARN(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.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", "UNMANAGED"), + ), + }, + // Can't import in this scenario. + }, + }) +} + +// Test plan time errors... + +func TestAccAWSBatchComputeEnvironment_createEc2WithoutComputeResources(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, + ErrorCheck: testAccErrorCheck(t, batch.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSBatchComputeEnvironmentConfigEC2WithoutComputeResources(rName), + ExpectError: regexp.MustCompile(`computeResources must be provided for a MANAGED compute environment`), + }, + }, + }) +} + +func TestAccAWSBatchComputeEnvironment_createSpotWithoutIamFleetRole(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSBatch(t) }, + ErrorCheck: testAccErrorCheck(t, batch.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckBatchComputeEnvironmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSBatchComputeEnvironmentConfigSpotWithoutIamFleetRole(rName), + ExpectError: regexp.MustCompile(`ComputeResources.spotIamFleetRole cannot not be null or empty`), + }, + }, + }) +} + func testAccCheckBatchComputeEnvironmentDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).batchconn @@ -688,49 +1374,42 @@ func testAccCheckBatchComputeEnvironmentDestroy(s *terraform.State) error { continue } - result, err := conn.DescribeComputeEnvironments(&batch.DescribeComputeEnvironmentsInput{ - ComputeEnvironments: []*string{ - aws.String(rs.Primary.ID), - }, - }) + _, err := finder.ComputeEnvironmentDetailByName(conn, rs.Primary.ID) - if err != nil { - return fmt.Errorf("Error occurred when get compute environment information.") + if tfresource.NotFound(err) { + continue } - if len(result.ComputeEnvironments) == 1 { - return fmt.Errorf("Compute environment still exists.") + + if err != nil { + return err } + return fmt.Errorf("Batch Compute Environment %s still exists", rs.Primary.ID) } - return nil } -func testAccCheckAwsBatchComputeEnvironmentExists() resource.TestCheckFunc { +func testAccCheckAwsBatchComputeEnvironmentExists(n string, v *batch.ComputeEnvironmentDetail) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).batchconn + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } - for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_batch_compute_environment" { - continue - } + if rs.Primary.ID == "" { + return fmt.Errorf("No Batch Compute Environment ID is set") + } - result, err := conn.DescribeComputeEnvironments(&batch.DescribeComputeEnvironmentsInput{ - ComputeEnvironments: []*string{ - aws.String(rs.Primary.ID), - }, - }) + conn := testAccProvider.Meta().(*AWSClient).batchconn - if err != nil { - return fmt.Errorf("Error occurred when get compute environment information.") - } - if len(result.ComputeEnvironments) == 0 { - return fmt.Errorf("Compute environment doesn't exists.") - } else if len(result.ComputeEnvironments) >= 2 { - return fmt.Errorf("Too many compute environments exist.") - } + computeEnvironment, err := finder.ComputeEnvironmentDetailByName(conn, rs.Primary.ID) + + if err != nil { + return err } + *v = *computeEnvironment + return nil } } @@ -751,559 +1430,650 @@ func testAccPreCheckAWSBatch(t *testing.T) { } } -func testAccAWSBatchComputeEnvironmentConfigBase(rInt int) string { +func testAccAWSBatchComputeEnvironmentConfigBase(rName string) string { return fmt.Sprintf(` -data "aws_partition" "current" { -} - -########## ecs_instance_role ########## +data "aws_partition" "current" {} -resource "aws_iam_role" "ecs_instance_role" { - name = "tf_acc_test_batch_inst_role_%d" +resource "aws_iam_role" "ecs_instance" { + name = "%[1]s_ecs_instance" assume_role_policy = <