github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/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.1713209538.bucket", "terraform-access-logs-bucket"), 106 resource.TestCheckResourceAttr( 107 "aws_elb.foo", "access_logs.1713209538.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.3484319807.healthy_threshold", "5"), 343 resource.TestCheckResourceAttr( 344 "aws_elb.bar", "health_check.3484319807.unhealthy_threshold", "5"), 345 resource.TestCheckResourceAttr( 346 "aws_elb.bar", "health_check.3484319807.target", "HTTP:8000/"), 347 resource.TestCheckResourceAttr( 348 "aws_elb.bar", "health_check.3484319807.timeout", "30"), 349 resource.TestCheckResourceAttr( 350 "aws_elb.bar", "health_check.3484319807.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.3484319807.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.2648756019.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 resource.TestCheckResourceAttr( 499 "aws_elb.bar", "security_groups.#", "0", 500 ), 501 ), 502 }, 503 resource.TestStep{ 504 Config: testAccAWSELBConfigSecurityGroups, 505 Check: resource.ComposeTestCheckFunc( 506 resource.TestCheckResourceAttr( 507 "aws_elb.bar", "security_groups.#", "1", 508 ), 509 ), 510 }, 511 }, 512 }) 513 } 514 515 // Unit test for listeners hash 516 func TestResourceAwsElbListenerHash(t *testing.T) { 517 cases := map[string]struct { 518 Left map[string]interface{} 519 Right map[string]interface{} 520 Match bool 521 }{ 522 "protocols are case insensitive": { 523 map[string]interface{}{ 524 "instance_port": 80, 525 "instance_protocol": "TCP", 526 "lb_port": 80, 527 "lb_protocol": "TCP", 528 }, 529 map[string]interface{}{ 530 "instance_port": 80, 531 "instance_protocol": "Tcp", 532 "lb_port": 80, 533 "lb_protocol": "tcP", 534 }, 535 true, 536 }, 537 } 538 539 for tn, tc := range cases { 540 leftHash := resourceAwsElbListenerHash(tc.Left) 541 rightHash := resourceAwsElbListenerHash(tc.Right) 542 if leftHash == rightHash != tc.Match { 543 t.Fatalf("%s: expected match: %t, but did not get it", tn, tc.Match) 544 } 545 } 546 } 547 548 func TestResourceAWSELB_validateElbNameCannotBeginWithHyphen(t *testing.T) { 549 var elbName = "-Testing123" 550 _, errors := validateElbName(elbName, "SampleKey") 551 552 if len(errors) != 1 { 553 t.Fatalf("Expected the ELB Name to trigger a validation error") 554 } 555 } 556 557 func TestResourceAWSELB_validateElbNameCannotBeLongerThen32Characters(t *testing.T) { 558 var elbName = "Testing123dddddddddddddddddddvvvv" 559 _, errors := validateElbName(elbName, "SampleKey") 560 561 if len(errors) != 1 { 562 t.Fatalf("Expected the ELB Name to trigger a validation error") 563 } 564 } 565 566 func TestResourceAWSELB_validateElbNameCannotHaveSpecialCharacters(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_validateElbNameCannotEndWithHyphen(t *testing.T) { 576 var elbName = "Testing123-" 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 testAccCheckAWSELBDestroy(s *terraform.State) error { 585 conn := testAccProvider.Meta().(*AWSClient).elbconn 586 587 for _, rs := range s.RootModule().Resources { 588 if rs.Type != "aws_elb" { 589 continue 590 } 591 592 describe, err := conn.DescribeLoadBalancers(&elb.DescribeLoadBalancersInput{ 593 LoadBalancerNames: []*string{aws.String(rs.Primary.ID)}, 594 }) 595 596 if err == nil { 597 if len(describe.LoadBalancerDescriptions) != 0 && 598 *describe.LoadBalancerDescriptions[0].LoadBalancerName == rs.Primary.ID { 599 return fmt.Errorf("ELB still exists") 600 } 601 } 602 603 // Verify the error 604 providerErr, ok := err.(awserr.Error) 605 if !ok { 606 return err 607 } 608 609 if providerErr.Code() != "LoadBalancerNotFound" { 610 return fmt.Errorf("Unexpected error: %s", err) 611 } 612 } 613 614 return nil 615 } 616 617 func testAccCheckAWSELBAttributes(conf *elb.LoadBalancerDescription) resource.TestCheckFunc { 618 return func(s *terraform.State) error { 619 zones := []string{"us-west-2a", "us-west-2b", "us-west-2c"} 620 azs := make([]string, 0, len(conf.AvailabilityZones)) 621 for _, x := range conf.AvailabilityZones { 622 azs = append(azs, *x) 623 } 624 sort.StringSlice(azs).Sort() 625 if !reflect.DeepEqual(azs, zones) { 626 return fmt.Errorf("bad availability_zones") 627 } 628 629 l := elb.Listener{ 630 InstancePort: aws.Int64(int64(8000)), 631 InstanceProtocol: aws.String("HTTP"), 632 LoadBalancerPort: aws.Int64(int64(80)), 633 Protocol: aws.String("HTTP"), 634 } 635 636 if !reflect.DeepEqual(conf.ListenerDescriptions[0].Listener, &l) { 637 return fmt.Errorf( 638 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 639 conf.ListenerDescriptions[0].Listener, 640 l) 641 } 642 643 if *conf.DNSName == "" { 644 return fmt.Errorf("empty dns_name") 645 } 646 647 return nil 648 } 649 } 650 651 func testAccCheckAWSELBAttributesHealthCheck(conf *elb.LoadBalancerDescription) resource.TestCheckFunc { 652 return func(s *terraform.State) error { 653 zones := []string{"us-west-2a", "us-west-2b", "us-west-2c"} 654 azs := make([]string, 0, len(conf.AvailabilityZones)) 655 for _, x := range conf.AvailabilityZones { 656 azs = append(azs, *x) 657 } 658 sort.StringSlice(azs).Sort() 659 if !reflect.DeepEqual(azs, zones) { 660 return fmt.Errorf("bad availability_zones") 661 } 662 663 check := &elb.HealthCheck{ 664 Timeout: aws.Int64(int64(30)), 665 UnhealthyThreshold: aws.Int64(int64(5)), 666 HealthyThreshold: aws.Int64(int64(5)), 667 Interval: aws.Int64(int64(60)), 668 Target: aws.String("HTTP:8000/"), 669 } 670 671 if !reflect.DeepEqual(conf.HealthCheck, check) { 672 return fmt.Errorf( 673 "Got:\n\n%#v\n\nExpected:\n\n%#v\n", 674 conf.HealthCheck, 675 check) 676 } 677 678 if *conf.DNSName == "" { 679 return fmt.Errorf("empty dns_name") 680 } 681 682 return nil 683 } 684 } 685 686 func testAccCheckAWSELBExists(n string, res *elb.LoadBalancerDescription) resource.TestCheckFunc { 687 return func(s *terraform.State) error { 688 rs, ok := s.RootModule().Resources[n] 689 if !ok { 690 return fmt.Errorf("Not found: %s", n) 691 } 692 693 if rs.Primary.ID == "" { 694 return fmt.Errorf("No ELB ID is set") 695 } 696 697 conn := testAccProvider.Meta().(*AWSClient).elbconn 698 699 describe, err := conn.DescribeLoadBalancers(&elb.DescribeLoadBalancersInput{ 700 LoadBalancerNames: []*string{aws.String(rs.Primary.ID)}, 701 }) 702 703 if err != nil { 704 return err 705 } 706 707 if len(describe.LoadBalancerDescriptions) != 1 || 708 *describe.LoadBalancerDescriptions[0].LoadBalancerName != rs.Primary.ID { 709 return fmt.Errorf("ELB not found") 710 } 711 712 *res = *describe.LoadBalancerDescriptions[0] 713 714 // Confirm source_security_group_id for ELBs in a VPC 715 // See https://github.com/hashicorp/terraform/pull/3780 716 if res.VPCId != nil { 717 sgid := rs.Primary.Attributes["source_security_group_id"] 718 if sgid == "" { 719 return fmt.Errorf("Expected to find source_security_group_id for ELB, but was empty") 720 } 721 } 722 723 return nil 724 } 725 } 726 727 const testAccAWSELBConfig = ` 728 resource "aws_elb" "bar" { 729 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 730 731 listener { 732 instance_port = 8000 733 instance_protocol = "http" 734 lb_port = 80 735 // Protocol should be case insensitive 736 lb_protocol = "HttP" 737 } 738 739 tags { 740 bar = "baz" 741 } 742 743 cross_zone_load_balancing = true 744 } 745 ` 746 747 const testAccAWSELBFullRangeOfCharacters = ` 748 resource "aws_elb" "foo" { 749 name = "%s" 750 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 751 752 listener { 753 instance_port = 8000 754 instance_protocol = "http" 755 lb_port = 80 756 lb_protocol = "http" 757 } 758 } 759 ` 760 761 const testAccAWSELBAccessLogs = ` 762 resource "aws_elb" "foo" { 763 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 764 765 listener { 766 instance_port = 8000 767 instance_protocol = "http" 768 lb_port = 80 769 lb_protocol = "http" 770 } 771 } 772 ` 773 const testAccAWSELBAccessLogsOn = ` 774 # an S3 bucket configured for Access logs 775 # The 797873946194 is the AWS ID for us-west-2, so this test 776 # must be ran in us-west-2 777 resource "aws_s3_bucket" "acceslogs_bucket" { 778 bucket = "terraform-access-logs-bucket" 779 acl = "private" 780 force_destroy = true 781 policy = <<EOF 782 { 783 "Id": "Policy1446577137248", 784 "Statement": [ 785 { 786 "Action": "s3:PutObject", 787 "Effect": "Allow", 788 "Principal": { 789 "AWS": "arn:aws:iam::797873946194:root" 790 }, 791 "Resource": "arn:aws:s3:::terraform-access-logs-bucket/*", 792 "Sid": "Stmt1446575236270" 793 } 794 ], 795 "Version": "2012-10-17" 796 } 797 EOF 798 } 799 800 resource "aws_elb" "foo" { 801 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 802 803 listener { 804 instance_port = 8000 805 instance_protocol = "http" 806 lb_port = 80 807 lb_protocol = "http" 808 } 809 810 access_logs { 811 interval = 5 812 bucket = "${aws_s3_bucket.acceslogs_bucket.bucket}" 813 } 814 } 815 ` 816 817 const testAccAWSELBGeneratedName = ` 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 ` 829 830 const testAccAWSELBConfig_AvailabilityZonesUpdate = ` 831 resource "aws_elb" "bar" { 832 availability_zones = ["us-west-2a", "us-west-2b"] 833 834 listener { 835 instance_port = 8000 836 instance_protocol = "http" 837 lb_port = 80 838 lb_protocol = "http" 839 } 840 } 841 ` 842 843 const testAccAWSELBConfig_TagUpdate = ` 844 resource "aws_elb" "bar" { 845 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 846 847 listener { 848 instance_port = 8000 849 instance_protocol = "http" 850 lb_port = 80 851 lb_protocol = "http" 852 } 853 854 tags { 855 foo = "bar" 856 new = "type" 857 } 858 859 cross_zone_load_balancing = true 860 } 861 ` 862 863 const testAccAWSELBConfigNewInstance = ` 864 resource "aws_elb" "bar" { 865 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 866 867 listener { 868 instance_port = 8000 869 instance_protocol = "http" 870 lb_port = 80 871 lb_protocol = "http" 872 } 873 874 instances = ["${aws_instance.foo.id}"] 875 } 876 877 resource "aws_instance" "foo" { 878 # us-west-2 879 ami = "ami-043a5034" 880 instance_type = "t1.micro" 881 } 882 ` 883 884 const testAccAWSELBConfigListenerSSLCertificateId = ` 885 resource "aws_elb" "bar" { 886 availability_zones = ["us-west-2a"] 887 888 listener { 889 instance_port = 8000 890 instance_protocol = "http" 891 ssl_certificate_id = "%s" 892 lb_port = 443 893 lb_protocol = "https" 894 } 895 } 896 ` 897 898 const testAccAWSELBConfigHealthCheck = ` 899 resource "aws_elb" "bar" { 900 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 901 902 listener { 903 instance_port = 8000 904 instance_protocol = "http" 905 lb_port = 80 906 lb_protocol = "http" 907 } 908 909 health_check { 910 healthy_threshold = 5 911 unhealthy_threshold = 5 912 target = "HTTP:8000/" 913 interval = 60 914 timeout = 30 915 } 916 } 917 ` 918 919 const testAccAWSELBConfigHealthCheck_update = ` 920 resource "aws_elb" "bar" { 921 availability_zones = ["us-west-2a"] 922 923 listener { 924 instance_port = 8000 925 instance_protocol = "http" 926 lb_port = 80 927 lb_protocol = "http" 928 } 929 930 health_check { 931 healthy_threshold = 10 932 unhealthy_threshold = 5 933 target = "HTTP:8000/" 934 interval = 60 935 timeout = 30 936 } 937 } 938 ` 939 940 const testAccAWSELBConfigListener_update = ` 941 resource "aws_elb" "bar" { 942 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 943 944 listener { 945 instance_port = 8080 946 instance_protocol = "http" 947 lb_port = 80 948 lb_protocol = "http" 949 } 950 } 951 ` 952 953 const testAccAWSELBConfigIdleTimeout = ` 954 resource "aws_elb" "bar" { 955 availability_zones = ["us-west-2a"] 956 957 listener { 958 instance_port = 8000 959 instance_protocol = "http" 960 lb_port = 80 961 lb_protocol = "http" 962 } 963 964 idle_timeout = 200 965 } 966 ` 967 968 const testAccAWSELBConfigIdleTimeout_update = ` 969 resource "aws_elb" "bar" { 970 availability_zones = ["us-west-2a"] 971 972 listener { 973 instance_port = 8000 974 instance_protocol = "http" 975 lb_port = 80 976 lb_protocol = "http" 977 } 978 979 idle_timeout = 400 980 } 981 ` 982 983 const testAccAWSELBConfigConnectionDraining = ` 984 resource "aws_elb" "bar" { 985 availability_zones = ["us-west-2a"] 986 987 listener { 988 instance_port = 8000 989 instance_protocol = "http" 990 lb_port = 80 991 lb_protocol = "http" 992 } 993 994 connection_draining = true 995 connection_draining_timeout = 400 996 } 997 ` 998 999 const testAccAWSELBConfigConnectionDraining_update_timeout = ` 1000 resource "aws_elb" "bar" { 1001 availability_zones = ["us-west-2a"] 1002 1003 listener { 1004 instance_port = 8000 1005 instance_protocol = "http" 1006 lb_port = 80 1007 lb_protocol = "http" 1008 } 1009 1010 connection_draining = true 1011 connection_draining_timeout = 600 1012 } 1013 ` 1014 1015 const testAccAWSELBConfigConnectionDraining_update_disable = ` 1016 resource "aws_elb" "bar" { 1017 availability_zones = ["us-west-2a"] 1018 1019 listener { 1020 instance_port = 8000 1021 instance_protocol = "http" 1022 lb_port = 80 1023 lb_protocol = "http" 1024 } 1025 1026 connection_draining = false 1027 } 1028 ` 1029 1030 const testAccAWSELBConfigSecurityGroups = ` 1031 resource "aws_elb" "bar" { 1032 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 1033 1034 listener { 1035 instance_port = 8000 1036 instance_protocol = "http" 1037 lb_port = 80 1038 lb_protocol = "http" 1039 } 1040 1041 security_groups = ["${aws_security_group.bar.id}"] 1042 } 1043 1044 resource "aws_security_group" "bar" { 1045 ingress { 1046 protocol = "tcp" 1047 from_port = 80 1048 to_port = 80 1049 cidr_blocks = ["0.0.0.0/0"] 1050 } 1051 } 1052 ` 1053 1054 // This IAM Server config is lifted from 1055 // builtin/providers/aws/resource_aws_iam_server_certificate_test.go 1056 func testAccELBIAMServerCertConfig(certName string) string { 1057 return fmt.Sprintf(` 1058 resource "aws_iam_server_certificate" "test_cert" { 1059 name = "%s" 1060 certificate_body = <<EOF 1061 -----BEGIN CERTIFICATE----- 1062 MIIDCDCCAfACAQEwDQYJKoZIhvcNAQELBQAwgY4xCzAJBgNVBAYTAlVTMREwDwYD 1063 VQQIDAhOZXcgWW9yazERMA8GA1UEBwwITmV3IFlvcmsxFjAUBgNVBAoMDUJhcmVm 1064 b290IExhYnMxGDAWBgNVBAMMD0phc29uIEJlcmxpbnNreTEnMCUGCSqGSIb3DQEJ 1065 ARYYamFzb25AYmFyZWZvb3Rjb2RlcnMuY29tMB4XDTE1MDYyMTA1MzcwNVoXDTE2 1066 MDYyMDA1MzcwNVowgYgxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEL 1067 MAkGA1UEBwwCTlkxFjAUBgNVBAoMDUJhcmVmb290IExhYnMxGDAWBgNVBAMMD0ph 1068 c29uIEJlcmxpbnNreTEnMCUGCSqGSIb3DQEJARYYamFzb25AYmFyZWZvb3Rjb2Rl 1069 cnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2AVGKRIx+EFM0kkg7 1070 6GoJv9uy0biEDHB4phQBqnDIf8J8/gq9eVvQrR5jJC9Uz4zp5wG/oLZlGuF92/jD 1071 bI/yS+DOAjrh30vN79Au74jGN2Cw8fIak40iDUwjZaczK2Gkna54XIO9pqMcbQ6Q 1072 mLUkQXsqlJ7Q4X2kL3b9iMsXcQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCDGNvU 1073 eioQMVPNlmmxW3+Rwo0Kl+/HtUOmqUDKUDvJnelxulBr7O8w75N/Z7h7+aBJCUkt 1074 tz+DwATZswXtsal6TuzHHpAhpFql82jQZVE8OYkrX84XKRQpm8ZnbyZObMdXTJWk 1075 ArC/rGVIWsvhlbgGM8zu7a3zbeuAESZ8Bn4ZbJxnoaRK8p36/alvzAwkgzSf3oUX 1076 HtU4LrdunevBs6/CbKCWrxYcvNCy8EcmHitqCfQL5nxCCXpgf/Mw1vmIPTwbPSJq 1077 oUkh5yjGRKzhh7QbG1TlFX6zUp4vb+UJn5+g4edHrqivRSjIqYrC45ygVMOABn21 1078 hpMXOlZL+YXfR4Kp 1079 -----END CERTIFICATE----- 1080 EOF 1081 1082 certificate_chain = <<EOF 1083 -----BEGIN CERTIFICATE----- 1084 MIID8TCCAtmgAwIBAgIJAKX2xeCkfFcbMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD 1085 VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYw 1086 FAYDVQQKDA1CYXJlZm9vdCBMYWJzMRgwFgYDVQQDDA9KYXNvbiBCZXJsaW5za3kx 1087 JzAlBgkqhkiG9w0BCQEWGGphc29uQGJhcmVmb290Y29kZXJzLmNvbTAeFw0xNTA2 1088 MjEwNTM2MDZaFw0yNTA2MTgwNTM2MDZaMIGOMQswCQYDVQQGEwJVUzERMA8GA1UE 1089 CAwITmV3IFlvcmsxETAPBgNVBAcMCE5ldyBZb3JrMRYwFAYDVQQKDA1CYXJlZm9v 1090 dCBMYWJzMRgwFgYDVQQDDA9KYXNvbiBCZXJsaW5za3kxJzAlBgkqhkiG9w0BCQEW 1091 GGphc29uQGJhcmVmb290Y29kZXJzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP 1092 ADCCAQoCggEBAMteFbwfLz7NyQn3eDxxw22l1ZPBrzfPON0HOAq8nHat4kT4A2cI 1093 45kCtxKMzCVoG84tXoX/rbjGkez7lz9lEfvEuSh+I+UqinFA/sefhcE63foVMZu1 1094 2t6O3+utdxBvOYJwAQaiGW44x0h6fTyqDv6Gc5Ml0uoIVeMWPhT1MREoOcPDz1gb 1095 Ep3VT2aqFULLJedP37qbzS4D04rn1tS7pcm3wYivRyjVNEvs91NsWEvvE1WtS2Cl 1096 2RBt+ihXwq4UNB9UPYG75+FuRcQQvfqameyweyKT9qBmJLELMtYa/KTCYvSch4JY 1097 YVPAPOlhFlO4BcTto/gpBes2WEAWZtE/jnECAwEAAaNQME4wHQYDVR0OBBYEFOna 1098 aiYnm5583EY7FT/mXwTBuLZgMB8GA1UdIwQYMBaAFOnaaiYnm5583EY7FT/mXwTB 1099 uLZgMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABp/dKQ489CCzzB1 1100 IX78p6RFAdda4e3lL6uVjeS3itzFIIiKvdf1/txhmsEeCEYz0El6aMnXLkpk7jAr 1101 kCwlAOOz2R2hlA8k8opKTYX4IQQau8DATslUFAFOvRGOim/TD/Yuch+a/VF2VQKz 1102 L2lUVi5Hjp9KvWe2HQYPjnJaZs/OKAmZQ4uP547dqFrTz6sWfisF1rJ60JH70cyM 1103 qjZQp/xYHTZIB8TCPvLgtVIGFmd/VAHVBFW2p9IBwtSxBIsEPwYQOV3XbwhhmGIv 1104 DWx5TpnEzH7ZM33RNbAKcdwOBxdRY+SI/ua5hYCm4QngAqY69lEuk4zXZpdDLPq1 1105 qxxQx0E= 1106 -----END CERTIFICATE----- 1107 EOF 1108 1109 private_key = <<EOF 1110 -----BEGIN RSA PRIVATE KEY----- 1111 MIICXQIBAAKBgQD2AVGKRIx+EFM0kkg76GoJv9uy0biEDHB4phQBqnDIf8J8/gq9 1112 eVvQrR5jJC9Uz4zp5wG/oLZlGuF92/jDbI/yS+DOAjrh30vN79Au74jGN2Cw8fIa 1113 k40iDUwjZaczK2Gkna54XIO9pqMcbQ6QmLUkQXsqlJ7Q4X2kL3b9iMsXcQIDAQAB 1114 AoGALmVBQ5p6BKx/hMKx7NqAZSZSAP+clQrji12HGGlUq/usanZfAC0LK+f6eygv 1115 5QbfxJ1UrxdYTukq7dm2qOSooOMUuukWInqC6ztjdLwH70CKnl0bkNB3/NkW2VNc 1116 32YiUuZCM9zaeBuEUclKNs+dhD2EeGdJF8KGntWGOTU/M4ECQQD9gdYb38PvaMdu 1117 opM3sKJF5n9pMoLDleBpCGqq3nD3DFn0V6PHQAwn30EhRN+7BbUEpde5PmfoIdAR 1118 uDlj/XPlAkEA+GyY1e4uU9rz+1K4ubxmtXTp9ZIR2LsqFy5L/MS5hqX2zq5GGq8g 1119 jZYDxnxPEUrxaWQH4nh0qdu3skUBi4a0nQJBAKJaqLkpUd7eB/t++zHLWeHSgP7q 1120 bny8XABod4f+9fICYwntpuJQzngqrxeTeIXaXdggLkxg/0LXhN4UUg0LoVECQQDE 1121 Pi1h2dyY+37/CzLH7q+IKopjJneYqQmv9C+sxs70MgjM7liM3ckub9IdqrdfJr+c 1122 DJw56APo5puvZNm6mbf1AkBVMDyfdOOyoHpJjrhmZWo6QqynujfwErrBYQ0sZQ3l 1123 O57Z0RUNQ8DRyymhLd2t5nAHTfpcFA1sBeKE6CziLbZB 1124 -----END RSA PRIVATE KEY----- 1125 EOF 1126 } 1127 1128 resource "aws_elb" "bar" { 1129 availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] 1130 1131 listener { 1132 instance_port = 8000 1133 instance_protocol = "https" 1134 lb_port = 80 1135 // Protocol should be case insensitive 1136 lb_protocol = "HttPs" 1137 ssl_certificate_id = "${aws_iam_server_certificate.test_cert.arn}" 1138 } 1139 1140 tags { 1141 bar = "baz" 1142 } 1143 1144 cross_zone_load_balancing = true 1145 } 1146 `, certName) 1147 }