provider/aws: wait for ASG capacity on update

It's a bit confusing to have Terraform poll until instances come up on
ASG creation but not on update. This changes update to also poll if
min_size or desired_capacity are changed.

This changes the waiting behavior to wait for precisely the desired
number of instances instead of that number as a "minimum". I believe
this shouldn't have any undue side effects, and the behavior can still
be opted out of by setting `wait_for_capacity_timeout` to 0.
This commit is contained in:
Paul Hinze 2015-11-16 18:16:22 -06:00
parent 24ee56326d
commit 7f9360797c
3 changed files with 40 additions and 14 deletions

View File

@ -51,8 +51,9 @@ func resourceAwsAutoscalingGroup() *schema.Resource {
},
"min_elb_capacity": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Type: schema.TypeInt,
Optional: true,
Deprecated: "Please use 'wait_for_elb_capacity' instead.",
},
"min_size": &schema.Schema{
@ -136,6 +137,11 @@ func resourceAwsAutoscalingGroup() *schema.Resource {
},
},
"wait_for_elb_capacity": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},
"tag": autoscalingTagsSchema(),
},
}
@ -242,6 +248,7 @@ func resourceAwsAutoscalingGroupRead(d *schema.ResourceData, meta interface{}) e
func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).autoscalingconn
shouldWaitForCapacity := false
opts := autoscaling.UpdateAutoScalingGroupInput{
AutoScalingGroupName: aws.String(d.Id()),
@ -253,6 +260,7 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
if d.HasChange("desired_capacity") {
opts.DesiredCapacity = aws.Int64(int64(d.Get("desired_capacity").(int)))
shouldWaitForCapacity = true
}
if d.HasChange("launch_configuration") {
@ -261,6 +269,7 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
if d.HasChange("min_size") {
opts.MinSize = aws.Int64(int64(d.Get("min_size").(int)))
shouldWaitForCapacity = true
}
if d.HasChange("max_size") {
@ -353,6 +362,10 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
}
}
if shouldWaitForCapacity {
waitForASGCapacity(d, meta)
}
return resourceAwsAutoscalingGroupRead(d, meta)
}
@ -490,7 +503,7 @@ func resourceAwsAutoscalingGroupDrain(d *schema.ResourceData, meta interface{})
// ASG before continuing. Waits up to `waitForASGCapacityTimeout` for
// "desired_capacity", or "min_size" if desired capacity is not specified.
//
// If "min_elb_capacity" is specified, will also wait for that number of
// If "wait_for_elb_capacity" is specified, will also wait for that number of
// instances to show up InService in all attached ELBs. See "Waiting for
// Capacity" in docs for more discussion of the feature.
func waitForASGCapacity(d *schema.ResourceData, meta interface{}) error {
@ -498,7 +511,10 @@ func waitForASGCapacity(d *schema.ResourceData, meta interface{}) error {
if v := d.Get("desired_capacity").(int); v > 0 {
wantASG = v
}
wantELB := d.Get("min_elb_capacity").(int)
wantELB := d.Get("wait_for_elb_capacity").(int)
// Covers deprecated field support
wantELB += d.Get("min_elb_capacity").(int)
wait, err := time.ParseDuration(d.Get("wait_for_capacity_timeout").(string))
if err != nil {
@ -561,11 +577,13 @@ func waitForASGCapacity(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] %q Capacity: %d/%d ASG, %d/%d ELB",
d.Id(), haveASG, wantASG, haveELB, wantELB)
if haveASG >= wantASG && haveELB >= wantELB {
if haveASG == wantASG && haveELB == wantELB {
return nil
}
return fmt.Errorf("Still need to wait for more healthy instances. This could mean instances failed to launch. See Scaling History for more information.")
return fmt.Errorf(
"Still waiting for %q instances. Current/Desired: %d/%d ASG, %d/%d ELB",
d.Id(), haveASG, wantASG, haveELB, wantELB)
})
}

View File

@ -526,7 +526,7 @@ resource "aws_autoscaling_group" "bar" {
min_size = 2
health_check_grace_period = 300
health_check_type = "ELB"
min_elb_capacity = 2
wait_for_elb_capacity = 2
force_delete = true
launch_configuration = "${aws_launch_configuration.foobar.name}"

View File

@ -53,9 +53,6 @@ The following arguments are supported:
* `desired_capacity` - (Optional) The number of Amazon EC2 instances that
should be running in the group. (See also [Waiting for
Capacity](#waiting-for-capacity) below.)
* `min_elb_capacity` - (Optional) Setting this will cause Terraform to wait
for this number of healthy instances all attached load balancers.
(See also [Waiting for Capacity](#waiting-for-capacity) below.)
* `force_delete` - (Optional) Allows deleting the autoscaling group without waiting
for all instances in the pool to terminate. You can force an autoscaling group to delete
even if it's in the process of scaling a resource. Normally, Terraform
@ -71,6 +68,9 @@ The following arguments are supported:
wait for ASG instances to be healthy before timing out. (See also [Waiting
for Capacity](#waiting-for-capacity) below.) Setting this to "0" causes
Terraform to skip all Capacity Waiting behavior.
* `wait_for_elb_capacity` - (Optional) Setting this will cause Terraform to wait
for this number of healthy instances all attached load balancers.
(See also [Waiting for Capacity](#waiting-for-capacity) below.)
Tags support the following:
@ -79,6 +79,10 @@ Tags support the following:
* `propagate_at_launch` - (Required) Enables propagation of the tag to
Amazon EC2 instances launched via this ASG
The following fields are deprecated:
* `min_elb_capacity` - Please use `wait_for_elb_capacity` instead.
## Attributes Reference
The following attributes are exported:
@ -96,7 +100,7 @@ The following attributes are exported:
* `vpc_zone_identifier` - The VPC zone identifier
* `load_balancers` (Optional) The load balancer names associated with the
autoscaling group.
~> **NOTE:** When using `ELB` as the health_check_type, `health_check_grace_period` is required.
<a id="waiting-for-capacity"></a>
@ -115,6 +119,10 @@ The first is default behavior. Terraform waits after ASG creation for
`min_size` (or `desired_capacity`, if specified) healthy instances to show up
in the ASG before continuing.
If `min_size` or `desired_capacity` are changed in a subsequent update,
Terraform will also wait for the correct number of healthy instances before
continuing.
Terraform considers an instance "healthy" when the ASG reports `HealthStatus:
"Healthy"` and `LifecycleState: "InService"`. See the [AWS AutoScaling
Docs](https://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AutoScalingGroupLifecycle.html)
@ -130,9 +138,9 @@ Setting `wait_for_capacity_timeout` to `"0"` disables ASG Capacity waiting.
#### Waiting for ELB Capacity
The second mechanism is optional, and affects ASGs with attached Load
Balancers. If `min_elb_capacity` is set, Terraform will wait for that number of
Instances to be `"InService"` in all attached `load_balancers`. This can be
used to ensure that service is being provided before Terraform moves on.
Balancers. If `wait_for_elb_capacity` is set, Terraform will wait for that
number of Instances to be `"InService"` in all attached `load_balancers`. This
can be used to ensure that service is being provided before Terraform moves on.
As with ASG Capacity, Terraform will wait for up to `wait_for_capacity_timeout`
(for `"InService"` instances. If ASG creation takes more than a few minutes,