Merge pull request #3947 from hashicorp/phinze/asg-wait-on-update

provider/aws: wait for ASG capacity on update
This commit is contained in:
Paul Hinze 2016-01-06 15:55:43 -06:00
commit 319f7d77a0
3 changed files with 40 additions and 14 deletions

View File

@ -51,8 +51,9 @@ func resourceAwsAutoscalingGroup() *schema.Resource {
}, },
"min_elb_capacity": &schema.Schema{ "min_elb_capacity": &schema.Schema{
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Deprecated: "Please use 'wait_for_elb_capacity' instead.",
}, },
"min_size": &schema.Schema{ "min_size": &schema.Schema{
@ -141,6 +142,11 @@ func resourceAwsAutoscalingGroup() *schema.Resource {
}, },
}, },
"wait_for_elb_capacity": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},
"tag": autoscalingTagsSchema(), "tag": autoscalingTagsSchema(),
}, },
} }
@ -252,6 +258,7 @@ func resourceAwsAutoscalingGroupRead(d *schema.ResourceData, meta interface{}) e
func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) error { func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).autoscalingconn conn := meta.(*AWSClient).autoscalingconn
shouldWaitForCapacity := false
opts := autoscaling.UpdateAutoScalingGroupInput{ opts := autoscaling.UpdateAutoScalingGroupInput{
AutoScalingGroupName: aws.String(d.Id()), AutoScalingGroupName: aws.String(d.Id()),
@ -263,6 +270,7 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
if d.HasChange("desired_capacity") { if d.HasChange("desired_capacity") {
opts.DesiredCapacity = aws.Int64(int64(d.Get("desired_capacity").(int))) opts.DesiredCapacity = aws.Int64(int64(d.Get("desired_capacity").(int)))
shouldWaitForCapacity = true
} }
if d.HasChange("launch_configuration") { if d.HasChange("launch_configuration") {
@ -271,6 +279,7 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
if d.HasChange("min_size") { if d.HasChange("min_size") {
opts.MinSize = aws.Int64(int64(d.Get("min_size").(int))) opts.MinSize = aws.Int64(int64(d.Get("min_size").(int)))
shouldWaitForCapacity = true
} }
if d.HasChange("max_size") { if d.HasChange("max_size") {
@ -367,6 +376,10 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
} }
} }
if shouldWaitForCapacity {
waitForASGCapacity(d, meta)
}
return resourceAwsAutoscalingGroupRead(d, meta) return resourceAwsAutoscalingGroupRead(d, meta)
} }
@ -504,7 +517,7 @@ func resourceAwsAutoscalingGroupDrain(d *schema.ResourceData, meta interface{})
// ASG before continuing. Waits up to `waitForASGCapacityTimeout` for // ASG before continuing. Waits up to `waitForASGCapacityTimeout` for
// "desired_capacity", or "min_size" if desired capacity is not specified. // "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 // instances to show up InService in all attached ELBs. See "Waiting for
// Capacity" in docs for more discussion of the feature. // Capacity" in docs for more discussion of the feature.
func waitForASGCapacity(d *schema.ResourceData, meta interface{}) error { func waitForASGCapacity(d *schema.ResourceData, meta interface{}) error {
@ -512,7 +525,10 @@ func waitForASGCapacity(d *schema.ResourceData, meta interface{}) error {
if v := d.Get("desired_capacity").(int); v > 0 { if v := d.Get("desired_capacity").(int); v > 0 {
wantASG = v 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)) wait, err := time.ParseDuration(d.Get("wait_for_capacity_timeout").(string))
if err != nil { if err != nil {
@ -575,11 +591,13 @@ func waitForASGCapacity(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] %q Capacity: %d/%d ASG, %d/%d ELB", log.Printf("[DEBUG] %q Capacity: %d/%d ASG, %d/%d ELB",
d.Id(), haveASG, wantASG, haveELB, wantELB) d.Id(), haveASG, wantASG, haveELB, wantELB)
if haveASG >= wantASG && haveELB >= wantELB { if haveASG == wantASG && haveELB == wantELB {
return nil 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

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

View File

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