github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/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 `