github.com/ottenhoff/terraform@v0.7.0-rc1.0.20160607213102-ac2d195cc560/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 MIIDCDCCAfACAQEwDQYJKoZIhvcNAQELBQAwgY4xCzAJBgNVBAYTAlVTMREwDwYD 1085 VQQIDAhOZXcgWW9yazERMA8GA1UEBwwITmV3IFlvcmsxFjAUBgNVBAoMDUJhcmVm 1086 b290IExhYnMxGDAWBgNVBAMMD0phc29uIEJlcmxpbnNreTEnMCUGCSqGSIb3DQEJ 1087 ARYYamFzb25AYmFyZWZvb3Rjb2RlcnMuY29tMB4XDTE1MDYyMTA1MzcwNVoXDTE2 1088 MDYyMDA1MzcwNVowgYgxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEL 1089 MAkGA1UEBwwCTlkxFjAUBgNVBAoMDUJhcmVmb290IExhYnMxGDAWBgNVBAMMD0ph 1090 c29uIEJlcmxpbnNreTEnMCUGCSqGSIb3DQEJARYYamFzb25AYmFyZWZvb3Rjb2Rl 1091 cnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2AVGKRIx+EFM0kkg7 1092 6GoJv9uy0biEDHB4phQBqnDIf8J8/gq9eVvQrR5jJC9Uz4zp5wG/oLZlGuF92/jD 1093 bI/yS+DOAjrh30vN79Au74jGN2Cw8fIak40iDUwjZaczK2Gkna54XIO9pqMcbQ6Q 1094 mLUkQXsqlJ7Q4X2kL3b9iMsXcQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCDGNvU 1095 eioQMVPNlmmxW3+Rwo0Kl+/HtUOmqUDKUDvJnelxulBr7O8w75N/Z7h7+aBJCUkt 1096 tz+DwATZswXtsal6TuzHHpAhpFql82jQZVE8OYkrX84XKRQpm8ZnbyZObMdXTJWk 1097 ArC/rGVIWsvhlbgGM8zu7a3zbeuAESZ8Bn4ZbJxnoaRK8p36/alvzAwkgzSf3oUX 1098 HtU4LrdunevBs6/CbKCWrxYcvNCy8EcmHitqCfQL5nxCCXpgf/Mw1vmIPTwbPSJq 1099 oUkh5yjGRKzhh7QbG1TlFX6zUp4vb+UJn5+g4edHrqivRSjIqYrC45ygVMOABn21 1100 hpMXOlZL+YXfR4Kp 1101 -----END CERTIFICATE----- 1102 EOF 1103 1104 certificate_chain = <<EOF 1105 -----BEGIN CERTIFICATE----- 1106 MIID8TCCAtmgAwIBAgIJAKX2xeCkfFcbMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD 1107 VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYw 1108 FAYDVQQKDA1CYXJlZm9vdCBMYWJzMRgwFgYDVQQDDA9KYXNvbiBCZXJsaW5za3kx 1109 JzAlBgkqhkiG9w0BCQEWGGphc29uQGJhcmVmb290Y29kZXJzLmNvbTAeFw0xNTA2 1110 MjEwNTM2MDZaFw0yNTA2MTgwNTM2MDZaMIGOMQswCQYDVQQGEwJVUzERMA8GA1UE 1111 CAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYwFAYDVQQKDA1CYXJlZm9v 1112 dCBMYWJzMRgwFgYDVQQDDA9KYXNvbiBCZXJsaW5za3kxJzAlBgkqhkiG9w0BCQEW 1113 GGphc29uQGJhcmVmb290Y29kZXJzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP 1114 ADCCAQoCggEBAMteFbwfLz7NyQn3eDxxw22l1ZPBrzfPON0HOAq8nHat4kT4A2cI 1115 45kCtxKMzCVoG84tXoX/rbjGkez7lz9lEfvEuSh+I+UqinFA/sefhcE63foVMZu1 1116 2t6O3+utdxBvOYJwAQaiGW44x0h6fTyqDv6Gc5Ml0uoIVeMWPhT1MREoOcPDz1gb 1117 Ep3VT2aqFULLJedP37qbzS4D04rn1tS7pcm3wYivRyjVNEvs91NsWEvvE1WtS2Cl 1118 2RBt+ihXwq4UNB9UPYG75+FuRcQQvfqameyweyKT9qBmJLELMtYa/KTCYvSch4JY 1119 YVPAPOlhFlO4BcTto/gpBes2WEAWZtE/jnECAwEAAaNQME4wHQYDVR0OBBYEFOna 1120 aiYnm5583EY7FT/mXwTBuLZgMB8GA1UdIwQYMBaAFOnaaiYnm5583EY7FT/mXwTB 1121 uLZgMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABp/dKQ489CCzzB1 1122 IX78p6RFAdda4e3lL6uVjeS3itzFIIiKvdf1/txhmsEeCEYz0El6aMnXLkpk7jAr 1123 kCwlAOOz2R2hlA8k8opKTYX4IQQau8DATslUFAFOvRGOim/TD/Yuch+a/VF2VQKz 1124 L2lUVi5Hjp9KvWe2HQYPjnJaZs/OKAmZQ4uP547dqFrTz6sWfisF1rJ60JH70cyM 1125 qjZQp/xYHTZIB8TCPvLgtVIGFmd/VAHVBFW2p9IBwtSxBIsEPwYQOV3XbwhhmGIv 1126 DWx5TpnEzH7ZM33RNbAKcdwOBxdRY+SI/ua5hYCm4QngAqY69lEuk4zXZpdDLPq1 1127 qxxQx0E= 1128 -----END CERTIFICATE----- 1129 EOF 1130 1131 private_key = <<EOF 1132 -----BEGIN RSA PRIVATE KEY----- 1133 MIICXQIBAAKBgQD2AVGKRIx+EFM0kkg76GoJv9uy0biEDHB4phQBqnDIf8J8/gq9 1134 eVvQrR5jJC9Uz4zp5wG/oLZlGuF92/jDbI/yS+DOAjrh30vN79Au74jGN2Cw8fIa 1135 k40iDUwjZaczK2Gkna54XIO9pqMcbQ6QmLUkQXsqlJ7Q4X2kL3b9iMsXcQIDAQAB 1136 AoGALmVBQ5p6BKx/hMKx7NqAZSZSAP+clQrji12HGGlUq/usanZfAC0LK+f6eygv 1137 5QbfxJ1UrxdYTukq7dm2qOSooOMUuukWInqC6ztjdLwH70CKnl0bkNB3/NkW2VNc 1138 32YiUuZCM9zaeBuEUclKNs+dhD2EeGdJF8KGntWGOTU/M4ECQQD9gdYb38PvaMdu 1139 opM3sKJF5n9pMoLDleBpCGqq3nD3DFn0V6PHQAwn30EhRN+7BbUEpde5PmfoIdAR 1140 uDlj/XPlAkEA+GyY1e4uU9rz+1K4ubxmtXTp9ZIR2LsqFy5L/MS5hqX2zq5GGq8g 1141 jZYDxnxPEUrxaWQH4nh0qdu3skUBi4a0nQJBAKJaqLkpUd7eB/t++zHLWeHSgP7q 1142 bny8XABod4f+9fICYwntpuJQzngqrxeTeIXaXdggLkxg/0LXhN4UUg0LoVECQQDE 1143 Pi1h2dyY+37/CzLH7q+IKopjJneYqQmv9C+sxs70MgjM7liM3ckub9IdqrdfJr+c 1144 DJw56APo5puvZNm6mbf1AkBVMDyfdOOyoHpJjrhmZWo6QqynujfwErrBYQ0sZQ3l 1145 O57Z0RUNQ8DRyymhLd2t5nAHTfpcFA1sBeKE6CziLbZB 1146 -----END RSA PRIVATE KEY----- 1147 EOF 1148 } 1149 1150 resource "aws_elb" "bar" { 1151 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 1152 1153 listener { 1154 instance_port = 8000 1155 instance_protocol = "https" 1156 lb_port = 80 1157 // Protocol should be case insensitive 1158 lb_protocol = "HttPs" 1159 ssl_certificate_id = "${aws_iam_server_certificate.test_cert.arn}" 1160 } 1161 1162 tags { 1163 bar = "baz" 1164 } 1165 1166 cross_zone_load_balancing = true 1167 } 1168 `, certName) 1169 }