github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/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 // Regression for https://github.com/hashicorp/terraform/issues/3444 182 func TestAccAWSEcsService_withLbChanges(t *testing.T) { 183 resource.Test(t, resource.TestCase{ 184 PreCheck: func() { testAccPreCheck(t) }, 185 Providers: testAccProviders, 186 CheckDestroy: testAccCheckAWSEcsServiceDestroy, 187 Steps: []resource.TestStep{ 188 resource.TestStep{ 189 Config: testAccAWSEcsService_withLbChanges, 190 Check: resource.ComposeTestCheckFunc( 191 testAccCheckAWSEcsServiceExists("aws_ecs_service.with_lb_changes"), 192 ), 193 }, 194 resource.TestStep{ 195 Config: testAccAWSEcsService_withLbChanges_modified, 196 Check: resource.ComposeTestCheckFunc( 197 testAccCheckAWSEcsServiceExists("aws_ecs_service.with_lb_changes"), 198 ), 199 }, 200 }, 201 }) 202 } 203 204 // Regression for https://github.com/hashicorp/terraform/issues/3361 205 func TestAccAWSEcsService_withEcsClusterName(t *testing.T) { 206 clusterName := regexp.MustCompile("^terraformecstestcluster$") 207 resource.Test(t, resource.TestCase{ 208 PreCheck: func() { testAccPreCheck(t) }, 209 Providers: testAccProviders, 210 CheckDestroy: testAccCheckAWSEcsServiceDestroy, 211 Steps: []resource.TestStep{ 212 resource.TestStep{ 213 Config: testAccAWSEcsServiceWithEcsClusterName, 214 Check: resource.ComposeTestCheckFunc( 215 testAccCheckAWSEcsServiceExists("aws_ecs_service.jenkins"), 216 resource.TestMatchResourceAttr( 217 "aws_ecs_service.jenkins", "cluster", clusterName), 218 ), 219 }, 220 }, 221 }) 222 } 223 224 func testAccCheckAWSEcsServiceDestroy(s *terraform.State) error { 225 conn := testAccProvider.Meta().(*AWSClient).ecsconn 226 227 for _, rs := range s.RootModule().Resources { 228 if rs.Type != "aws_ecs_service" { 229 continue 230 } 231 232 out, err := conn.DescribeServices(&ecs.DescribeServicesInput{ 233 Services: []*string{aws.String(rs.Primary.ID)}, 234 Cluster: aws.String(rs.Primary.Attributes["cluster"]), 235 }) 236 237 if err == nil { 238 if len(out.Services) > 0 { 239 var activeServices []*ecs.Service 240 for _, svc := range out.Services { 241 if *svc.Status != "INACTIVE" { 242 activeServices = append(activeServices, svc) 243 } 244 } 245 if len(activeServices) == 0 { 246 return nil 247 } 248 249 return fmt.Errorf("ECS service still exists:\n%#v", activeServices) 250 } 251 return nil 252 } 253 254 return err 255 } 256 257 return nil 258 } 259 260 func testAccCheckAWSEcsServiceExists(name string) resource.TestCheckFunc { 261 return func(s *terraform.State) error { 262 _, ok := s.RootModule().Resources[name] 263 if !ok { 264 return fmt.Errorf("Not found: %s", name) 265 } 266 267 return nil 268 } 269 } 270 271 var testAccAWSEcsService = ` 272 resource "aws_ecs_cluster" "default" { 273 name = "terraformecstest1" 274 } 275 276 resource "aws_ecs_task_definition" "mongo" { 277 family = "mongodb" 278 container_definitions = <<DEFINITION 279 [ 280 { 281 "cpu": 128, 282 "essential": true, 283 "image": "mongo:latest", 284 "memory": 128, 285 "name": "mongodb" 286 } 287 ] 288 DEFINITION 289 } 290 291 resource "aws_ecs_service" "mongo" { 292 name = "mongodb" 293 cluster = "${aws_ecs_cluster.default.id}" 294 task_definition = "${aws_ecs_task_definition.mongo.arn}" 295 desired_count = 1 296 } 297 ` 298 299 var testAccAWSEcsServiceModified = ` 300 resource "aws_ecs_cluster" "default" { 301 name = "terraformecstest1" 302 } 303 304 resource "aws_ecs_task_definition" "mongo" { 305 family = "mongodb" 306 container_definitions = <<DEFINITION 307 [ 308 { 309 "cpu": 128, 310 "essential": true, 311 "image": "mongo:latest", 312 "memory": 128, 313 "name": "mongodb" 314 } 315 ] 316 DEFINITION 317 } 318 319 resource "aws_ecs_service" "mongo" { 320 name = "mongodb" 321 cluster = "${aws_ecs_cluster.default.id}" 322 task_definition = "${aws_ecs_task_definition.mongo.arn}" 323 desired_count = 2 324 } 325 ` 326 327 var testAccAWSEcsService_withIamRole = ` 328 resource "aws_ecs_cluster" "main" { 329 name = "terraformecstest11" 330 } 331 332 resource "aws_ecs_task_definition" "ghost" { 333 family = "ghost_service" 334 container_definitions = <<DEFINITION 335 [ 336 { 337 "cpu": 128, 338 "essential": true, 339 "image": "ghost:latest", 340 "memory": 128, 341 "name": "ghost", 342 "portMappings": [ 343 { 344 "containerPort": 2368, 345 "hostPort": 8080 346 } 347 ] 348 } 349 ] 350 DEFINITION 351 } 352 353 resource "aws_iam_role" "ecs_service" { 354 name = "EcsService" 355 assume_role_policy = <<EOF 356 { 357 "Version": "2012-10-17", 358 "Statement": [ 359 { 360 "Action": "sts:AssumeRole", 361 "Principal": {"AWS": "*"}, 362 "Effect": "Allow", 363 "Sid": "" 364 } 365 ] 366 } 367 EOF 368 } 369 370 resource "aws_iam_role_policy" "ecs_service" { 371 name = "EcsService" 372 role = "${aws_iam_role.ecs_service.name}" 373 policy = <<EOF 374 { 375 "Version": "2012-10-17", 376 "Statement": [ 377 { 378 "Effect": "Allow", 379 "Action": [ 380 "elasticloadbalancing:*", 381 "ec2:*", 382 "ecs:*" 383 ], 384 "Resource": [ 385 "*" 386 ] 387 } 388 ] 389 } 390 EOF 391 } 392 393 resource "aws_elb" "main" { 394 availability_zones = ["us-west-2a"] 395 396 listener { 397 instance_port = 8080 398 instance_protocol = "http" 399 lb_port = 80 400 lb_protocol = "http" 401 } 402 } 403 404 resource "aws_ecs_service" "ghost" { 405 name = "ghost" 406 cluster = "${aws_ecs_cluster.main.id}" 407 task_definition = "${aws_ecs_task_definition.ghost.arn}" 408 desired_count = 1 409 iam_role = "${aws_iam_role.ecs_service.name}" 410 411 load_balancer { 412 elb_name = "${aws_elb.main.id}" 413 container_name = "ghost" 414 container_port = "2368" 415 } 416 417 depends_on = ["aws_iam_role_policy.ecs_service"] 418 } 419 ` 420 421 var tpl_testAccAWSEcsService_withLbChanges = ` 422 resource "aws_ecs_cluster" "main" { 423 name = "terraformecstest12" 424 } 425 426 resource "aws_ecs_task_definition" "with_lb_changes" { 427 family = "ghost_lbd" 428 container_definitions = <<DEFINITION 429 [ 430 { 431 "cpu": 128, 432 "essential": true, 433 "image": "%s", 434 "memory": 128, 435 "name": "%s", 436 "portMappings": [ 437 { 438 "containerPort": %d, 439 "hostPort": %d 440 } 441 ] 442 } 443 ] 444 DEFINITION 445 } 446 447 resource "aws_iam_role" "ecs_service" { 448 name = "EcsServiceLbd" 449 assume_role_policy = <<EOF 450 { 451 "Version": "2012-10-17", 452 "Statement": [ 453 { 454 "Action": "sts:AssumeRole", 455 "Principal": {"AWS": "*"}, 456 "Effect": "Allow", 457 "Sid": "" 458 } 459 ] 460 } 461 EOF 462 } 463 464 resource "aws_iam_role_policy" "ecs_service" { 465 name = "EcsServiceLbd" 466 role = "${aws_iam_role.ecs_service.name}" 467 policy = <<EOF 468 { 469 "Version": "2012-10-17", 470 "Statement": [ 471 { 472 "Effect": "Allow", 473 "Action": [ 474 "elasticloadbalancing:*", 475 "ec2:*", 476 "ecs:*" 477 ], 478 "Resource": [ 479 "*" 480 ] 481 } 482 ] 483 } 484 EOF 485 } 486 487 resource "aws_elb" "main" { 488 availability_zones = ["us-west-2a"] 489 490 listener { 491 instance_port = %d 492 instance_protocol = "http" 493 lb_port = 80 494 lb_protocol = "http" 495 } 496 } 497 498 resource "aws_ecs_service" "with_lb_changes" { 499 name = "ghost" 500 cluster = "${aws_ecs_cluster.main.id}" 501 task_definition = "${aws_ecs_task_definition.with_lb_changes.arn}" 502 desired_count = 1 503 iam_role = "${aws_iam_role.ecs_service.name}" 504 505 load_balancer { 506 elb_name = "${aws_elb.main.id}" 507 container_name = "%s" 508 container_port = "%d" 509 } 510 511 depends_on = ["aws_iam_role_policy.ecs_service"] 512 } 513 ` 514 515 var testAccAWSEcsService_withLbChanges = fmt.Sprintf( 516 tpl_testAccAWSEcsService_withLbChanges, 517 "ghost:latest", "ghost", 2368, 8080, 8080, "ghost", 2368) 518 var testAccAWSEcsService_withLbChanges_modified = fmt.Sprintf( 519 tpl_testAccAWSEcsService_withLbChanges, 520 "nginx:latest", "nginx", 80, 8080, 8080, "nginx", 80) 521 522 var testAccAWSEcsServiceWithFamilyAndRevision = ` 523 resource "aws_ecs_cluster" "default" { 524 name = "terraformecstest2" 525 } 526 527 resource "aws_ecs_task_definition" "jenkins" { 528 family = "jenkins" 529 container_definitions = <<DEFINITION 530 [ 531 { 532 "cpu": 128, 533 "essential": true, 534 "image": "jenkins:latest", 535 "memory": 128, 536 "name": "jenkins" 537 } 538 ] 539 DEFINITION 540 } 541 542 resource "aws_ecs_service" "jenkins" { 543 name = "jenkins" 544 cluster = "${aws_ecs_cluster.default.id}" 545 task_definition = "${aws_ecs_task_definition.jenkins.family}:${aws_ecs_task_definition.jenkins.revision}" 546 desired_count = 1 547 } 548 ` 549 550 var testAccAWSEcsServiceWithFamilyAndRevisionModified = ` 551 resource "aws_ecs_cluster" "default" { 552 name = "terraformecstest2" 553 } 554 555 resource "aws_ecs_task_definition" "jenkins" { 556 family = "jenkins" 557 container_definitions = <<DEFINITION 558 [ 559 { 560 "cpu": 128, 561 "essential": true, 562 "image": "jenkins:latest", 563 "memory": 128, 564 "name": "jenkins" 565 } 566 ] 567 DEFINITION 568 } 569 570 resource "aws_ecs_service" "jenkins" { 571 name = "jenkins" 572 cluster = "${aws_ecs_cluster.default.id}" 573 task_definition = "${aws_ecs_task_definition.jenkins.family}:${aws_ecs_task_definition.jenkins.revision}" 574 desired_count = 1 575 } 576 ` 577 578 var testAccAWSEcsServiceWithRenamedCluster = ` 579 resource "aws_ecs_cluster" "default" { 580 name = "terraformecstest3" 581 } 582 resource "aws_ecs_task_definition" "ghost" { 583 family = "ghost" 584 container_definitions = <<DEFINITION 585 [ 586 { 587 "cpu": 128, 588 "essential": true, 589 "image": "ghost:latest", 590 "memory": 128, 591 "name": "ghost" 592 } 593 ] 594 DEFINITION 595 } 596 resource "aws_ecs_service" "ghost" { 597 name = "ghost" 598 cluster = "${aws_ecs_cluster.default.id}" 599 task_definition = "${aws_ecs_task_definition.ghost.family}:${aws_ecs_task_definition.ghost.revision}" 600 desired_count = 1 601 } 602 ` 603 604 var testAccAWSEcsServiceWithRenamedClusterModified = ` 605 resource "aws_ecs_cluster" "default" { 606 name = "terraformecstest3modified" 607 } 608 resource "aws_ecs_task_definition" "ghost" { 609 family = "ghost" 610 container_definitions = <<DEFINITION 611 [ 612 { 613 "cpu": 128, 614 "essential": true, 615 "image": "ghost:latest", 616 "memory": 128, 617 "name": "ghost" 618 } 619 ] 620 DEFINITION 621 } 622 resource "aws_ecs_service" "ghost" { 623 name = "ghost" 624 cluster = "${aws_ecs_cluster.default.id}" 625 task_definition = "${aws_ecs_task_definition.ghost.family}:${aws_ecs_task_definition.ghost.revision}" 626 desired_count = 1 627 } 628 ` 629 630 var testAccAWSEcsServiceWithEcsClusterName = ` 631 resource "aws_ecs_cluster" "default" { 632 name = "terraformecstestcluster" 633 } 634 635 resource "aws_ecs_task_definition" "jenkins" { 636 family = "jenkins" 637 container_definitions = <<DEFINITION 638 [ 639 { 640 "cpu": 128, 641 "essential": true, 642 "image": "jenkins:latest", 643 "memory": 128, 644 "name": "jenkins" 645 } 646 ] 647 DEFINITION 648 } 649 650 resource "aws_ecs_service" "jenkins" { 651 name = "jenkins" 652 cluster = "${aws_ecs_cluster.default.name}" 653 task_definition = "${aws_ecs_task_definition.jenkins.arn}" 654 desired_count = 1 655 } 656 `