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