Merge branch 'jwaldrip-elb-connection-settings'

This commit is contained in:
Mitchell Hashimoto 2015-04-22 08:38:27 +02:00
commit 1e9f63ef3c
3 changed files with 249 additions and 28 deletions

View File

@ -81,6 +81,24 @@ func resourceAwsElb() *schema.Resource {
}, },
}, },
"idle_timeout": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 30,
},
"connection_draining": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"connection_draining_timeout": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Default: 300,
},
"listener": &schema.Schema{ "listener": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Required: true, Required: true,
@ -213,38 +231,16 @@ func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error {
d.Set("tags", tagsToMapELB(tags)) d.Set("tags", tagsToMapELB(tags))
if d.HasChange("health_check") {
vs := d.Get("health_check").(*schema.Set).List()
if len(vs) > 0 {
check := vs[0].(map[string]interface{})
configureHealthCheckOpts := elb.ConfigureHealthCheckInput{
LoadBalancerName: aws.String(d.Id()),
HealthCheck: &elb.HealthCheck{
HealthyThreshold: aws.Long(int64(check["healthy_threshold"].(int))),
UnhealthyThreshold: aws.Long(int64(check["unhealthy_threshold"].(int))),
Interval: aws.Long(int64(check["interval"].(int))),
Target: aws.String(check["target"].(string)),
Timeout: aws.Long(int64(check["timeout"].(int))),
},
}
_, err = elbconn.ConfigureHealthCheck(&configureHealthCheckOpts)
if err != nil {
return fmt.Errorf("Failure configuring health check: %s", err)
}
}
}
return resourceAwsElbUpdate(d, meta) return resourceAwsElbUpdate(d, meta)
} }
func resourceAwsElbRead(d *schema.ResourceData, meta interface{}) error { func resourceAwsElbRead(d *schema.ResourceData, meta interface{}) error {
elbconn := meta.(*AWSClient).elbconn elbconn := meta.(*AWSClient).elbconn
elbName := d.Id()
// Retrieve the ELB properties for updating the state // Retrieve the ELB properties for updating the state
describeElbOpts := &elb.DescribeLoadBalancersInput{ describeElbOpts := &elb.DescribeLoadBalancersInput{
LoadBalancerNames: []*string{aws.String(d.Id())}, LoadBalancerNames: []*string{aws.String(elbName)},
} }
describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts) describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
@ -261,6 +257,22 @@ func resourceAwsElbRead(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions) return fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancerDescriptions)
} }
describeAttrsOpts := &elb.DescribeLoadBalancerAttributesInput{
LoadBalancerName: aws.String(elbName),
}
describeAttrsResp, err := elbconn.DescribeLoadBalancerAttributes(describeAttrsOpts)
if err != nil {
if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "LoadBalancerNotFound" {
// The ELB is gone now, so just remove it from the state
d.SetId("")
return nil
}
return fmt.Errorf("Error retrieving ELB: %s", err)
}
lbAttrs := describeAttrsResp.LoadBalancerAttributes
lb := describeResp.LoadBalancerDescriptions[0] lb := describeResp.LoadBalancerDescriptions[0]
d.Set("name", *lb.LoadBalancerName) d.Set("name", *lb.LoadBalancerName)
@ -271,6 +283,9 @@ func resourceAwsElbRead(d *schema.ResourceData, meta interface{}) error {
d.Set("listener", flattenListeners(lb.ListenerDescriptions)) d.Set("listener", flattenListeners(lb.ListenerDescriptions))
d.Set("security_groups", lb.SecurityGroups) d.Set("security_groups", lb.SecurityGroups)
d.Set("subnets", lb.Subnets) d.Set("subnets", lb.Subnets)
d.Set("idle_timeout", lbAttrs.ConnectionSettings.IdleTimeout)
d.Set("connection_draining", lbAttrs.ConnectionDraining.Enabled)
d.Set("connection_draining_timeout", lbAttrs.ConnectionDraining.Timeout)
resp, err := elbconn.DescribeTags(&elb.DescribeTagsInput{ resp, err := elbconn.DescribeTags(&elb.DescribeTagsInput{
LoadBalancerNames: []*string{lb.LoadBalancerName}, LoadBalancerNames: []*string{lb.LoadBalancerName},
@ -372,7 +387,7 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
} }
log.Println("[INFO] outside modify attributes") log.Println("[INFO] outside modify attributes")
if d.HasChange("cross_zone_load_balancing") { if d.HasChange("cross_zone_load_balancing") || d.HasChange("idle_timeout") || d.HasChange("connection_draining") || d.HasChange("connection_draining_timeout") {
log.Println("[INFO] inside modify attributes") log.Println("[INFO] inside modify attributes")
attrs := elb.ModifyLoadBalancerAttributesInput{ attrs := elb.ModifyLoadBalancerAttributesInput{
LoadBalancerName: aws.String(d.Get("name").(string)), LoadBalancerName: aws.String(d.Get("name").(string)),
@ -380,13 +395,23 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
CrossZoneLoadBalancing: &elb.CrossZoneLoadBalancing{ CrossZoneLoadBalancing: &elb.CrossZoneLoadBalancing{
Enabled: aws.Boolean(d.Get("cross_zone_load_balancing").(bool)), Enabled: aws.Boolean(d.Get("cross_zone_load_balancing").(bool)),
}, },
ConnectionSettings: &elb.ConnectionSettings{
IdleTimeout: aws.Integer(d.Get("idle_timeout").(int)),
},
ConnectionDraining: &elb.ConnectionDraining{
Enabled: aws.Boolean(d.Get("connection_draining").(bool)),
Timeout: aws.Integer(d.Get("connection_draining_timeout").(int)),
},
}, },
} }
_, err := elbconn.ModifyLoadBalancerAttributes(&attrs) _, err := elbconn.ModifyLoadBalancerAttributes(&attrs)
if err != nil { if err != nil {
return fmt.Errorf("Failure configuring cross zone balancing: %s", err) return fmt.Errorf("Failure configuring elb attributes: %s", err)
} }
d.SetPartial("cross_zone_load_balancing") d.SetPartial("cross_zone_load_balancing")
d.SetPartial("idle_timeout")
d.SetPartial("connection_draining")
d.SetPartial("connection_draining_timeout")
} }
if d.HasChange("health_check") { if d.HasChange("health_check") {
@ -413,9 +438,9 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
if err := setTagsELB(elbconn, d); err != nil { if err := setTagsELB(elbconn, d); err != nil {
return err return err
} else {
d.SetPartial("tags")
} }
d.SetPartial("tags")
d.Partial(false) d.Partial(false)
return resourceAwsElbRead(d, meta) return resourceAwsElbRead(d, meta)

View File

@ -227,6 +227,114 @@ func TestAccAWSELBUpdate_HealthCheck(t *testing.T) {
}) })
} }
func testAccAWSELB_Timeout(t *testing.T) {
var conf elb.LoadBalancerDescription
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSELBDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSELBConfigIdleTimeout,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSELBExists("aws_elb.bar", &conf),
resource.TestCheckResourceAttr(
"aws_elb.bar", "idle_timeout", "200",
),
),
},
},
})
}
func testAccAWSELBUpdate_Timeout(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSELBDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSELBConfigIdleTimeout,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_elb.bar", "idle_timeout", "200",
),
),
},
resource.TestStep{
Config: testAccAWSELBConfigIdleTimeout_update,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_elb.bar", "idle_timeout", "400",
),
),
},
},
})
}
func testAccAWSELB_ConnectionDraining(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSELBDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSELBConfigConnectionDraining,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_elb.bar", "connection_draining", "true",
),
resource.TestCheckResourceAttr(
"aws_elb.bar", "connection_draining_timeout", "400",
),
),
},
},
})
}
func testAccAWSELBUpdate_ConnectionDraining(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSELBDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSELBConfigConnectionDraining,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_elb.bar", "connection_draining", "true",
),
resource.TestCheckResourceAttr(
"aws_elb.bar", "connection_draining_timeout", "400",
),
),
},
resource.TestStep{
Config: testAccAWSELBConfigConnectionDraining_update_timeout,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_elb.bar", "connection_draining", "true",
),
resource.TestCheckResourceAttr(
"aws_elb.bar", "connection_draining_timeout", "600",
),
),
},
resource.TestStep{
Config: testAccAWSELBConfigConnectionDraining_update_disable,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_elb.bar", "connection_draining", "false",
),
),
},
},
})
}
func testAccCheckAWSELBDestroy(s *terraform.State) error { func testAccCheckAWSELBDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).elbconn conn := testAccProvider.Meta().(*AWSClient).elbconn
@ -504,3 +612,85 @@ resource "aws_elb" "bar" {
} }
} }
` `
const testAccAWSELBConfigIdleTimeout = `
resource "aws_elb" "bar" {
name = "foobar-terraform-test"
availability_zones = ["us-west-2a"]
listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
idle_timeout = 200
}
`
const testAccAWSELBConfigIdleTimeout_update = `
resource "aws_elb" "bar" {
name = "foobar-terraform-test"
availability_zones = ["us-west-2a"]
listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
idle_timeout = 400
}
`
const testAccAWSELBConfigConnectionDraining = `
resource "aws_elb" "bar" {
name = "foobar-terraform-test"
availability_zones = ["us-west-2a"]
listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
connection_draining = true
connection_draining_timeout = 400
}
`
const testAccAWSELBConfigConnectionDraining_update_timeout = `
resource "aws_elb" "bar" {
name = "foobar-terraform-test"
availability_zones = ["us-west-2a"]
listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
connection_draining = true
connection_draining_timeout = 400
}
`
const testAccAWSELBConfigConnectionDraining_update_disable = `
resource "aws_elb" "bar" {
name = "foobar-terraform-test"
availability_zones = ["us-west-2a"]
listener {
instance_port = 8000
instance_protocol = "http"
lb_port = 80
lb_protocol = "http"
}
connection_draining = false
}
`

View File

@ -43,6 +43,9 @@ resource "aws_elb" "bar" {
instances = ["${aws_instance.foo.id}"] instances = ["${aws_instance.foo.id}"]
cross_zone_load_balancing = true cross_zone_load_balancing = true
idle_timeout = 400
connection_draining = true
connection_draining_timeout = 400
} }
``` ```
@ -59,6 +62,9 @@ The following arguments are supported:
* `listener` - (Required) A list of listener blocks. Listeners documented below. * `listener` - (Required) A list of listener blocks. Listeners documented below.
* `health_check` - (Optional) A health_check block. Health Check documented below. * `health_check` - (Optional) A health_check block. Health Check documented below.
* `cross_zone_load_balancing` - (Optional) Enable cross-zone load balancing. * `cross_zone_load_balancing` - (Optional) Enable cross-zone load balancing.
* `idle_timeout` - (Optional) The time in seconds that the connection is allowed to be idle. Default: 300.
* `connection_draining` - (Optional) Boolean to enable connection draining.
* `connection_draining_timeout` - (Optional) The time in seconds to allow for connections to drain.
Exactly one of `availability_zones` or `subnets` must be specified: this Exactly one of `availability_zones` or `subnets` must be specified: this
determines if the ELB exists in a VPC or in EC2-classic. determines if the ELB exists in a VPC or in EC2-classic.