package aws import ( "fmt" "regexp" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ecs" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" ) func TestParseTaskDefinition(t *testing.T) { cases := map[string]map[string]interface{}{ "invalid": { "family": "", "revision": "", "isValid": false, }, "invalidWithColon:": { "family": "", "revision": "", "isValid": false, }, "1234": { "family": "", "revision": "", "isValid": false, }, "invalid:aaa": { "family": "", "revision": "", "isValid": false, }, "invalid=family:1": { "family": "", "revision": "", "isValid": false, }, "invalid:name:1": { "family": "", "revision": "", "isValid": false, }, "valid:1": { "family": "valid", "revision": "1", "isValid": true, }, "abc12-def:54": { "family": "abc12-def", "revision": "54", "isValid": true, }, "lorem_ip-sum:123": { "family": "lorem_ip-sum", "revision": "123", "isValid": true, }, "lorem-ipsum:1": { "family": "lorem-ipsum", "revision": "1", "isValid": true, }, } for input, expectedOutput := range cases { family, revision, err := parseTaskDefinition(input) isValid := expectedOutput["isValid"].(bool) if !isValid && err == nil { t.Fatalf("Task definition %s should fail", input) } expectedFamily := expectedOutput["family"].(string) if family != expectedFamily { t.Fatalf("Unexpected family (%#v) for task definition %s\n%#v", family, input, err) } expectedRevision := expectedOutput["revision"].(string) if revision != expectedRevision { t.Fatalf("Unexpected revision (%#v) for task definition %s\n%#v", revision, input, err) } } } func TestAccAWSEcsServiceWithARN(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsService, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), ), }, { Config: testAccAWSEcsServiceModified, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), ), }, }, }) } func TestAccAWSEcsServiceWithFamilyAndRevision(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsServiceWithFamilyAndRevision, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.jenkins"), ), }, { Config: testAccAWSEcsServiceWithFamilyAndRevisionModified, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.jenkins"), ), }, }, }) } // Regression for https://github.com/hashicorp/terraform/issues/2427 func TestAccAWSEcsServiceWithRenamedCluster(t *testing.T) { originalRegexp := regexp.MustCompile( "^arn:aws:ecs:[^:]+:[0-9]+:cluster/terraformecstest3$") modifiedRegexp := regexp.MustCompile( "^arn:aws:ecs:[^:]+:[0-9]+:cluster/terraformecstest3modified$") resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsServiceWithRenamedCluster, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost"), resource.TestMatchResourceAttr( "aws_ecs_service.ghost", "cluster", originalRegexp), ), }, { Config: testAccAWSEcsServiceWithRenamedClusterModified, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost"), resource.TestMatchResourceAttr( "aws_ecs_service.ghost", "cluster", modifiedRegexp), ), }, }, }) } func TestAccAWSEcsService_withIamRole(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsService_withIamRole, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost"), ), }, }, }) } func TestAccAWSEcsService_withDeploymentValues(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsServiceWithDeploymentValues, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr( "aws_ecs_service.mongo", "deployment_maximum_percent", "200"), resource.TestCheckResourceAttr( "aws_ecs_service.mongo", "deployment_minimum_healthy_percent", "100"), ), }, }, }) } // Regression for https://github.com/hashicorp/terraform/issues/3444 func TestAccAWSEcsService_withLbChanges(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsService_withLbChanges, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.with_lb_changes"), ), }, { Config: testAccAWSEcsService_withLbChanges_modified, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.with_lb_changes"), ), }, }, }) } // Regression for https://github.com/hashicorp/terraform/issues/3361 func TestAccAWSEcsService_withEcsClusterName(t *testing.T) { clusterName := regexp.MustCompile("^terraformecstestcluster$") resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsServiceWithEcsClusterName, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.jenkins"), resource.TestMatchResourceAttr( "aws_ecs_service.jenkins", "cluster", clusterName), ), }, }, }) } func TestAccAWSEcsService_withAlb(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsServiceWithAlb, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.with_alb"), ), }, }, }) } func TestAccAWSEcsServiceWithPlacementStrategy(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsService, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_strategy.#", "0"), ), }, { Config: testAccAWSEcsServiceWithPlacementStrategy, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_strategy.#", "1"), ), }, }, }) } func TestAccAWSEcsServiceWithPlacementConstraints(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsServiceWithPlacementConstraint, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_constraints.#", "1"), ), }, }, }) } func TestAccAWSEcsServiceWithPlacementConstraints_emptyExpression(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSEcsServiceDestroy, Steps: []resource.TestStep{ { Config: testAccAWSEcsServiceWithPlacementConstraintEmptyExpression, Check: resource.ComposeTestCheckFunc( testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"), resource.TestCheckResourceAttr("aws_ecs_service.mongo", "placement_constraints.#", "1"), ), }, }, }) } func testAccCheckAWSEcsServiceDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ecsconn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_ecs_service" { continue } out, err := conn.DescribeServices(&ecs.DescribeServicesInput{ Services: []*string{aws.String(rs.Primary.ID)}, Cluster: aws.String(rs.Primary.Attributes["cluster"]), }) if err == nil { if len(out.Services) > 0 { var activeServices []*ecs.Service for _, svc := range out.Services { if *svc.Status != "INACTIVE" { activeServices = append(activeServices, svc) } } if len(activeServices) == 0 { return nil } return fmt.Errorf("ECS service still exists:\n%#v", activeServices) } return nil } return err } return nil } func testAccCheckAWSEcsServiceExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { _, ok := s.RootModule().Resources[name] if !ok { return fmt.Errorf("Not found: %s", name) } return nil } } var testAccAWSEcsService = ` resource "aws_ecs_cluster" "default" { name = "terraformecstest1" } resource "aws_ecs_task_definition" "mongo" { family = "mongodb" container_definitions = <