github.com/memsql/terraform@v0.7.0-rc2.0.20160706152241-21e2173e0a32/builtin/providers/aws/resource_aws_elb_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "math/rand" 6 "reflect" 7 "regexp" 8 "sort" 9 "testing" 10 "time" 11 12 "github.com/aws/aws-sdk-go/aws" 13 "github.com/aws/aws-sdk-go/aws/awserr" 14 "github.com/aws/aws-sdk-go/service/elb" 15 "github.com/hashicorp/terraform/helper/acctest" 16 "github.com/hashicorp/terraform/helper/resource" 17 "github.com/hashicorp/terraform/terraform" 18 ) 19 20 func TestAccAWSELB_basic(t *testing.T) { 21 var conf elb.LoadBalancerDescription 22 23 resource.Test(t, resource.TestCase{ 24 PreCheck: func() { testAccPreCheck(t) }, 25 IDRefreshName: "aws_elb.bar", 26 Providers: testAccProviders, 27 CheckDestroy: testAccCheckAWSELBDestroy, 28 Steps: []resource.TestStep{ 29 resource.TestStep{ 30 Config: testAccAWSELBConfig, 31 Check: resource.ComposeTestCheckFunc( 32 testAccCheckAWSELBExists("aws_elb.bar", &conf), 33 testAccCheckAWSELBAttributes(&conf), 34 resource.TestCheckResourceAttr( 35 "aws_elb.bar", "availability_zones.#", "3"), 36 resource.TestCheckResourceAttr( 37 "aws_elb.bar", "availability_zones.2487133097", "us-west-2a"), 38 resource.TestCheckResourceAttr( 39 "aws_elb.bar", "availability_zones.221770259", "us-west-2b"), 40 resource.TestCheckResourceAttr( 41 "aws_elb.bar", "availability_zones.2050015877", "us-west-2c"), 42 resource.TestCheckResourceAttr( 43 "aws_elb.bar", "subnets.#", "3"), 44 // NOTE: Subnet IDs are different across AWS accounts and cannot be checked. 45 resource.TestCheckResourceAttr( 46 "aws_elb.bar", "listener.206423021.instance_port", "8000"), 47 resource.TestCheckResourceAttr( 48 "aws_elb.bar", "listener.206423021.instance_protocol", "http"), 49 resource.TestCheckResourceAttr( 50 "aws_elb.bar", "listener.206423021.lb_port", "80"), 51 resource.TestCheckResourceAttr( 52 "aws_elb.bar", "listener.206423021.lb_protocol", "http"), 53 resource.TestCheckResourceAttr( 54 "aws_elb.bar", "cross_zone_load_balancing", "true"), 55 ), 56 }, 57 }, 58 }) 59 } 60 61 func TestAccAWSELB_fullCharacterRange(t *testing.T) { 62 var conf elb.LoadBalancerDescription 63 64 lbName := fmt.Sprintf("Tf-%d", 65 rand.New(rand.NewSource(time.Now().UnixNano())).Int()) 66 67 resource.Test(t, resource.TestCase{ 68 PreCheck: func() { testAccPreCheck(t) }, 69 IDRefreshName: "aws_elb.foo", 70 Providers: testAccProviders, 71 CheckDestroy: testAccCheckAWSELBDestroy, 72 Steps: []resource.TestStep{ 73 resource.TestStep{ 74 Config: fmt.Sprintf(testAccAWSELBFullRangeOfCharacters, lbName), 75 Check: resource.ComposeTestCheckFunc( 76 testAccCheckAWSELBExists("aws_elb.foo", &conf), 77 resource.TestCheckResourceAttr( 78 "aws_elb.foo", "name", lbName), 79 ), 80 }, 81 }, 82 }) 83 } 84 85 func TestAccAWSELB_AccessLogs(t *testing.T) { 86 var conf elb.LoadBalancerDescription 87 88 resource.Test(t, resource.TestCase{ 89 PreCheck: func() { testAccPreCheck(t) }, 90 IDRefreshName: "aws_elb.foo", 91 Providers: testAccProviders, 92 CheckDestroy: testAccCheckAWSELBDestroy, 93 Steps: []resource.TestStep{ 94 resource.TestStep{ 95 Config: testAccAWSELBAccessLogs, 96 Check: resource.ComposeTestCheckFunc( 97 testAccCheckAWSELBExists("aws_elb.foo", &conf), 98 ), 99 }, 100 101 resource.TestStep{ 102 Config: testAccAWSELBAccessLogsOn, 103 Check: resource.ComposeTestCheckFunc( 104 testAccCheckAWSELBExists("aws_elb.foo", &conf), 105 resource.TestCheckResourceAttr( 106 "aws_elb.foo", "access_logs.#", "1"), 107 resource.TestCheckResourceAttr( 108 "aws_elb.foo", "access_logs.0.bucket", "terraform-access-logs-bucket"), 109 resource.TestCheckResourceAttr( 110 "aws_elb.foo", "access_logs.0.interval", "5"), 111 ), 112 }, 113 114 resource.TestStep{ 115 Config: testAccAWSELBAccessLogs, 116 Check: resource.ComposeTestCheckFunc( 117 testAccCheckAWSELBExists("aws_elb.foo", &conf), 118 resource.TestCheckResourceAttr( 119 "aws_elb.foo", "access_logs.#", "0"), 120 ), 121 }, 122 }, 123 }) 124 } 125 126 func TestAccAWSELB_generatedName(t *testing.T) { 127 var conf elb.LoadBalancerDescription 128 generatedNameRegexp := regexp.MustCompile("^tf-lb-") 129 130 resource.Test(t, resource.TestCase{ 131 PreCheck: func() { testAccPreCheck(t) }, 132 IDRefreshName: "aws_elb.foo", 133 Providers: testAccProviders, 134 CheckDestroy: testAccCheckAWSELBDestroy, 135 Steps: []resource.TestStep{ 136 resource.TestStep{ 137 Config: testAccAWSELBGeneratedName, 138 Check: resource.ComposeTestCheckFunc( 139 testAccCheckAWSELBExists("aws_elb.foo", &conf), 140 resource.TestMatchResourceAttr( 141 "aws_elb.foo", "name", generatedNameRegexp), 142 ), 143 }, 144 }, 145 }) 146 } 147 148 func TestAccAWSELB_availabilityZones(t *testing.T) { 149 var conf elb.LoadBalancerDescription 150 151 resource.Test(t, resource.TestCase{ 152 PreCheck: func() { testAccPreCheck(t) }, 153 IDRefreshName: "aws_elb.bar", 154 Providers: testAccProviders, 155 CheckDestroy: testAccCheckAWSELBDestroy, 156 Steps: []resource.TestStep{ 157 resource.TestStep{ 158 Config: testAccAWSELBConfig, 159 Check: resource.ComposeTestCheckFunc( 160 testAccCheckAWSELBExists("aws_elb.bar", &conf), 161 resource.TestCheckResourceAttr( 162 "aws_elb.bar", "availability_zones.#", "3"), 163 resource.TestCheckResourceAttr( 164 "aws_elb.bar", "availability_zones.2487133097", "us-west-2a"), 165 resource.TestCheckResourceAttr( 166 "aws_elb.bar", "availability_zones.221770259", "us-west-2b"), 167 resource.TestCheckResourceAttr( 168 "aws_elb.bar", "availability_zones.2050015877", "us-west-2c"), 169 ), 170 }, 171 172 resource.TestStep{ 173 Config: testAccAWSELBConfig_AvailabilityZonesUpdate, 174 Check: resource.ComposeTestCheckFunc( 175 testAccCheckAWSELBExists("aws_elb.bar", &conf), 176 resource.TestCheckResourceAttr( 177 "aws_elb.bar", "availability_zones.#", "2"), 178 resource.TestCheckResourceAttr( 179 "aws_elb.bar", "availability_zones.2487133097", "us-west-2a"), 180 resource.TestCheckResourceAttr( 181 "aws_elb.bar", "availability_zones.221770259", "us-west-2b"), 182 ), 183 }, 184 }, 185 }) 186 } 187 188 func TestAccAWSELB_tags(t *testing.T) { 189 var conf elb.LoadBalancerDescription 190 var td elb.TagDescription 191 192 resource.Test(t, resource.TestCase{ 193 PreCheck: func() { testAccPreCheck(t) }, 194 IDRefreshName: "aws_elb.bar", 195 Providers: testAccProviders, 196 CheckDestroy: testAccCheckAWSELBDestroy, 197 Steps: []resource.TestStep{ 198 resource.TestStep{ 199 Config: testAccAWSELBConfig, 200 Check: resource.ComposeTestCheckFunc( 201 testAccCheckAWSELBExists("aws_elb.bar", &conf), 202 testAccCheckAWSELBAttributes(&conf), 203 testAccLoadTags(&conf, &td), 204 testAccCheckELBTags(&td.Tags, "bar", "baz"), 205 ), 206 }, 207 208 resource.TestStep{ 209 Config: testAccAWSELBConfig_TagUpdate, 210 Check: resource.ComposeTestCheckFunc( 211 testAccCheckAWSELBExists("aws_elb.bar", &conf), 212 testAccCheckAWSELBAttributes(&conf), 213 testAccLoadTags(&conf, &td), 214 testAccCheckELBTags(&td.Tags, "foo", "bar"), 215 testAccCheckELBTags(&td.Tags, "new", "type"), 216 ), 217 }, 218 }, 219 }) 220 } 221 222 func TestAccAWSELB_iam_server_cert(t *testing.T) { 223 var conf elb.LoadBalancerDescription 224 // var td elb.TagDescription 225 testCheck := func(*terraform.State) error { 226 if len(conf.ListenerDescriptions) != 1 { 227 return fmt.Errorf( 228 "TestAccAWSELB_iam_server_cert expected 1 listener, got %d", 229 len(conf.ListenerDescriptions)) 230 } 231 return nil 232 } 233 resource.Test(t, resource.TestCase{ 234 PreCheck: func() { testAccPreCheck(t) }, 235 IDRefreshName: "aws_elb.bar", 236 Providers: testAccProviders, 237 CheckDestroy: testAccCheckAWSELBDestroy, 238 Steps: []resource.TestStep{ 239 resource.TestStep{ 240 Config: testAccELBIAMServerCertConfig( 241 fmt.Sprintf("tf-acctest-%s", acctest.RandString(10))), 242 Check: resource.ComposeTestCheckFunc( 243 testAccCheckAWSELBExists("aws_elb.bar", &conf), 244 testCheck, 245 ), 246 }, 247 }, 248 }) 249 } 250 251 func testAccLoadTags(conf *elb.LoadBalancerDescription, td *elb.TagDescription) resource.TestCheckFunc { 252 return func(s *terraform.State) error { 253 conn := testAccProvider.Meta().(*AWSClient).elbconn 254 255 describe, err := conn.DescribeTags(&elb.DescribeTagsInput{ 256 LoadBalancerNames: []*string{conf.LoadBalancerName}, 257 }) 258 259 if err != nil { 260 return err 261 } 262 if len(describe.TagDescriptions) > 0 { 263 *td = *describe.TagDescriptions[0] 264 } 265 return nil 266 } 267 } 268 269 func TestAccAWSELB_InstanceAttaching(t *testing.T) { 270 var conf elb.LoadBalancerDescription 271 272 testCheckInstanceAttached := func(count int) resource.TestCheckFunc { 273 return func(*terraform.State) error { 274 if len(conf.Instances) != count { 275 return fmt.Errorf("instance count does not match") 276 } 277 return nil 278 } 279 } 280 281 resource.Test(t, resource.TestCase{ 282 PreCheck: func() { testAccPreCheck(t) }, 283 IDRefreshName: "aws_elb.bar", 284 Providers: testAccProviders, 285 CheckDestroy: testAccCheckAWSELBDestroy, 286 Steps: []resource.TestStep{ 287 resource.TestStep{ 288 Config: testAccAWSELBConfig, 289 Check: resource.ComposeTestCheckFunc( 290 testAccCheckAWSELBExists("aws_elb.bar", &conf), 291 testAccCheckAWSELBAttributes(&conf), 292 ), 293 }, 294 295 resource.TestStep{ 296 Config: testAccAWSELBConfigNewInstance, 297 Check: resource.ComposeTestCheckFunc( 298 testAccCheckAWSELBExists("aws_elb.bar", &conf), 299 testCheckInstanceAttached(1), 300 ), 301 }, 302 }, 303 }) 304 } 305 306 func TestAccAWSELBUpdate_Listener(t *testing.T) { 307 var conf elb.LoadBalancerDescription 308 309 resource.Test(t, resource.TestCase{ 310 PreCheck: func() { testAccPreCheck(t) }, 311 IDRefreshName: "aws_elb.bar", 312 Providers: testAccProviders, 313 CheckDestroy: testAccCheckAWSELBDestroy, 314 Steps: []resource.TestStep{ 315 resource.TestStep{ 316 Config: testAccAWSELBConfig, 317 Check: resource.ComposeTestCheckFunc( 318 testAccCheckAWSELBExists("aws_elb.bar", &conf), 319 testAccCheckAWSELBAttributes(&conf), 320 resource.TestCheckResourceAttr( 321 "aws_elb.bar", "listener.206423021.instance_port", "8000"), 322 ), 323 }, 324 325 resource.TestStep{ 326 Config: testAccAWSELBConfigListener_update, 327 Check: resource.ComposeTestCheckFunc( 328 testAccCheckAWSELBExists("aws_elb.bar", &conf), 329 resource.TestCheckResourceAttr( 330 "aws_elb.bar", "listener.3931999347.instance_port", "8080"), 331 ), 332 }, 333 }, 334 }) 335 } 336 337 func TestAccAWSELB_HealthCheck(t *testing.T) { 338 var conf elb.LoadBalancerDescription 339 340 resource.Test(t, resource.TestCase{ 341 PreCheck: func() { testAccPreCheck(t) }, 342 IDRefreshName: "aws_elb.bar", 343 Providers: testAccProviders, 344 CheckDestroy: testAccCheckAWSELBDestroy, 345 Steps: []resource.TestStep{ 346 resource.TestStep{ 347 Config: testAccAWSELBConfigHealthCheck, 348 Check: resource.ComposeTestCheckFunc( 349 testAccCheckAWSELBExists("aws_elb.bar", &conf), 350 testAccCheckAWSELBAttributesHealthCheck(&conf), 351 resource.TestCheckResourceAttr( 352 "aws_elb.bar", "health_check.0.healthy_threshold", "5"), 353 resource.TestCheckResourceAttr( 354 "aws_elb.bar", "health_check.0.unhealthy_threshold", "5"), 355 resource.TestCheckResourceAttr( 356 "aws_elb.bar", "health_check.0.target", "HTTP:8000/"), 357 resource.TestCheckResourceAttr( 358 "aws_elb.bar", "health_check.0.timeout", "30"), 359 resource.TestCheckResourceAttr( 360 "aws_elb.bar", "health_check.0.interval", "60"), 361 ), 362 }, 363 }, 364 }) 365 } 366 367 func TestAccAWSELBUpdate_HealthCheck(t *testing.T) { 368 resource.Test(t, resource.TestCase{ 369 PreCheck: func() { testAccPreCheck(t) }, 370 IDRefreshName: "aws_elb.bar", 371 Providers: testAccProviders, 372 CheckDestroy: testAccCheckAWSELBDestroy, 373 Steps: []resource.TestStep{ 374 resource.TestStep{ 375 Config: testAccAWSELBConfigHealthCheck, 376 Check: resource.ComposeTestCheckFunc( 377 resource.TestCheckResourceAttr( 378 "aws_elb.bar", "health_check.0.healthy_threshold", "5"), 379 ), 380 }, 381 resource.TestStep{ 382 Config: testAccAWSELBConfigHealthCheck_update, 383 Check: resource.ComposeTestCheckFunc( 384 resource.TestCheckResourceAttr( 385 "aws_elb.bar", "health_check.0.healthy_threshold", "10"), 386 ), 387 }, 388 }, 389 }) 390 } 391 392 func TestAccAWSELB_Timeout(t *testing.T) { 393 var conf elb.LoadBalancerDescription 394 395 resource.Test(t, resource.TestCase{ 396 PreCheck: func() { testAccPreCheck(t) }, 397 IDRefreshName: "aws_elb.bar", 398 Providers: testAccProviders, 399 CheckDestroy: testAccCheckAWSELBDestroy, 400 Steps: []resource.TestStep{ 401 resource.TestStep{ 402 Config: testAccAWSELBConfigIdleTimeout, 403 Check: resource.ComposeTestCheckFunc( 404 testAccCheckAWSELBExists("aws_elb.bar", &conf), 405 resource.TestCheckResourceAttr( 406 "aws_elb.bar", "idle_timeout", "200", 407 ), 408 ), 409 }, 410 }, 411 }) 412 } 413 414 func TestAccAWSELBUpdate_Timeout(t *testing.T) { 415 resource.Test(t, resource.TestCase{ 416 PreCheck: func() { testAccPreCheck(t) }, 417 IDRefreshName: "aws_elb.bar", 418 Providers: testAccProviders, 419 CheckDestroy: testAccCheckAWSELBDestroy, 420 Steps: []resource.TestStep{ 421 resource.TestStep{ 422 Config: testAccAWSELBConfigIdleTimeout, 423 Check: resource.ComposeTestCheckFunc( 424 resource.TestCheckResourceAttr( 425 "aws_elb.bar", "idle_timeout", "200", 426 ), 427 ), 428 }, 429 resource.TestStep{ 430 Config: testAccAWSELBConfigIdleTimeout_update, 431 Check: resource.ComposeTestCheckFunc( 432 resource.TestCheckResourceAttr( 433 "aws_elb.bar", "idle_timeout", "400", 434 ), 435 ), 436 }, 437 }, 438 }) 439 } 440 441 func TestAccAWSELB_ConnectionDraining(t *testing.T) { 442 resource.Test(t, resource.TestCase{ 443 PreCheck: func() { testAccPreCheck(t) }, 444 IDRefreshName: "aws_elb.bar", 445 Providers: testAccProviders, 446 CheckDestroy: testAccCheckAWSELBDestroy, 447 Steps: []resource.TestStep{ 448 resource.TestStep{ 449 Config: testAccAWSELBConfigConnectionDraining, 450 Check: resource.ComposeTestCheckFunc( 451 resource.TestCheckResourceAttr( 452 "aws_elb.bar", "connection_draining", "true", 453 ), 454 resource.TestCheckResourceAttr( 455 "aws_elb.bar", "connection_draining_timeout", "400", 456 ), 457 ), 458 }, 459 }, 460 }) 461 } 462 463 func TestAccAWSELBUpdate_ConnectionDraining(t *testing.T) { 464 resource.Test(t, resource.TestCase{ 465 PreCheck: func() { testAccPreCheck(t) }, 466 IDRefreshName: "aws_elb.bar", 467 Providers: testAccProviders, 468 CheckDestroy: testAccCheckAWSELBDestroy, 469 Steps: []resource.TestStep{ 470 resource.TestStep{ 471 Config: testAccAWSELBConfigConnectionDraining, 472 Check: resource.ComposeTestCheckFunc( 473 resource.TestCheckResourceAttr( 474 "aws_elb.bar", "connection_draining", "true", 475 ), 476 resource.TestCheckResourceAttr( 477 "aws_elb.bar", "connection_draining_timeout", "400", 478 ), 479 ), 480 }, 481 resource.TestStep{ 482 Config: testAccAWSELBConfigConnectionDraining_update_timeout, 483 Check: resource.ComposeTestCheckFunc( 484 resource.TestCheckResourceAttr( 485 "aws_elb.bar", "connection_draining", "true", 486 ), 487 resource.TestCheckResourceAttr( 488 "aws_elb.bar", "connection_draining_timeout", "600", 489 ), 490 ), 491 }, 492 resource.TestStep{ 493 Config: testAccAWSELBConfigConnectionDraining_update_disable, 494 Check: resource.ComposeTestCheckFunc( 495 resource.TestCheckResourceAttr( 496 "aws_elb.bar", "connection_draining", "false", 497 ), 498 ), 499 }, 500 }, 501 }) 502 } 503 504 func TestAccAWSELB_SecurityGroups(t *testing.T) { 505 resource.Test(t, resource.TestCase{ 506 PreCheck: func() { testAccPreCheck(t) }, 507 IDRefreshName: "aws_elb.bar", 508 Providers: testAccProviders, 509 CheckDestroy: testAccCheckAWSELBDestroy, 510 Steps: []resource.TestStep{ 511 resource.TestStep{ 512 Config: testAccAWSELBConfig, 513 Check: resource.ComposeTestCheckFunc( 514 // ELBs get a default security group 515 resource.TestCheckResourceAttr( 516 "aws_elb.bar", "security_groups.#", "1", 517 ), 518 ), 519 }, 520 resource.TestStep{ 521 Config: testAccAWSELBConfigSecurityGroups, 522 Check: resource.ComposeTestCheckFunc( 523 // Count should still be one as we swap in a custom security group 524 resource.TestCheckResourceAttr( 525 "aws_elb.bar", "security_groups.#", "1", 526 ), 527 ), 528 }, 529 }, 530 }) 531 } 532 533 // Unit test for listeners hash 534 func TestResourceAwsElbListenerHash(t *testing.T) { 535 cases := map[string]struct { 536 Left map[string]interface{} 537 Right map[string]interface{} 538 Match bool 539 }{ 540 "protocols are case insensitive": { 541 map[string]interface{}{ 542 "instance_port": 80, 543 "instance_protocol": "TCP", 544 "lb_port": 80, 545 "lb_protocol": "TCP", 546 }, 547 map[string]interface{}{ 548 "instance_port": 80, 549 "instance_protocol": "Tcp", 550 "lb_port": 80, 551 "lb_protocol": "tcP", 552 }, 553 true, 554 }, 555 } 556 557 for tn, tc := range cases { 558 leftHash := resourceAwsElbListenerHash(tc.Left) 559 rightHash := resourceAwsElbListenerHash(tc.Right) 560 if leftHash == rightHash != tc.Match { 561 t.Fatalf("%s: expected match: %t, but did not get it", tn, tc.Match) 562 } 563 } 564 } 565 566 func TestResourceAWSELB_validateElbNameCannotBeginWithHyphen(t *testing.T) { 567 var elbName = "-Testing123" 568 _, errors := validateElbName(elbName, "SampleKey") 569 570 if len(errors) != 1 { 571 t.Fatalf("Expected the ELB Name to trigger a validation error") 572 } 573 } 574 575 func TestResourceAWSELB_validateElbNameCannotBeLongerThen32Characters(t *testing.T) { 576 var elbName = "Testing123dddddddddddddddddddvvvv" 577 _, errors := validateElbName(elbName, "SampleKey") 578 579 if len(errors) != 1 { 580 t.Fatalf("Expected the ELB Name to trigger a validation error") 581 } 582 } 583 584 func TestResourceAWSELB_validateElbNameCannotHaveSpecialCharacters(t *testing.T) { 585 var elbName = "Testing123%%" 586 _, errors := validateElbName(elbName, "SampleKey") 587 588 if len(errors) != 1 { 589 t.Fatalf("Expected the ELB Name to trigger a validation error") 590 } 591 } 592 593 func TestResourceAWSELB_validateElbNameCannotEndWithHyphen(t *testing.T) { 594 var elbName = "Testing123-" 595 _, errors := validateElbName(elbName, "SampleKey") 596 597 if len(errors) != 1 { 598 t.Fatalf("Expected the ELB Name to trigger a validation error") 599 } 600 } 601 602 func testAccCheckAWSELBDestroy(s *terraform.State) error { 603 conn := testAccProvider.Meta().(*AWSClient).elbconn 604 605 for _, rs := range s.RootModule().Resources { 606 if rs.Type != "aws_elb" { 607 continue 608 } 609 610 describe, err := conn.DescribeLoadBalancers(&elb.DescribeLoadBalancersInput{ 611 LoadBalancerNames: []*string{aws.String(rs.Primary.ID)}, 612 }) 613 614 if err == nil { 615 if len(describe.LoadBalancerDescriptions) != 0 && 616 *describe.LoadBalancerDescriptions[0].LoadBalancerName == rs.Primary.ID { 617 return fmt.Errorf("ELB still exists") 618 } 619 } 620 621 // Verify the error 622 providerErr, ok := err.(awserr.Error) 623 if !ok { 624 return err 625 } 626 627 if providerErr.Code() != "LoadBalancerNotFound" { 628 return fmt.Errorf("Unexpected error: %s", err) 629 } 630 } 631 632 return nil 633 } 634 635 func testAccCheckAWSELBAttributes(conf *elb.LoadBalancerDescription) resource.TestCheckFunc { 636 return func(s *terraform.State) error { 637 zones := []string{"us-west-2a", "us-west-2b", "us-west-2c"} 638 azs := make([]string, 0, len(conf.AvailabilityZones)) 639 for _, x := range conf.AvailabilityZones { 640 azs = append(azs, *x) 641 } 642 sort.StringSlice(azs).Sort() 643 if !reflect.DeepEqual(azs, zones) { 644 return fmt.Errorf("bad availability_zones") 645 } 646 647 l := elb.Listener{ 648 InstancePort: aws.Int64(int64(8000)), 649 InstanceProtocol: aws.String("HTTP"), 650 LoadBalancerPort: aws.Int64(int64(80)), 651 Protocol: aws.String("HTTP"), 652 } 653 654 if !reflect.DeepEqual(conf.ListenerDescriptions[0].Listener, &l) { 655 return fmt.Errorf( 656 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 657 conf.ListenerDescriptions[0].Listener, 658 l) 659 } 660 661 if *conf.DNSName == "" { 662 return fmt.Errorf("empty dns_name") 663 } 664 665 return nil 666 } 667 } 668 669 func testAccCheckAWSELBAttributesHealthCheck(conf *elb.LoadBalancerDescription) resource.TestCheckFunc { 670 return func(s *terraform.State) error { 671 zones := []string{"us-west-2a", "us-west-2b", "us-west-2c"} 672 azs := make([]string, 0, len(conf.AvailabilityZones)) 673 for _, x := range conf.AvailabilityZones { 674 azs = append(azs, *x) 675 } 676 sort.StringSlice(azs).Sort() 677 if !reflect.DeepEqual(azs, zones) { 678 return fmt.Errorf("bad availability_zones") 679 } 680 681 check := &elb.HealthCheck{ 682 Timeout: aws.Int64(int64(30)), 683 UnhealthyThreshold: aws.Int64(int64(5)), 684 HealthyThreshold: aws.Int64(int64(5)), 685 Interval: aws.Int64(int64(60)), 686 Target: aws.String("HTTP:8000/"), 687 } 688 689 if !reflect.DeepEqual(conf.HealthCheck, check) { 690 return fmt.Errorf( 691 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 692 conf.HealthCheck, 693 check) 694 } 695 696 if *conf.DNSName == "" { 697 return fmt.Errorf("empty dns_name") 698 } 699 700 return nil 701 } 702 } 703 704 func testAccCheckAWSELBExists(n string, res *elb.LoadBalancerDescription) resource.TestCheckFunc { 705 return func(s *terraform.State) error { 706 rs, ok := s.RootModule().Resources[n] 707 if !ok { 708 return fmt.Errorf("Not found: %s", n) 709 } 710 711 if rs.Primary.ID == "" { 712 return fmt.Errorf("No ELB ID is set") 713 } 714 715 conn := testAccProvider.Meta().(*AWSClient).elbconn 716 717 describe, err := conn.DescribeLoadBalancers(&elb.DescribeLoadBalancersInput{ 718 LoadBalancerNames: []*string{aws.String(rs.Primary.ID)}, 719 }) 720 721 if err != nil { 722 return err 723 } 724 725 if len(describe.LoadBalancerDescriptions) != 1 || 726 *describe.LoadBalancerDescriptions[0].LoadBalancerName != rs.Primary.ID { 727 return fmt.Errorf("ELB not found") 728 } 729 730 *res = *describe.LoadBalancerDescriptions[0] 731 732 // Confirm source_security_group_id for ELBs in a VPC 733 // See https://github.com/hashicorp/terraform/pull/3780 734 if res.VPCId != nil { 735 sgid := rs.Primary.Attributes["source_security_group_id"] 736 if sgid == "" { 737 return fmt.Errorf("Expected to find source_security_group_id for ELB, but was empty") 738 } 739 } 740 741 return nil 742 } 743 } 744 745 const testAccAWSELBConfig = ` 746 resource "aws_elb" "bar" { 747 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 748 749 listener { 750 instance_port = 8000 751 instance_protocol = "http" 752 lb_port = 80 753 // Protocol should be case insensitive 754 lb_protocol = "HttP" 755 } 756 757 tags { 758 bar = "baz" 759 } 760 761 cross_zone_load_balancing = true 762 } 763 ` 764 765 const testAccAWSELBFullRangeOfCharacters = ` 766 resource "aws_elb" "foo" { 767 name = "%s" 768 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 769 770 listener { 771 instance_port = 8000 772 instance_protocol = "http" 773 lb_port = 80 774 lb_protocol = "http" 775 } 776 } 777 ` 778 779 const testAccAWSELBAccessLogs = ` 780 resource "aws_elb" "foo" { 781 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 782 783 listener { 784 instance_port = 8000 785 instance_protocol = "http" 786 lb_port = 80 787 lb_protocol = "http" 788 } 789 } 790 ` 791 const testAccAWSELBAccessLogsOn = ` 792 # an S3 bucket configured for Access logs 793 # The 797873946194 is the AWS ID for us-west-2, so this test 794 # must be ran in us-west-2 795 resource "aws_s3_bucket" "acceslogs_bucket" { 796 bucket = "terraform-access-logs-bucket" 797 acl = "private" 798 force_destroy = true 799 policy = <<EOF 800 { 801 "Id": "Policy1446577137248", 802 "Statement": [ 803 { 804 "Action": "s3:PutObject", 805 "Effect": "Allow", 806 "Principal": { 807 "AWS": "arn:aws:iam::797873946194:root" 808 }, 809 "Resource": "arn:aws:s3:::terraform-access-logs-bucket/*", 810 "Sid": "Stmt1446575236270" 811 } 812 ], 813 "Version": "2012-10-17" 814 } 815 EOF 816 } 817 818 resource "aws_elb" "foo" { 819 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 820 821 listener { 822 instance_port = 8000 823 instance_protocol = "http" 824 lb_port = 80 825 lb_protocol = "http" 826 } 827 828 access_logs { 829 interval = 5 830 bucket = "${aws_s3_bucket.acceslogs_bucket.bucket}" 831 } 832 } 833 ` 834 835 const testAccAWSELBGeneratedName = ` 836 resource "aws_elb" "foo" { 837 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 838 839 listener { 840 instance_port = 8000 841 instance_protocol = "http" 842 lb_port = 80 843 lb_protocol = "http" 844 } 845 } 846 ` 847 848 const testAccAWSELBConfig_AvailabilityZonesUpdate = ` 849 resource "aws_elb" "bar" { 850 availability_zones = ["us-west-2a", "us-west-2b"] 851 852 listener { 853 instance_port = 8000 854 instance_protocol = "http" 855 lb_port = 80 856 lb_protocol = "http" 857 } 858 } 859 ` 860 861 const testAccAWSELBConfig_TagUpdate = ` 862 resource "aws_elb" "bar" { 863 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 864 865 listener { 866 instance_port = 8000 867 instance_protocol = "http" 868 lb_port = 80 869 lb_protocol = "http" 870 } 871 872 tags { 873 foo = "bar" 874 new = "type" 875 } 876 877 cross_zone_load_balancing = true 878 } 879 ` 880 881 const testAccAWSELBConfigNewInstance = ` 882 resource "aws_elb" "bar" { 883 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 884 885 listener { 886 instance_port = 8000 887 instance_protocol = "http" 888 lb_port = 80 889 lb_protocol = "http" 890 } 891 892 instances = ["${aws_instance.foo.id}"] 893 } 894 895 resource "aws_instance" "foo" { 896 # us-west-2 897 ami = "ami-043a5034" 898 instance_type = "t1.micro" 899 } 900 ` 901 902 const testAccAWSELBConfigListenerSSLCertificateId = ` 903 resource "aws_elb" "bar" { 904 availability_zones = ["us-west-2a"] 905 906 listener { 907 instance_port = 8000 908 instance_protocol = "http" 909 ssl_certificate_id = "%s" 910 lb_port = 443 911 lb_protocol = "https" 912 } 913 } 914 ` 915 916 const testAccAWSELBConfigHealthCheck = ` 917 resource "aws_elb" "bar" { 918 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 919 920 listener { 921 instance_port = 8000 922 instance_protocol = "http" 923 lb_port = 80 924 lb_protocol = "http" 925 } 926 927 health_check { 928 healthy_threshold = 5 929 unhealthy_threshold = 5 930 target = "HTTP:8000/" 931 interval = 60 932 timeout = 30 933 } 934 } 935 ` 936 937 const testAccAWSELBConfigHealthCheck_update = ` 938 resource "aws_elb" "bar" { 939 availability_zones = ["us-west-2a"] 940 941 listener { 942 instance_port = 8000 943 instance_protocol = "http" 944 lb_port = 80 945 lb_protocol = "http" 946 } 947 948 health_check { 949 healthy_threshold = 10 950 unhealthy_threshold = 5 951 target = "HTTP:8000/" 952 interval = 60 953 timeout = 30 954 } 955 } 956 ` 957 958 const testAccAWSELBConfigListener_update = ` 959 resource "aws_elb" "bar" { 960 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 961 962 listener { 963 instance_port = 8080 964 instance_protocol = "http" 965 lb_port = 80 966 lb_protocol = "http" 967 } 968 } 969 ` 970 971 const testAccAWSELBConfigIdleTimeout = ` 972 resource "aws_elb" "bar" { 973 availability_zones = ["us-west-2a"] 974 975 listener { 976 instance_port = 8000 977 instance_protocol = "http" 978 lb_port = 80 979 lb_protocol = "http" 980 } 981 982 idle_timeout = 200 983 } 984 ` 985 986 const testAccAWSELBConfigIdleTimeout_update = ` 987 resource "aws_elb" "bar" { 988 availability_zones = ["us-west-2a"] 989 990 listener { 991 instance_port = 8000 992 instance_protocol = "http" 993 lb_port = 80 994 lb_protocol = "http" 995 } 996 997 idle_timeout = 400 998 } 999 ` 1000 1001 const testAccAWSELBConfigConnectionDraining = ` 1002 resource "aws_elb" "bar" { 1003 availability_zones = ["us-west-2a"] 1004 1005 listener { 1006 instance_port = 8000 1007 instance_protocol = "http" 1008 lb_port = 80 1009 lb_protocol = "http" 1010 } 1011 1012 connection_draining = true 1013 connection_draining_timeout = 400 1014 } 1015 ` 1016 1017 const testAccAWSELBConfigConnectionDraining_update_timeout = ` 1018 resource "aws_elb" "bar" { 1019 availability_zones = ["us-west-2a"] 1020 1021 listener { 1022 instance_port = 8000 1023 instance_protocol = "http" 1024 lb_port = 80 1025 lb_protocol = "http" 1026 } 1027 1028 connection_draining = true 1029 connection_draining_timeout = 600 1030 } 1031 ` 1032 1033 const testAccAWSELBConfigConnectionDraining_update_disable = ` 1034 resource "aws_elb" "bar" { 1035 availability_zones = ["us-west-2a"] 1036 1037 listener { 1038 instance_port = 8000 1039 instance_protocol = "http" 1040 lb_port = 80 1041 lb_protocol = "http" 1042 } 1043 1044 connection_draining = false 1045 } 1046 ` 1047 1048 const testAccAWSELBConfigSecurityGroups = ` 1049 resource "aws_elb" "bar" { 1050 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 1051 1052 listener { 1053 instance_port = 8000 1054 instance_protocol = "http" 1055 lb_port = 80 1056 lb_protocol = "http" 1057 } 1058 1059 security_groups = ["${aws_security_group.bar.id}"] 1060 } 1061 1062 resource "aws_security_group" "bar" { 1063 ingress { 1064 protocol = "tcp" 1065 from_port = 80 1066 to_port = 80 1067 cidr_blocks = ["0.0.0.0/0"] 1068 } 1069 1070 tags { 1071 Name = "tf_elb_sg_test" 1072 } 1073 } 1074 ` 1075 1076 // This IAM Server config is lifted from 1077 // builtin/providers/aws/resource_aws_iam_server_certificate_test.go 1078 func testAccELBIAMServerCertConfig(certName string) string { 1079 return fmt.Sprintf(` 1080 resource "aws_iam_server_certificate" "test_cert" { 1081 name = "%s" 1082 certificate_body = <<EOF 1083 -----BEGIN CERTIFICATE----- 1084 MIIDBjCCAe4CCQCGWwBmOiHQdTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB 1085 VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0 1086 cyBQdHkgTHRkMB4XDTE2MDYyMTE2MzM0MVoXDTE3MDYyMTE2MzM0MVowRTELMAkG 1087 A1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0 1088 IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 1089 AL+LFlsCJG5txZp4yuu+lQnuUrgBXRG+irQqcTXlV91Bp5hpmRIyhnGCtWxxDBUL 1090 xrh4WN3VV/0jDzKT976oLgOy3hj56Cdqf+JlZ1qgMN5bHB3mm3aVWnrnsLbBsfwZ 1091 SEbk3Kht/cE1nK2toNVW+rznS3m+eoV3Zn/DUNwGlZr42hGNs6ETn2jURY78ETqR 1092 mW47xvjf86eIo7vULHJaY6xyarPqkL8DZazOmvY06hUGvGwGBny7gugfXqDG+I8n 1093 cPBsGJGSAmHmVV8o0RCB9UjY+TvSMQRpEDoVlvyrGuglsD8to/4+7UcsuDGlRYN6 1094 jmIOC37mOi/jwRfWL1YUa4MCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAPDxTH0oQ 1095 JjKXoJgkmQxurB81RfnK/NrswJVzWbOv6ejcbhwh+/ZgJTMc15BrYcxU6vUW1V/i 1096 Z7APU0qJ0icECACML+a2fRI7YdLCTiPIOmY66HY8MZHAn3dGjU5TeiUflC0n0zkP 1097 mxKJe43kcYLNDItbfvUDo/GoxTXrC3EFVZyU0RhFzoVJdODlTHXMVFCzcbQEBrBJ 1098 xKdShCEc8nFMneZcGFeEU488ntZoWzzms8/QpYrKa5S0Sd7umEU2Kwu4HTkvUFg/ 1099 CqDUFjhydXxYRsxXBBrEiLOE5BdtJR1sH/QHxIJe23C9iHI2nS1NbLziNEApLwC4 1100 GnSud83VUo9G9w== 1101 -----END CERTIFICATE----- 1102 EOF 1103 1104 private_key = <<EOF 1105 -----BEGIN RSA PRIVATE KEY----- 1106 MIIEowIBAAKCAQEAv4sWWwIkbm3FmnjK676VCe5SuAFdEb6KtCpxNeVX3UGnmGmZ 1107 EjKGcYK1bHEMFQvGuHhY3dVX/SMPMpP3vqguA7LeGPnoJ2p/4mVnWqAw3lscHeab 1108 dpVaeuewtsGx/BlIRuTcqG39wTWcra2g1Vb6vOdLeb56hXdmf8NQ3AaVmvjaEY2z 1109 oROfaNRFjvwROpGZbjvG+N/zp4iju9QsclpjrHJqs+qQvwNlrM6a9jTqFQa8bAYG 1110 fLuC6B9eoMb4jydw8GwYkZICYeZVXyjREIH1SNj5O9IxBGkQOhWW/Ksa6CWwPy2j 1111 /j7tRyy4MaVFg3qOYg4LfuY6L+PBF9YvVhRrgwIDAQABAoIBAFqJ4h1Om+3e0WK8 1112 6h4YzdYN4ue7LUTv7hxPW4gASlH5cMDoWURywX3yLNN/dBiWom4b5NWmvJqY8dwU 1113 eSyTznxNFhJ0PjozaxOWnw4FXlQceOPhV2bsHgKudadNU1Y4lSN9lpe+tg2Xy+GE 1114 ituM66RTKCf502w3DioiJpx6OEkxuhrnsQAWNcGB0MnTukm2f+629V+04R5MT5V1 1115 nY+5Phx2BpHgYzWBKh6Px1puu7xFv5SMQda1ndlPIKb4cNp0yYn+1lHNjbOE7QL/ 1116 oEpWgrauS5Zk/APK33v/p3wVYHrKocIFHlPiCW0uIJJLsOZDY8pQXpTlc+/xGLLy 1117 WBu4boECgYEA6xO+1UNh6ndJ3xGuNippH+ucTi/uq1+0tG1bd63v+75tn5l4LyY2 1118 CWHRaWVlVn+WnDslkQTJzFD68X+9M7Cc4oP6WnhTyPamG7HlGv5JxfFHTC9GOKmz 1119 sSc624BDmqYJ7Xzyhe5kc3iHzqG/L72ZF1aijZdrodQMSY1634UX6aECgYEA0Jdr 1120 cBPSN+mgmEY6ogN5h7sO5uNV3TQQtW2IslfWZn6JhSRF4Rf7IReng48CMy9ZhFBy 1121 Q7H2I1pDGjEC9gQHhgVfm+FyMSVqXfCHEW/97pvvu9ougHA0MhPep1twzTGrqg+K 1122 f3PLW8hVkGyCrTfWgbDlPsHgsocA/wTaQOheaqMCgYBat5z+WemQfQZh8kXDm2xE 1123 KD2Cota9BcsLkeQpdFNXWC6f167cqydRSZFx1fJchhJOKjkeFLX3hgzBY6VVLEPu 1124 2jWj8imLNTv3Fhiu6RD5NVppWRkFRuAUbmo1SPNN2+Oa5YwGCXB0a0Alip/oQYex 1125 zPogIB4mLlmrjNCtL4SB4QKBgCEHKMrZSJrz0irqS9RlanPUaZqjenAJE3A2xMNA 1126 Z0FZXdsIEEyA6JGn1i1dkoKaR7lMp5sSbZ/RZfiatBZSMwLEjQv4mYUwoHP5Ztma 1127 +wEyDbaX6G8L1Sfsv3+OWgETkVPfHBXsNtH0mZ/BnrtgsQVeBh52wmZiPAUlNo26 1128 fWCzAoGBAJOjqovLelLWzyQGqPFx/MwuI56UFXd1CmFlCIvF2WxCFmk3tlExoCN1 1129 HqSpt92vsgYgV7+lAb4U7Uy/v012gwiU1LK+vyAE9geo3pTjG73BNzG4H547xtbY 1130 dg+Sd4Wjm89UQoUUoiIcstY7FPbqfBtYKfh4RYHAHV2BwDFqzZCM 1131 -----END RSA PRIVATE KEY----- 1132 EOF 1133 } 1134 1135 resource "aws_elb" "bar" { 1136 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 1137 1138 listener { 1139 instance_port = 8000 1140 instance_protocol = "https" 1141 lb_port = 80 1142 // Protocol should be case insensitive 1143 lb_protocol = "HttPs" 1144 ssl_certificate_id = "${aws_iam_server_certificate.test_cert.arn}" 1145 } 1146 1147 tags { 1148 bar = "baz" 1149 } 1150 1151 cross_zone_load_balancing = true 1152 } 1153 `, certName) 1154 }