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