github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/builtin/providers/aws/resource_aws_ecs_service_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"testing"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/ecs"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestParseTaskDefinition(t *testing.T) {
    15  	cases := map[string]map[string]interface{}{
    16  		"invalid": map[string]interface{}{
    17  			"family":   "",
    18  			"revision": "",
    19  			"isValid":  false,
    20  		},
    21  		"invalidWithColon:": map[string]interface{}{
    22  			"family":   "",
    23  			"revision": "",
    24  			"isValid":  false,
    25  		},
    26  		"1234": map[string]interface{}{
    27  			"family":   "",
    28  			"revision": "",
    29  			"isValid":  false,
    30  		},
    31  		"invalid:aaa": map[string]interface{}{
    32  			"family":   "",
    33  			"revision": "",
    34  			"isValid":  false,
    35  		},
    36  		"invalid=family:1": map[string]interface{}{
    37  			"family":   "",
    38  			"revision": "",
    39  			"isValid":  false,
    40  		},
    41  		"invalid:name:1": map[string]interface{}{
    42  			"family":   "",
    43  			"revision": "",
    44  			"isValid":  false,
    45  		},
    46  		"valid:1": map[string]interface{}{
    47  			"family":   "valid",
    48  			"revision": "1",
    49  			"isValid":  true,
    50  		},
    51  		"abc12-def:54": map[string]interface{}{
    52  			"family":   "abc12-def",
    53  			"revision": "54",
    54  			"isValid":  true,
    55  		},
    56  		"lorem_ip-sum:123": map[string]interface{}{
    57  			"family":   "lorem_ip-sum",
    58  			"revision": "123",
    59  			"isValid":  true,
    60  		},
    61  		"lorem-ipsum:1": map[string]interface{}{
    62  			"family":   "lorem-ipsum",
    63  			"revision": "1",
    64  			"isValid":  true,
    65  		},
    66  	}
    67  
    68  	for input, expectedOutput := range cases {
    69  		family, revision, err := parseTaskDefinition(input)
    70  		isValid := expectedOutput["isValid"].(bool)
    71  		if !isValid && err == nil {
    72  			t.Fatalf("Task definition %s should fail", input)
    73  		}
    74  
    75  		expectedFamily := expectedOutput["family"].(string)
    76  		if family != expectedFamily {
    77  			t.Fatalf("Unexpected family (%#v) for task definition %s\n%#v", family, input, err)
    78  		}
    79  		expectedRevision := expectedOutput["revision"].(string)
    80  		if revision != expectedRevision {
    81  			t.Fatalf("Unexpected revision (%#v) for task definition %s\n%#v", revision, input, err)
    82  		}
    83  	}
    84  }
    85  
    86  func TestAccAWSEcsServiceWithARN(t *testing.T) {
    87  	resource.Test(t, resource.TestCase{
    88  		PreCheck:     func() { testAccPreCheck(t) },
    89  		Providers:    testAccProviders,
    90  		CheckDestroy: testAccCheckAWSEcsServiceDestroy,
    91  		Steps: []resource.TestStep{
    92  			resource.TestStep{
    93  				Config: testAccAWSEcsService,
    94  				Check: resource.ComposeTestCheckFunc(
    95  					testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"),
    96  				),
    97  			},
    98  
    99  			resource.TestStep{
   100  				Config: testAccAWSEcsServiceModified,
   101  				Check: resource.ComposeTestCheckFunc(
   102  					testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"),
   103  				),
   104  			},
   105  		},
   106  	})
   107  }
   108  
   109  func TestAccAWSEcsServiceWithFamilyAndRevision(t *testing.T) {
   110  	resource.Test(t, resource.TestCase{
   111  		PreCheck:     func() { testAccPreCheck(t) },
   112  		Providers:    testAccProviders,
   113  		CheckDestroy: testAccCheckAWSEcsServiceDestroy,
   114  		Steps: []resource.TestStep{
   115  			resource.TestStep{
   116  				Config: testAccAWSEcsServiceWithFamilyAndRevision,
   117  				Check: resource.ComposeTestCheckFunc(
   118  					testAccCheckAWSEcsServiceExists("aws_ecs_service.jenkins"),
   119  				),
   120  			},
   121  
   122  			resource.TestStep{
   123  				Config: testAccAWSEcsServiceWithFamilyAndRevisionModified,
   124  				Check: resource.ComposeTestCheckFunc(
   125  					testAccCheckAWSEcsServiceExists("aws_ecs_service.jenkins"),
   126  				),
   127  			},
   128  		},
   129  	})
   130  }
   131  
   132  // Regression for https://github.com/hashicorp/terraform/issues/2427
   133  func TestAccAWSEcsServiceWithRenamedCluster(t *testing.T) {
   134  	originalRegexp := regexp.MustCompile(
   135  		"^arn:aws:ecs:[^:]+:[0-9]+:cluster/terraformecstest3$")
   136  	modifiedRegexp := regexp.MustCompile(
   137  		"^arn:aws:ecs:[^:]+:[0-9]+:cluster/terraformecstest3modified$")
   138  
   139  	resource.Test(t, resource.TestCase{
   140  		PreCheck:     func() { testAccPreCheck(t) },
   141  		Providers:    testAccProviders,
   142  		CheckDestroy: testAccCheckAWSEcsServiceDestroy,
   143  		Steps: []resource.TestStep{
   144  			resource.TestStep{
   145  				Config: testAccAWSEcsServiceWithRenamedCluster,
   146  				Check: resource.ComposeTestCheckFunc(
   147  					testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost"),
   148  					resource.TestMatchResourceAttr(
   149  						"aws_ecs_service.ghost", "cluster", originalRegexp),
   150  				),
   151  			},
   152  
   153  			resource.TestStep{
   154  				Config: testAccAWSEcsServiceWithRenamedClusterModified,
   155  				Check: resource.ComposeTestCheckFunc(
   156  					testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost"),
   157  					resource.TestMatchResourceAttr(
   158  						"aws_ecs_service.ghost", "cluster", modifiedRegexp),
   159  				),
   160  			},
   161  		},
   162  	})
   163  }
   164  
   165  func TestAccAWSEcsService_withIamRole(t *testing.T) {
   166  	resource.Test(t, resource.TestCase{
   167  		PreCheck:     func() { testAccPreCheck(t) },
   168  		Providers:    testAccProviders,
   169  		CheckDestroy: testAccCheckAWSEcsServiceDestroy,
   170  		Steps: []resource.TestStep{
   171  			resource.TestStep{
   172  				Config: testAccAWSEcsService_withIamRole,
   173  				Check: resource.ComposeTestCheckFunc(
   174  					testAccCheckAWSEcsServiceExists("aws_ecs_service.ghost"),
   175  				),
   176  			},
   177  		},
   178  	})
   179  }
   180  
   181  func TestAccAWSEcsService_withDeploymentValues(t *testing.T) {
   182  	resource.Test(t, resource.TestCase{
   183  		PreCheck:     func() { testAccPreCheck(t) },
   184  		Providers:    testAccProviders,
   185  		CheckDestroy: testAccCheckAWSEcsServiceDestroy,
   186  		Steps: []resource.TestStep{
   187  			resource.TestStep{
   188  				Config: testAccAWSEcsServiceWithDeploymentValues,
   189  				Check: resource.ComposeTestCheckFunc(
   190  					testAccCheckAWSEcsServiceExists("aws_ecs_service.mongo"),
   191  					resource.TestCheckResourceAttr(
   192  						"aws_ecs_service.mongo", "deployment_maximum_percent", "200"),
   193  					resource.TestCheckResourceAttr(
   194  						"aws_ecs_service.mongo", "deployment_minimum_healthy_percent", "100"),
   195  				),
   196  			},
   197  		},
   198  	})
   199  }
   200  
   201  // Regression for https://github.com/hashicorp/terraform/issues/3444
   202  func TestAccAWSEcsService_withLbChanges(t *testing.T) {
   203  	resource.Test(t, resource.TestCase{
   204  		PreCheck:     func() { testAccPreCheck(t) },
   205  		Providers:    testAccProviders,
   206  		CheckDestroy: testAccCheckAWSEcsServiceDestroy,
   207  		Steps: []resource.TestStep{
   208  			resource.TestStep{
   209  				Config: testAccAWSEcsService_withLbChanges,
   210  				Check: resource.ComposeTestCheckFunc(
   211  					testAccCheckAWSEcsServiceExists("aws_ecs_service.with_lb_changes"),
   212  				),
   213  			},
   214  			resource.TestStep{
   215  				Config: testAccAWSEcsService_withLbChanges_modified,
   216  				Check: resource.ComposeTestCheckFunc(
   217  					testAccCheckAWSEcsServiceExists("aws_ecs_service.with_lb_changes"),
   218  				),
   219  			},
   220  		},
   221  	})
   222  }
   223  
   224  // Regression for https://github.com/hashicorp/terraform/issues/3361
   225  func TestAccAWSEcsService_withEcsClusterName(t *testing.T) {
   226  	clusterName := regexp.MustCompile("^terraformecstestcluster$")
   227  	resource.Test(t, resource.TestCase{
   228  		PreCheck:     func() { testAccPreCheck(t) },
   229  		Providers:    testAccProviders,
   230  		CheckDestroy: testAccCheckAWSEcsServiceDestroy,
   231  		Steps: []resource.TestStep{
   232  			resource.TestStep{
   233  				Config: testAccAWSEcsServiceWithEcsClusterName,
   234  				Check: resource.ComposeTestCheckFunc(
   235  					testAccCheckAWSEcsServiceExists("aws_ecs_service.jenkins"),
   236  					resource.TestMatchResourceAttr(
   237  						"aws_ecs_service.jenkins", "cluster", clusterName),
   238  				),
   239  			},
   240  		},
   241  	})
   242  }
   243  
   244  func testAccCheckAWSEcsServiceDestroy(s *terraform.State) error {
   245  	conn := testAccProvider.Meta().(*AWSClient).ecsconn
   246  
   247  	for _, rs := range s.RootModule().Resources {
   248  		if rs.Type != "aws_ecs_service" {
   249  			continue
   250  		}
   251  
   252  		out, err := conn.DescribeServices(&ecs.DescribeServicesInput{
   253  			Services: []*string{aws.String(rs.Primary.ID)},
   254  			Cluster:  aws.String(rs.Primary.Attributes["cluster"]),
   255  		})
   256  
   257  		if err == nil {
   258  			if len(out.Services) > 0 {
   259  				var activeServices []*ecs.Service
   260  				for _, svc := range out.Services {
   261  					if *svc.Status != "INACTIVE" {
   262  						activeServices = append(activeServices, svc)
   263  					}
   264  				}
   265  				if len(activeServices) == 0 {
   266  					return nil
   267  				}
   268  
   269  				return fmt.Errorf("ECS service still exists:\n%#v", activeServices)
   270  			}
   271  			return nil
   272  		}
   273  
   274  		return err
   275  	}
   276  
   277  	return nil
   278  }
   279  
   280  func testAccCheckAWSEcsServiceExists(name string) resource.TestCheckFunc {
   281  	return func(s *terraform.State) error {
   282  		_, ok := s.RootModule().Resources[name]
   283  		if !ok {
   284  			return fmt.Errorf("Not found: %s", name)
   285  		}
   286  
   287  		return nil
   288  	}
   289  }
   290  
   291  var testAccAWSEcsService = `
   292  resource "aws_ecs_cluster" "default" {
   293  	name = "terraformecstest1"
   294  }
   295  
   296  resource "aws_ecs_task_definition" "mongo" {
   297    family = "mongodb"
   298    container_definitions = <<DEFINITION
   299  [
   300    {
   301      "cpu": 128,
   302      "essential": true,
   303      "image": "mongo:latest",
   304      "memory": 128,
   305      "name": "mongodb"
   306    }
   307  ]
   308  DEFINITION
   309  }
   310  
   311  resource "aws_ecs_service" "mongo" {
   312    name = "mongodb"
   313    cluster = "${aws_ecs_cluster.default.id}"
   314    task_definition = "${aws_ecs_task_definition.mongo.arn}"
   315    desired_count = 1
   316  }
   317  `
   318  
   319  var testAccAWSEcsServiceModified = `
   320  resource "aws_ecs_cluster" "default" {
   321  	name = "terraformecstest1"
   322  }
   323  
   324  resource "aws_ecs_task_definition" "mongo" {
   325    family = "mongodb"
   326    container_definitions = <<DEFINITION
   327  [
   328    {
   329      "cpu": 128,
   330      "essential": true,
   331      "image": "mongo:latest",
   332      "memory": 128,
   333      "name": "mongodb"
   334    }
   335  ]
   336  DEFINITION
   337  }
   338  
   339  resource "aws_ecs_service" "mongo" {
   340    name = "mongodb"
   341    cluster = "${aws_ecs_cluster.default.id}"
   342    task_definition = "${aws_ecs_task_definition.mongo.arn}"
   343    desired_count = 2
   344  }
   345  `
   346  
   347  var testAccAWSEcsService_withIamRole = `
   348  resource "aws_ecs_cluster" "main" {
   349  	name = "terraformecstest11"
   350  }
   351  
   352  resource "aws_ecs_task_definition" "ghost" {
   353    family = "ghost_service"
   354    container_definitions = <<DEFINITION
   355  [
   356    {
   357      "cpu": 128,
   358      "essential": true,
   359      "image": "ghost:latest",
   360      "memory": 128,
   361      "name": "ghost",
   362      "portMappings": [
   363        {
   364          "containerPort": 2368,
   365          "hostPort": 8080
   366        }
   367      ]
   368    }
   369  ]
   370  DEFINITION
   371  }
   372  
   373  resource "aws_iam_role" "ecs_service" {
   374      name = "EcsService"
   375      assume_role_policy = <<EOF
   376  {
   377      "Version": "2012-10-17",
   378      "Statement": [
   379          {
   380              "Action": "sts:AssumeRole",
   381              "Principal": {"AWS": "*"},
   382              "Effect": "Allow",
   383              "Sid": ""
   384          }
   385      ]
   386  }
   387  EOF
   388  }
   389  
   390  resource "aws_iam_role_policy" "ecs_service" {
   391      name = "EcsService"
   392      role = "${aws_iam_role.ecs_service.name}"
   393      policy = <<EOF
   394  {
   395    "Version": "2012-10-17",
   396    "Statement": [
   397      {
   398        "Effect": "Allow",
   399        "Action": [
   400          "elasticloadbalancing:*",
   401          "ec2:*",
   402          "ecs:*"
   403        ],
   404        "Resource": [
   405          "*"
   406        ]
   407      }
   408    ]
   409  }
   410  EOF
   411  }
   412  
   413  resource "aws_elb" "main" {
   414    availability_zones = ["us-west-2a"]
   415  
   416    listener {
   417      instance_port = 8080
   418      instance_protocol = "http"
   419      lb_port = 80
   420      lb_protocol = "http"
   421    }
   422  }
   423  
   424  resource "aws_ecs_service" "ghost" {
   425    name = "ghost"
   426    cluster = "${aws_ecs_cluster.main.id}"
   427    task_definition = "${aws_ecs_task_definition.ghost.arn}"
   428    desired_count = 1
   429    iam_role = "${aws_iam_role.ecs_service.name}"
   430  
   431    load_balancer {
   432      elb_name = "${aws_elb.main.id}"
   433      container_name = "ghost"
   434      container_port = "2368"
   435    }
   436  
   437    depends_on = ["aws_iam_role_policy.ecs_service"]
   438  }
   439  `
   440  
   441  var testAccAWSEcsServiceWithDeploymentValues = `
   442  resource "aws_ecs_cluster" "default" {
   443  	name = "terraformecstest1"
   444  }
   445  
   446  resource "aws_ecs_task_definition" "mongo" {
   447    family = "mongodb"
   448    container_definitions = <<DEFINITION
   449  [
   450    {
   451      "cpu": 128,
   452      "essential": true,
   453      "image": "mongo:latest",
   454      "memory": 128,
   455      "name": "mongodb"
   456    }
   457  ]
   458  DEFINITION
   459  }
   460  
   461  resource "aws_ecs_service" "mongo" {
   462    name = "mongodb"
   463    cluster = "${aws_ecs_cluster.default.id}"
   464    task_definition = "${aws_ecs_task_definition.mongo.arn}"
   465    desired_count = 1
   466  }
   467  `
   468  
   469  var tpl_testAccAWSEcsService_withLbChanges = `
   470  resource "aws_ecs_cluster" "main" {
   471  	name = "terraformecstest12"
   472  }
   473  
   474  resource "aws_ecs_task_definition" "with_lb_changes" {
   475    family = "ghost_lbd"
   476    container_definitions = <<DEFINITION
   477  [
   478    {
   479      "cpu": 128,
   480      "essential": true,
   481      "image": "%s",
   482      "memory": 128,
   483      "name": "%s",
   484      "portMappings": [
   485        {
   486          "containerPort": %d,
   487          "hostPort": %d
   488        }
   489      ]
   490    }
   491  ]
   492  DEFINITION
   493  }
   494  
   495  resource "aws_iam_role" "ecs_service" {
   496      name = "EcsServiceLbd"
   497      assume_role_policy = <<EOF
   498  {
   499      "Version": "2012-10-17",
   500      "Statement": [
   501          {
   502              "Action": "sts:AssumeRole",
   503              "Principal": {"AWS": "*"},
   504              "Effect": "Allow",
   505              "Sid": ""
   506          }
   507      ]
   508  }
   509  EOF
   510  }
   511  
   512  resource "aws_iam_role_policy" "ecs_service" {
   513      name = "EcsServiceLbd"
   514      role = "${aws_iam_role.ecs_service.name}"
   515      policy = <<EOF
   516  {
   517    "Version": "2012-10-17",
   518    "Statement": [
   519      {
   520        "Effect": "Allow",
   521        "Action": [
   522          "elasticloadbalancing:*",
   523          "ec2:*",
   524          "ecs:*"
   525        ],
   526        "Resource": [
   527          "*"
   528        ]
   529      }
   530    ]
   531  }
   532  EOF
   533  }
   534  
   535  resource "aws_elb" "main" {
   536    availability_zones = ["us-west-2a"]
   537  
   538    listener {
   539      instance_port = %d
   540      instance_protocol = "http"
   541      lb_port = 80
   542      lb_protocol = "http"
   543    }
   544  }
   545  
   546  resource "aws_ecs_service" "with_lb_changes" {
   547    name = "ghost"
   548    cluster = "${aws_ecs_cluster.main.id}"
   549    task_definition = "${aws_ecs_task_definition.with_lb_changes.arn}"
   550    desired_count = 1
   551    iam_role = "${aws_iam_role.ecs_service.name}"
   552  
   553    load_balancer {
   554      elb_name = "${aws_elb.main.id}"
   555      container_name = "%s"
   556      container_port = "%d"
   557    }
   558  
   559    depends_on = ["aws_iam_role_policy.ecs_service"]
   560  }
   561  `
   562  
   563  var testAccAWSEcsService_withLbChanges = fmt.Sprintf(
   564  	tpl_testAccAWSEcsService_withLbChanges,
   565  	"ghost:latest", "ghost", 2368, 8080, 8080, "ghost", 2368)
   566  var testAccAWSEcsService_withLbChanges_modified = fmt.Sprintf(
   567  	tpl_testAccAWSEcsService_withLbChanges,
   568  	"nginx:latest", "nginx", 80, 8080, 8080, "nginx", 80)
   569  
   570  var testAccAWSEcsServiceWithFamilyAndRevision = `
   571  resource "aws_ecs_cluster" "default" {
   572  	name = "terraformecstest2"
   573  }
   574  
   575  resource "aws_ecs_task_definition" "jenkins" {
   576    family = "jenkins"
   577    container_definitions = <<DEFINITION
   578  [
   579    {
   580      "cpu": 128,
   581      "essential": true,
   582      "image": "jenkins:latest",
   583      "memory": 128,
   584      "name": "jenkins"
   585    }
   586  ]
   587  DEFINITION
   588  }
   589  
   590  resource "aws_ecs_service" "jenkins" {
   591    name = "jenkins"
   592    cluster = "${aws_ecs_cluster.default.id}"
   593    task_definition = "${aws_ecs_task_definition.jenkins.family}:${aws_ecs_task_definition.jenkins.revision}"
   594    desired_count = 1
   595  }
   596  `
   597  
   598  var testAccAWSEcsServiceWithFamilyAndRevisionModified = `
   599  resource "aws_ecs_cluster" "default" {
   600  	name = "terraformecstest2"
   601  }
   602  
   603  resource "aws_ecs_task_definition" "jenkins" {
   604    family = "jenkins"
   605    container_definitions = <<DEFINITION
   606  [
   607    {
   608      "cpu": 128,
   609      "essential": true,
   610      "image": "jenkins:latest",
   611      "memory": 128,
   612      "name": "jenkins"
   613    }
   614  ]
   615  DEFINITION
   616  }
   617  
   618  resource "aws_ecs_service" "jenkins" {
   619    name = "jenkins"
   620    cluster = "${aws_ecs_cluster.default.id}"
   621    task_definition = "${aws_ecs_task_definition.jenkins.family}:${aws_ecs_task_definition.jenkins.revision}"
   622    desired_count = 1
   623  }
   624  `
   625  
   626  var testAccAWSEcsServiceWithRenamedCluster = `
   627  resource "aws_ecs_cluster" "default" {
   628  	name = "terraformecstest3"
   629  }
   630  resource "aws_ecs_task_definition" "ghost" {
   631    family = "ghost"
   632    container_definitions = <<DEFINITION
   633  [
   634    {
   635      "cpu": 128,
   636      "essential": true,
   637      "image": "ghost:latest",
   638      "memory": 128,
   639      "name": "ghost"
   640    }
   641  ]
   642  DEFINITION
   643  }
   644  resource "aws_ecs_service" "ghost" {
   645    name = "ghost"
   646    cluster = "${aws_ecs_cluster.default.id}"
   647    task_definition = "${aws_ecs_task_definition.ghost.family}:${aws_ecs_task_definition.ghost.revision}"
   648    desired_count = 1
   649  }
   650  `
   651  
   652  var testAccAWSEcsServiceWithRenamedClusterModified = `
   653  resource "aws_ecs_cluster" "default" {
   654  	name = "terraformecstest3modified"
   655  }
   656  resource "aws_ecs_task_definition" "ghost" {
   657    family = "ghost"
   658    container_definitions = <<DEFINITION
   659  [
   660    {
   661      "cpu": 128,
   662      "essential": true,
   663      "image": "ghost:latest",
   664      "memory": 128,
   665      "name": "ghost"
   666    }
   667  ]
   668  DEFINITION
   669  }
   670  resource "aws_ecs_service" "ghost" {
   671    name = "ghost"
   672    cluster = "${aws_ecs_cluster.default.id}"
   673    task_definition = "${aws_ecs_task_definition.ghost.family}:${aws_ecs_task_definition.ghost.revision}"
   674    desired_count = 1
   675  }
   676  `
   677  
   678  var testAccAWSEcsServiceWithEcsClusterName = `
   679  resource "aws_ecs_cluster" "default" {
   680  	name = "terraformecstestcluster"
   681  }
   682  
   683  resource "aws_ecs_task_definition" "jenkins" {
   684    family = "jenkins"
   685    container_definitions = <<DEFINITION
   686  [
   687    {
   688      "cpu": 128,
   689      "essential": true,
   690      "image": "jenkins:latest",
   691      "memory": 128,
   692      "name": "jenkins"
   693    }
   694  ]
   695  DEFINITION
   696  }
   697  
   698  resource "aws_ecs_service" "jenkins" {
   699    name = "jenkins"
   700    cluster = "${aws_ecs_cluster.default.name}"
   701    task_definition = "${aws_ecs_task_definition.jenkins.arn}"
   702    desired_count = 1
   703  }
   704  `