github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_ecs_task_definition_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/service/ecs" 9 "github.com/hashicorp/terraform/helper/acctest" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/terraform" 12 ) 13 14 func TestAccAWSEcsTaskDefinition_basic(t *testing.T) { 15 var def ecs.TaskDefinition 16 resource.Test(t, resource.TestCase{ 17 PreCheck: func() { testAccPreCheck(t) }, 18 Providers: testAccProviders, 19 CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy, 20 Steps: []resource.TestStep{ 21 { 22 Config: testAccAWSEcsTaskDefinition, 23 Check: resource.ComposeTestCheckFunc( 24 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.jenkins", &def), 25 ), 26 }, 27 { 28 Config: testAccAWSEcsTaskDefinitionModified, 29 Check: resource.ComposeTestCheckFunc( 30 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.jenkins", &def), 31 ), 32 }, 33 }, 34 }) 35 } 36 37 // Regression for https://github.com/hashicorp/terraform/issues/2370 38 func TestAccAWSEcsTaskDefinition_withScratchVolume(t *testing.T) { 39 var def ecs.TaskDefinition 40 resource.Test(t, resource.TestCase{ 41 PreCheck: func() { testAccPreCheck(t) }, 42 Providers: testAccProviders, 43 CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy, 44 Steps: []resource.TestStep{ 45 { 46 Config: testAccAWSEcsTaskDefinitionWithScratchVolume, 47 Check: resource.ComposeTestCheckFunc( 48 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.sleep", &def), 49 ), 50 }, 51 }, 52 }) 53 } 54 55 // Regression for https://github.com/hashicorp/terraform/issues/2694 56 func TestAccAWSEcsTaskDefinition_withEcsService(t *testing.T) { 57 var def ecs.TaskDefinition 58 resource.Test(t, resource.TestCase{ 59 PreCheck: func() { testAccPreCheck(t) }, 60 Providers: testAccProviders, 61 CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy, 62 Steps: []resource.TestStep{ 63 { 64 Config: testAccAWSEcsTaskDefinitionWithEcsService, 65 Check: resource.ComposeTestCheckFunc( 66 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.sleep", &def), 67 testAccCheckAWSEcsServiceExists("aws_ecs_service.sleep-svc"), 68 ), 69 }, 70 { 71 Config: testAccAWSEcsTaskDefinitionWithEcsServiceModified, 72 Check: resource.ComposeTestCheckFunc( 73 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.sleep", &def), 74 testAccCheckAWSEcsServiceExists("aws_ecs_service.sleep-svc"), 75 ), 76 }, 77 }, 78 }) 79 } 80 81 func TestAccAWSEcsTaskDefinition_withTaskRoleArn(t *testing.T) { 82 var def ecs.TaskDefinition 83 rInt := acctest.RandInt() 84 resource.Test(t, resource.TestCase{ 85 PreCheck: func() { testAccPreCheck(t) }, 86 Providers: testAccProviders, 87 CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy, 88 Steps: []resource.TestStep{ 89 { 90 Config: testAccAWSEcsTaskDefinitionWithTaskRoleArn(rInt), 91 Check: resource.ComposeTestCheckFunc( 92 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.sleep", &def), 93 ), 94 }, 95 }, 96 }) 97 } 98 99 func TestAccAWSEcsTaskDefinition_withNetworkMode(t *testing.T) { 100 var def ecs.TaskDefinition 101 rInt := acctest.RandInt() 102 resource.Test(t, resource.TestCase{ 103 PreCheck: func() { testAccPreCheck(t) }, 104 Providers: testAccProviders, 105 CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy, 106 Steps: []resource.TestStep{ 107 { 108 Config: testAccAWSEcsTaskDefinitionWithNetworkMode(rInt), 109 Check: resource.ComposeTestCheckFunc( 110 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.sleep", &def), 111 resource.TestCheckResourceAttr( 112 "aws_ecs_task_definition.sleep", "network_mode", "bridge"), 113 ), 114 }, 115 }, 116 }) 117 } 118 119 func TestAccAWSEcsTaskDefinition_constraint(t *testing.T) { 120 var def ecs.TaskDefinition 121 resource.Test(t, resource.TestCase{ 122 PreCheck: func() { testAccPreCheck(t) }, 123 Providers: testAccProviders, 124 CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy, 125 Steps: []resource.TestStep{ 126 { 127 Config: testAccAWSEcsTaskDefinition_constraint, 128 Check: resource.ComposeTestCheckFunc( 129 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.jenkins", &def), 130 resource.TestCheckResourceAttr("aws_ecs_task_definition.jenkins", "placement_constraints.#", "1"), 131 testAccCheckAWSTaskDefinitionConstraintsAttrs(&def), 132 ), 133 }, 134 }, 135 }) 136 } 137 138 func TestAccAWSEcsTaskDefinition_changeVolumesForcesNewResource(t *testing.T) { 139 var before ecs.TaskDefinition 140 var after ecs.TaskDefinition 141 resource.Test(t, resource.TestCase{ 142 PreCheck: func() { testAccPreCheck(t) }, 143 Providers: testAccProviders, 144 CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy, 145 Steps: []resource.TestStep{ 146 { 147 Config: testAccAWSEcsTaskDefinition, 148 Check: resource.ComposeTestCheckFunc( 149 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.jenkins", &before), 150 ), 151 }, 152 { 153 Config: testAccAWSEcsTaskDefinitionUpdatedVolume, 154 Check: resource.ComposeTestCheckFunc( 155 testAccCheckAWSEcsTaskDefinitionExists("aws_ecs_task_definition.jenkins", &after), 156 testAccCheckEcsTaskDefinitionRecreated(t, &before, &after), 157 ), 158 }, 159 }, 160 }) 161 } 162 163 func testAccCheckEcsTaskDefinitionRecreated(t *testing.T, 164 before, after *ecs.TaskDefinition) resource.TestCheckFunc { 165 return func(s *terraform.State) error { 166 if *before.Revision == *after.Revision { 167 t.Fatalf("Expected change of TaskDefinition Revisions, but both were %v", before.Revision) 168 } 169 return nil 170 } 171 } 172 173 func testAccCheckAWSTaskDefinitionConstraintsAttrs(def *ecs.TaskDefinition) resource.TestCheckFunc { 174 return func(s *terraform.State) error { 175 if len(def.PlacementConstraints) != 1 { 176 return fmt.Errorf("Expected (1) placement_constraints, got (%d)", len(def.PlacementConstraints)) 177 } 178 return nil 179 } 180 } 181 func TestValidateAwsEcsTaskDefinitionNetworkMode(t *testing.T) { 182 validNames := []string{ 183 "bridge", 184 "host", 185 "none", 186 } 187 for _, v := range validNames { 188 _, errors := validateAwsEcsTaskDefinitionNetworkMode(v, "network_mode") 189 if len(errors) != 0 { 190 t.Fatalf("%q should be a valid AWS ECS Task Definition Network Mode: %q", v, errors) 191 } 192 } 193 194 invalidNames := []string{ 195 "bridged", 196 "-docker", 197 } 198 for _, v := range invalidNames { 199 _, errors := validateAwsEcsTaskDefinitionNetworkMode(v, "network_mode") 200 if len(errors) == 0 { 201 t.Fatalf("%q should be an invalid AWS ECS Task Definition Network Mode", v) 202 } 203 } 204 } 205 206 func TestValidateAwsEcsTaskDefinitionContainerDefinitions(t *testing.T) { 207 validDefinitions := []string{ 208 testValidateAwsEcsTaskDefinitionValidContainerDefinitions, 209 } 210 for _, v := range validDefinitions { 211 _, errors := validateAwsEcsTaskDefinitionContainerDefinitions(v, "container_definitions") 212 if len(errors) != 0 { 213 t.Fatalf("%q should be a valid AWS ECS Task Definition Container Definitions: %q", v, errors) 214 } 215 } 216 217 invalidDefinitions := []string{ 218 testValidateAwsEcsTaskDefinitionInvalidCommandContainerDefinitions, 219 } 220 for _, v := range invalidDefinitions { 221 _, errors := validateAwsEcsTaskDefinitionContainerDefinitions(v, "container_definitions") 222 if len(errors) == 0 { 223 t.Fatalf("%q should be an invalid AWS ECS Task Definition Container Definitions", v) 224 } 225 } 226 } 227 228 func testAccCheckAWSEcsTaskDefinitionDestroy(s *terraform.State) error { 229 conn := testAccProvider.Meta().(*AWSClient).ecsconn 230 231 for _, rs := range s.RootModule().Resources { 232 if rs.Type != "aws_ecs_task_definition" { 233 continue 234 } 235 236 input := ecs.DescribeTaskDefinitionInput{ 237 TaskDefinition: aws.String(rs.Primary.Attributes["arn"]), 238 } 239 240 out, err := conn.DescribeTaskDefinition(&input) 241 242 if err != nil { 243 return err 244 } 245 246 if out.TaskDefinition != nil && *out.TaskDefinition.Status != "INACTIVE" { 247 return fmt.Errorf("ECS task definition still exists:\n%#v", *out.TaskDefinition) 248 } 249 } 250 251 return nil 252 } 253 254 func testAccCheckAWSEcsTaskDefinitionExists(name string, def *ecs.TaskDefinition) resource.TestCheckFunc { 255 return func(s *terraform.State) error { 256 rs, ok := s.RootModule().Resources[name] 257 if !ok { 258 return fmt.Errorf("Not found: %s", name) 259 } 260 261 conn := testAccProvider.Meta().(*AWSClient).ecsconn 262 263 out, err := conn.DescribeTaskDefinition(&ecs.DescribeTaskDefinitionInput{ 264 TaskDefinition: aws.String(rs.Primary.Attributes["arn"]), 265 }) 266 if err != nil { 267 return err 268 } 269 270 *def = *out.TaskDefinition 271 272 return nil 273 } 274 } 275 276 var testAccAWSEcsTaskDefinition_constraint = ` 277 resource "aws_ecs_task_definition" "jenkins" { 278 family = "terraform-acc-test" 279 container_definitions = <<TASK_DEFINITION 280 [ 281 { 282 "cpu": 10, 283 "command": ["sleep", "10"], 284 "entryPoint": ["/"], 285 "environment": [ 286 {"name": "VARNAME", "value": "VARVAL"} 287 ], 288 "essential": true, 289 "image": "jenkins", 290 "links": ["mongodb"], 291 "memory": 128, 292 "name": "jenkins", 293 "portMappings": [ 294 { 295 "containerPort": 80, 296 "hostPort": 8080 297 } 298 ] 299 }, 300 { 301 "cpu": 10, 302 "command": ["sleep", "10"], 303 "entryPoint": ["/"], 304 "essential": true, 305 "image": "mongodb", 306 "memory": 128, 307 "name": "mongodb", 308 "portMappings": [ 309 { 310 "containerPort": 28017, 311 "hostPort": 28017 312 } 313 ] 314 } 315 ] 316 TASK_DEFINITION 317 318 volume { 319 name = "jenkins-home" 320 host_path = "/ecs/jenkins-home" 321 } 322 323 placement_constraints { 324 type = "memberOf" 325 expression = "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]" 326 } 327 } 328 ` 329 330 var testAccAWSEcsTaskDefinition = ` 331 resource "aws_ecs_task_definition" "jenkins" { 332 family = "terraform-acc-test" 333 container_definitions = <<TASK_DEFINITION 334 [ 335 { 336 "cpu": 10, 337 "command": ["sleep", "10"], 338 "entryPoint": ["/"], 339 "environment": [ 340 {"name": "VARNAME", "value": "VARVAL"} 341 ], 342 "essential": true, 343 "image": "jenkins", 344 "links": ["mongodb"], 345 "memory": 128, 346 "name": "jenkins", 347 "portMappings": [ 348 { 349 "containerPort": 80, 350 "hostPort": 8080 351 } 352 ] 353 }, 354 { 355 "cpu": 10, 356 "command": ["sleep", "10"], 357 "entryPoint": ["/"], 358 "essential": true, 359 "image": "mongodb", 360 "memory": 128, 361 "name": "mongodb", 362 "portMappings": [ 363 { 364 "containerPort": 28017, 365 "hostPort": 28017 366 } 367 ] 368 } 369 ] 370 TASK_DEFINITION 371 372 volume { 373 name = "jenkins-home" 374 host_path = "/ecs/jenkins-home" 375 } 376 } 377 ` 378 379 var testAccAWSEcsTaskDefinitionUpdatedVolume = ` 380 resource "aws_ecs_task_definition" "jenkins" { 381 family = "terraform-acc-test" 382 container_definitions = <<TASK_DEFINITION 383 [ 384 { 385 "cpu": 10, 386 "command": ["sleep", "10"], 387 "entryPoint": ["/"], 388 "environment": [ 389 {"name": "VARNAME", "value": "VARVAL"} 390 ], 391 "essential": true, 392 "image": "jenkins", 393 "links": ["mongodb"], 394 "memory": 128, 395 "name": "jenkins", 396 "portMappings": [ 397 { 398 "containerPort": 80, 399 "hostPort": 8080 400 } 401 ] 402 }, 403 { 404 "cpu": 10, 405 "command": ["sleep", "10"], 406 "entryPoint": ["/"], 407 "essential": true, 408 "image": "mongodb", 409 "memory": 128, 410 "name": "mongodb", 411 "portMappings": [ 412 { 413 "containerPort": 28017, 414 "hostPort": 28017 415 } 416 ] 417 } 418 ] 419 TASK_DEFINITION 420 421 volume { 422 name = "jenkins-home" 423 host_path = "/ecs/jenkins" 424 } 425 } 426 ` 427 428 var testAccAWSEcsTaskDefinitionWithScratchVolume = ` 429 resource "aws_ecs_task_definition" "sleep" { 430 family = "terraform-acc-sc-volume-test" 431 container_definitions = <<TASK_DEFINITION 432 [ 433 { 434 "name": "sleep", 435 "image": "busybox", 436 "cpu": 10, 437 "command": ["sleep","360"], 438 "memory": 10, 439 "essential": true 440 } 441 ] 442 TASK_DEFINITION 443 444 volume { 445 name = "database_scratch" 446 } 447 } 448 ` 449 450 func testAccAWSEcsTaskDefinitionWithTaskRoleArn(rInt int) string { 451 return fmt.Sprintf(` 452 resource "aws_iam_role" "role_test" { 453 name = "tf_old_name-%d" 454 path = "/test/" 455 assume_role_policy = <<EOF 456 { 457 "Version": "2012-10-17", 458 "Statement": [ 459 { 460 "Action": "sts:AssumeRole", 461 "Principal": { 462 "Service": "ec2.amazonaws.com" 463 }, 464 "Effect": "Allow", 465 "Sid": "" 466 } 467 ] 468 } 469 EOF 470 } 471 472 resource "aws_iam_role_policy" "role_test" { 473 name = "role_update_test-%d" 474 role = "${aws_iam_role.role_test.id}" 475 policy = <<EOF 476 { 477 "Version": "2012-10-17", 478 "Statement": [ 479 { 480 "Effect": "Allow", 481 "Action": [ 482 "s3:GetBucketLocation", 483 "s3:ListAllMyBuckets" 484 ], 485 "Resource": "arn:aws:s3:::*" 486 } 487 ] 488 } 489 EOF 490 } 491 492 resource "aws_ecs_task_definition" "sleep" { 493 family = "terraform-acc-sc-volume-test" 494 task_role_arn = "${aws_iam_role.role_test.arn}" 495 container_definitions = <<TASK_DEFINITION 496 [ 497 { 498 "name": "sleep", 499 "image": "busybox", 500 "cpu": 10, 501 "command": ["sleep","360"], 502 "memory": 10, 503 "essential": true 504 } 505 ] 506 TASK_DEFINITION 507 volume { 508 name = "database_scratch" 509 } 510 }`, rInt, rInt) 511 } 512 513 func testAccAWSEcsTaskDefinitionWithNetworkMode(rInt int) string { 514 return fmt.Sprintf(` 515 resource "aws_iam_role" "role_test" { 516 name = "tf_old_name-%d" 517 path = "/test/" 518 assume_role_policy = <<EOF 519 { 520 "Version": "2012-10-17", 521 "Statement": [ 522 { 523 "Action": "sts:AssumeRole", 524 "Principal": { 525 "Service": "ec2.amazonaws.com" 526 }, 527 "Effect": "Allow", 528 "Sid": "" 529 } 530 ] 531 } 532 EOF 533 } 534 535 resource "aws_iam_role_policy" "role_test" { 536 name = "role_update_test-%d" 537 role = "${aws_iam_role.role_test.id}" 538 policy = <<EOF 539 { 540 "Version": "2012-10-17", 541 "Statement": [ 542 { 543 "Effect": "Allow", 544 "Action": [ 545 "s3:GetBucketLocation", 546 "s3:ListAllMyBuckets" 547 ], 548 "Resource": "arn:aws:s3:::*" 549 } 550 ] 551 } 552 EOF 553 } 554 555 resource "aws_ecs_task_definition" "sleep" { 556 family = "terraform-acc-sc-volume-test-network-mode" 557 task_role_arn = "${aws_iam_role.role_test.arn}" 558 network_mode = "bridge" 559 container_definitions = <<TASK_DEFINITION 560 [ 561 { 562 "name": "sleep", 563 "image": "busybox", 564 "cpu": 10, 565 "command": ["sleep","360"], 566 "memory": 10, 567 "essential": true 568 } 569 ] 570 TASK_DEFINITION 571 572 volume { 573 name = "database_scratch" 574 } 575 }`, rInt, rInt) 576 } 577 578 var testAccAWSEcsTaskDefinitionWithEcsService = ` 579 resource "aws_ecs_cluster" "default" { 580 name = "terraform-acc-test" 581 } 582 583 resource "aws_ecs_service" "sleep-svc" { 584 name = "tf-acc-ecs-svc" 585 cluster = "${aws_ecs_cluster.default.id}" 586 task_definition = "${aws_ecs_task_definition.sleep.arn}" 587 desired_count = 1 588 } 589 590 resource "aws_ecs_task_definition" "sleep" { 591 family = "terraform-acc-sc-volume-test" 592 container_definitions = <<TASK_DEFINITION 593 [ 594 { 595 "name": "sleep", 596 "image": "busybox", 597 "cpu": 10, 598 "command": ["sleep","360"], 599 "memory": 10, 600 "essential": true 601 } 602 ] 603 TASK_DEFINITION 604 605 volume { 606 name = "database_scratch" 607 } 608 } 609 ` 610 var testAccAWSEcsTaskDefinitionWithEcsServiceModified = ` 611 resource "aws_ecs_cluster" "default" { 612 name = "terraform-acc-test" 613 } 614 615 resource "aws_ecs_service" "sleep-svc" { 616 name = "tf-acc-ecs-svc" 617 cluster = "${aws_ecs_cluster.default.id}" 618 task_definition = "${aws_ecs_task_definition.sleep.arn}" 619 desired_count = 1 620 } 621 622 resource "aws_ecs_task_definition" "sleep" { 623 family = "terraform-acc-sc-volume-test" 624 container_definitions = <<TASK_DEFINITION 625 [ 626 { 627 "name": "sleep", 628 "image": "busybox", 629 "cpu": 20, 630 "command": ["sleep","360"], 631 "memory": 50, 632 "essential": true 633 } 634 ] 635 TASK_DEFINITION 636 637 volume { 638 name = "database_scratch" 639 } 640 } 641 ` 642 643 var testAccAWSEcsTaskDefinitionModified = ` 644 resource "aws_ecs_task_definition" "jenkins" { 645 family = "terraform-acc-test" 646 container_definitions = <<TASK_DEFINITION 647 [ 648 { 649 "cpu": 10, 650 "command": ["sleep", "10"], 651 "entryPoint": ["/"], 652 "environment": [ 653 {"name": "VARNAME", "value": "VARVAL"} 654 ], 655 "essential": true, 656 "image": "jenkins", 657 "links": ["mongodb"], 658 "memory": 128, 659 "name": "jenkins", 660 "portMappings": [ 661 { 662 "containerPort": 80, 663 "hostPort": 8080 664 } 665 ] 666 }, 667 { 668 "cpu": 20, 669 "command": ["sleep", "10"], 670 "entryPoint": ["/"], 671 "essential": true, 672 "image": "mongodb", 673 "memory": 128, 674 "name": "mongodb", 675 "portMappings": [ 676 { 677 "containerPort": 28017, 678 "hostPort": 28017 679 } 680 ] 681 } 682 ] 683 TASK_DEFINITION 684 685 volume { 686 name = "jenkins-home" 687 host_path = "/ecs/jenkins-home" 688 } 689 } 690 ` 691 692 var testValidateAwsEcsTaskDefinitionValidContainerDefinitions = ` 693 [ 694 { 695 "name": "sleep", 696 "image": "busybox", 697 "cpu": 10, 698 "command": ["sleep","360"], 699 "memory": 10, 700 "essential": true 701 } 702 ] 703 ` 704 705 var testValidateAwsEcsTaskDefinitionInvalidCommandContainerDefinitions = ` 706 [ 707 { 708 "name": "sleep", 709 "image": "busybox", 710 "cpu": 10, 711 "command": "sleep 360", 712 "memory": 10, 713 "essential": true 714 } 715 ] 716 `