Skip to content
This repository has been archived by the owner on Dec 24, 2023. It is now read-only.

Add wait_for_steady_state #18

Merged
merged 2 commits into from
Feb 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions aws/resource_aws_ecs_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"log"
"regexp"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -115,6 +116,7 @@ func resourceAwsEcsService() *schema.Resource {
},
Set: resourceAwsEcsLoadBalancerHash,
},

"network_configuration": {
Type: schema.TypeList,
Optional: true,
Expand All @@ -136,6 +138,7 @@ func resourceAwsEcsService() *schema.Resource {
},
},
},

"placement_strategy": {
Type: schema.TypeSet,
Optional: true,
Expand Down Expand Up @@ -197,6 +200,12 @@ func resourceAwsEcsService() *schema.Resource {
},
},
},

"wait_for_steady_state": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
}
}
Expand Down Expand Up @@ -523,6 +532,22 @@ func resourceAwsEcsServiceUpdate(d *schema.ResourceData, meta interface{}) error
return err
}

if d.Get("wait_for_steady_state").(bool) {
log.Println("[INFO] Waiting for service to reach a steady state")

steadyStateConf := &resource.StateChangeConf{
Pending: []string{"false"},
Target: []string{"true"},
Refresh: resourceAwsEcsServiceIsSteadyStateFunc(d, meta),
Timeout: 10 * time.Minute,
MinTimeout: 1 * time.Second,
}

if _, err := steadyStateConf.WaitForState(); err != nil {
return err
}
}

return resourceAwsEcsServiceRead(d, meta)
}

Expand Down Expand Up @@ -668,3 +693,44 @@ func validateAwsEcsServiceHealthCheckGracePeriodSeconds(v interface{}, k string)
}
return
}

// Returns a StateRefreshFunc for a given service. That function will return "true" if the service is in a
// steady state, "false" if the service is running but not in a steady state, and an error otherwise.
func resourceAwsEcsServiceIsSteadyStateFunc(d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
conn := meta.(*AWSClient).ecsconn
in := &ecs.DescribeServicesInput{
Services: []*string{aws.String(d.Id())},
Cluster: aws.String(d.Get("cluster").(string)),
}

out, err := conn.DescribeServices(in)
if err != nil {
return nil, "", err
}

if len(out.Services) < 1 {
return nil, "", fmt.Errorf(
"Service %v disappeared while waiting for it to reach a steady state",
d.Id())
}

service := out.Services[0]

// A service is in a steady state if:
// 1. It is not INACTIVE or DRAINING
// 2. There is only one deployment, which will be PRIMARY
// 3. The count of running tasks matches the desired count
// ref: https://github.com/boto/botocore/blob/3ac0dd53/botocore/data/ecs/2014-11-13/waiters-2.json#L42-L72
if *service.Status == "INACTIVE" || *service.Status == "DRAINING" {
return nil, "", fmt.Errorf(
"Service %v can't reach steady state because its status is %v",
d.Id(), *service.Status)
}

isSteadyState := len(service.Deployments) == 1 &&
*service.RunningCount == *service.DesiredCount

return service, strconv.FormatBool(isSteadyState), nil
}
}
1 change: 1 addition & 0 deletions website/docs/r/ecs_service.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ into consideration during task placement. The maximum number of
* `placement_constraints` - (Optional) rules that are taken into consideration during task placement. Maximum number of
`placement_constraints` is `10`. Defined below.
* `network_configuration` - (Optional) The network configuration for the service. This parameter is required for task definitions that use the awsvpc network mode to receive their own Elastic Network Interface, and it is not supported for other network modes.
* `wait_for_steady_state` - (Optional) If `true`, Terraform will wait for the service to reach a steady state (like [`aws ecs wait services-stable`](https://docs.aws.amazon.com/cli/latest/reference/ecs/wait/services-stable.html)) before continuing. Default `false`.

-> **Note:** As a result of an AWS limitation, a single `load_balancer` can be attached to the ECS service at most. See [related docs](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html#load-balancing-concepts).

Expand Down