Skip to content

Commit 10db9ca

Browse files
authored
feat: add grace_period and deregistration_delay to http for lb web services. (#2576)
<!-- Provide summary of changes --> Implements two new fields in the manifest under `http`: `grace_period` and `deregistration_delay`. These allow customization of the corresponding fields in the target group health check and service parameters. Resolves #2190, resolves #2506 <!-- Issue number, if available. E.g. "Fixes #31", "Addresses #42, 77" --> By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
1 parent ab1f3fa commit 10db9ca

File tree

17 files changed

+100
-47
lines changed

17 files changed

+100
-47
lines changed

internal/pkg/aws/cloudformation/testdata/parse/env.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ Resources:
117117
Protocol: HTTP
118118
TargetGroupAttributes:
119119
- Key: deregistration_delay.timeout_seconds
120-
Value: 60 # Default is 300.
120+
Value: 60
121121
TargetType: ip
122122
VpcId: !Ref VPC
123123

internal/pkg/aws/cloudformation/testdata/parse/lb-web-svc.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Resources:
159159
Protocol: HTTP
160160
TargetGroupAttributes:
161161
- Key: deregistration_delay.timeout_seconds
162-
Value: 60 # Default is 300.
162+
Value: 60
163163
- Key: stickiness.enabled
164164
Value: !Ref Stickiness
165165
TargetType: ip

internal/pkg/deploy/cloudformation/stack/lb_web_svc.go

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -152,35 +152,41 @@ func (s *LoadBalancedWebService) Template() (string, error) {
152152
}
153153
}
154154

155+
var deregistrationDelay *int64 = aws.Int64(60)
156+
if s.manifest.RoutingRule.DeregistrationDelay != nil {
157+
deregistrationDelay = aws.Int64(int64(s.manifest.RoutingRule.DeregistrationDelay.Seconds()))
158+
}
159+
155160
var allowedSourceIPs []string
156161
if s.manifest.AllowedSourceIps != nil {
157162
allowedSourceIPs = *s.manifest.AllowedSourceIps
158163
}
159164
content, err := s.parser.ParseLoadBalancedWebService(template.WorkloadOpts{
160-
Variables: s.manifest.Variables,
161-
Secrets: s.manifest.Secrets,
162-
Aliases: aliases,
163-
NestedStack: outputs,
164-
Sidecars: sidecars,
165-
LogConfig: convertLogging(s.manifest.Logging),
166-
DockerLabels: s.manifest.ImageConfig.DockerLabels,
167-
Autoscaling: autoscaling,
168-
CapacityProviders: capacityProviders,
169-
DesiredCountOnSpot: desiredCountOnSpot,
170-
ExecuteCommand: convertExecuteCommand(&s.manifest.ExecuteCommand),
171-
WorkloadType: manifest.LoadBalancedWebServiceType,
172-
HealthCheck: s.manifest.ImageConfig.HealthCheckOpts(),
173-
HTTPHealthCheck: convertHTTPHealthCheck(&s.manifest.HealthCheck),
174-
AllowedSourceIps: allowedSourceIPs,
175-
RulePriorityLambda: rulePriorityLambda.String(),
176-
DesiredCountLambda: desiredCountLambda.String(),
177-
EnvControllerLambda: envControllerLambda.String(),
178-
Storage: storage,
179-
Network: convertNetworkConfig(s.manifest.Network),
180-
EntryPoint: entrypoint,
181-
Command: command,
182-
DependsOn: dependencies,
183-
CredentialsParameter: aws.StringValue(s.manifest.ImageConfig.Credentials),
165+
Variables: s.manifest.Variables,
166+
Secrets: s.manifest.Secrets,
167+
Aliases: aliases,
168+
NestedStack: outputs,
169+
Sidecars: sidecars,
170+
LogConfig: convertLogging(s.manifest.Logging),
171+
DockerLabels: s.manifest.ImageConfig.DockerLabels,
172+
Autoscaling: autoscaling,
173+
CapacityProviders: capacityProviders,
174+
DesiredCountOnSpot: desiredCountOnSpot,
175+
ExecuteCommand: convertExecuteCommand(&s.manifest.ExecuteCommand),
176+
WorkloadType: manifest.LoadBalancedWebServiceType,
177+
HealthCheck: s.manifest.ImageConfig.HealthCheckOpts(),
178+
HTTPHealthCheck: convertHTTPHealthCheck(&s.manifest.HealthCheck),
179+
DeregistrationDelay: deregistrationDelay,
180+
AllowedSourceIps: allowedSourceIPs,
181+
RulePriorityLambda: rulePriorityLambda.String(),
182+
DesiredCountLambda: desiredCountLambda.String(),
183+
EnvControllerLambda: envControllerLambda.String(),
184+
Storage: storage,
185+
Network: convertNetworkConfig(s.manifest.Network),
186+
EntryPoint: entrypoint,
187+
Command: command,
188+
DependsOn: dependencies,
189+
CredentialsParameter: aws.StringValue(s.manifest.ImageConfig.Credentials),
184190
ServiceDiscoveryEndpoint: s.rc.ServiceDiscoveryEndpoint,
185191
})
186192
if err != nil {

internal/pkg/deploy/cloudformation/stack/lb_web_svc_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ Outputs:
196196
WorkloadType: manifest.LoadBalancedWebServiceType,
197197
HTTPHealthCheck: template.HTTPHealthCheckOpts{
198198
HealthCheckPath: "/",
199+
GracePeriod: aws.Int64(60),
199200
},
201+
DeregistrationDelay: aws.Int64(60),
200202
HealthCheck: &overridenContainerHealthCheck,
201203
RulePriorityLambda: "lambda",
202204
DesiredCountLambda: "something",
@@ -232,7 +234,9 @@ Outputs:
232234
WorkloadType: manifest.LoadBalancedWebServiceType,
233235
HTTPHealthCheck: template.HTTPHealthCheckOpts{
234236
HealthCheckPath: "/",
237+
GracePeriod: aws.Int64(60),
235238
},
239+
DeregistrationDelay: aws.Int64(60),
236240
HealthCheck: &overridenContainerHealthCheck,
237241
RulePriorityLambda: "lambda",
238242
DesiredCountLambda: "something",

internal/pkg/deploy/cloudformation/stack/testdata/workloads/svc-manifest.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,16 @@ environments:
4444
staging:
4545
count:
4646
spot: 5
47+
http:
48+
healthcheck:
49+
path: /
50+
grace_period: 30s
51+
deregistration_delay: 30s
4752
prod:
4853
count:
4954
range:
5055
min: 3
5156
max: 12
5257
spot_from: 6
53-
foo:
54-
cpu: 512
55-
memory: 1024
58+
59+

internal/pkg/deploy/cloudformation/stack/testdata/workloads/svc-prod.stack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ Resources:
379379
Protocol: HTTP
380380
TargetGroupAttributes:
381381
- Key: deregistration_delay.timeout_seconds
382-
Value: 60 # Default is 300.
382+
Value: 60
383383
- Key: stickiness.enabled
384384
Value: !Ref Stickiness
385385
TargetType: ip

internal/pkg/deploy/cloudformation/stack/testdata/workloads/svc-staging.stack.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ Resources:
298298
- Fn::ImportValue: !Sub '${AppName}-${EnvName}-EnvironmentSecurityGroup'
299299

300300
# This may need to be adjusted if the container takes a while to start up
301-
HealthCheckGracePeriodSeconds: 60
301+
HealthCheckGracePeriodSeconds: 30
302302
LoadBalancers:
303303
- ContainerName: !Ref TargetContainer
304304
ContainerPort: !Ref TargetPort
@@ -317,7 +317,7 @@ Resources:
317317
Protocol: HTTP
318318
TargetGroupAttributes:
319319
- Key: deregistration_delay.timeout_seconds
320-
Value: 60 # Default is 300.
320+
Value: 30
321321
- Key: stickiness.enabled
322322
Value: !Ref Stickiness
323323
TargetType: ip

internal/pkg/deploy/cloudformation/stack/testdata/workloads/svc-test.stack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ Resources:
371371
Protocol: HTTP
372372
TargetGroupAttributes:
373373
- Key: deregistration_delay.timeout_seconds
374-
Value: 60 # Default is 300.
374+
Value: 60
375375
- Key: stickiness.enabled
376376
Value: !Ref Stickiness
377377
TargetType: ip

internal/pkg/deploy/cloudformation/stack/transformers.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ func convertHTTPHealthCheck(hc *manifest.HealthCheckArgsOrString) template.HTTPH
269269
HealthCheckPath: manifest.DefaultHealthCheckPath,
270270
HealthyThreshold: hc.HealthCheckArgs.HealthyThreshold,
271271
UnhealthyThreshold: hc.HealthCheckArgs.UnhealthyThreshold,
272+
GracePeriod: aws.Int64(manifest.DefaultHealthCheckGracePeriod),
272273
}
273274
if hc.HealthCheckArgs.Path != nil {
274275
opts.HealthCheckPath = *hc.HealthCheckArgs.Path
@@ -284,6 +285,9 @@ func convertHTTPHealthCheck(hc *manifest.HealthCheckArgsOrString) template.HTTPH
284285
if hc.HealthCheckArgs.Timeout != nil {
285286
opts.Timeout = aws.Int64(int64(hc.HealthCheckArgs.Timeout.Seconds()))
286287
}
288+
if hc.HealthCheckArgs.GracePeriod != nil {
289+
opts.GracePeriod = aws.Int64(int64(hc.HealthCheckArgs.GracePeriod.Seconds()))
290+
}
287291
return opts
288292
}
289293

internal/pkg/deploy/cloudformation/stack/transformers_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
556556
inputUnhealthyThreshold *int64
557557
inputInterval *time.Duration
558558
inputTimeout *time.Duration
559+
inputGracePeriod *time.Duration
559560

560561
wantedOpts template.HTTPHealthCheckOpts
561562
}{
@@ -566,9 +567,11 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
566567
inputUnhealthyThreshold: nil,
567568
inputInterval: nil,
568569
inputTimeout: nil,
570+
inputGracePeriod: nil,
569571

570572
wantedOpts: template.HTTPHealthCheckOpts{
571573
HealthCheckPath: "/",
574+
GracePeriod: aws.Int64(60),
572575
},
573576
},
574577
"just HealthyThreshold": {
@@ -578,10 +581,12 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
578581
inputUnhealthyThreshold: nil,
579582
inputInterval: nil,
580583
inputTimeout: nil,
584+
inputGracePeriod: nil,
581585

582586
wantedOpts: template.HTTPHealthCheckOpts{
583587
HealthCheckPath: "/",
584588
HealthyThreshold: aws.Int64(5),
589+
GracePeriod: aws.Int64(60),
585590
},
586591
},
587592
"just UnhealthyThreshold": {
@@ -591,10 +596,12 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
591596
inputUnhealthyThreshold: aws.Int64(5),
592597
inputInterval: nil,
593598
inputTimeout: nil,
599+
inputGracePeriod: nil,
594600

595601
wantedOpts: template.HTTPHealthCheckOpts{
596602
HealthCheckPath: "/",
597603
UnhealthyThreshold: aws.Int64(5),
604+
GracePeriod: aws.Int64(60),
598605
},
599606
},
600607
"just Interval": {
@@ -604,10 +611,12 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
604611
inputUnhealthyThreshold: nil,
605612
inputInterval: &duration15Seconds,
606613
inputTimeout: nil,
614+
inputGracePeriod: nil,
607615

608616
wantedOpts: template.HTTPHealthCheckOpts{
609617
HealthCheckPath: "/",
610618
Interval: aws.Int64(15),
619+
GracePeriod: aws.Int64(60),
611620
},
612621
},
613622
"just Timeout": {
@@ -617,10 +626,12 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
617626
inputUnhealthyThreshold: nil,
618627
inputInterval: nil,
619628
inputTimeout: &duration15Seconds,
629+
inputGracePeriod: nil,
620630

621631
wantedOpts: template.HTTPHealthCheckOpts{
622632
HealthCheckPath: "/",
623633
Timeout: aws.Int64(15),
634+
GracePeriod: aws.Int64(60),
624635
},
625636
},
626637
"just SuccessCodes": {
@@ -630,10 +641,12 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
630641
inputUnhealthyThreshold: nil,
631642
inputInterval: nil,
632643
inputTimeout: nil,
644+
inputGracePeriod: nil,
633645

634646
wantedOpts: template.HTTPHealthCheckOpts{
635647
HealthCheckPath: "/",
636648
SuccessCodes: "200,301",
649+
GracePeriod: aws.Int64(60),
637650
},
638651
},
639652
"all values changed in manifest": {
@@ -643,6 +656,7 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
643656
inputUnhealthyThreshold: aws.Int64(3),
644657
inputInterval: &duration60Seconds,
645658
inputTimeout: &duration60Seconds,
659+
inputGracePeriod: &duration15Seconds,
646660

647661
wantedOpts: template.HTTPHealthCheckOpts{
648662
HealthCheckPath: "/road/to/nowhere",
@@ -651,6 +665,7 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
651665
UnhealthyThreshold: aws.Int64(3),
652666
Interval: aws.Int64(60),
653667
Timeout: aws.Int64(60),
668+
GracePeriod: aws.Int64(15),
654669
},
655670
},
656671
}
@@ -666,6 +681,7 @@ func Test_convertHTTPHealthCheck(t *testing.T) {
666681
UnhealthyThreshold: tc.inputUnhealthyThreshold,
667682
Timeout: tc.inputTimeout,
668683
Interval: tc.inputInterval,
684+
GracePeriod: tc.inputGracePeriod,
669685
},
670686
}
671687
// WHEN

internal/pkg/manifest/lb_web_svc.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ const (
1818

1919
// Default values for HTTPHealthCheck for a load balanced web service.
2020
const (
21-
DefaultHealthCheckPath = "/"
21+
DefaultHealthCheckPath = "/"
22+
DefaultHealthCheckDeregistrationDelay = 60
23+
DefaultHealthCheckGracePeriod = 60
2224
)
2325

2426
var (
@@ -55,10 +57,11 @@ type LoadBalancedWebServiceConfig struct {
5557

5658
// RoutingRule holds the path to route requests to the service.
5759
type RoutingRule struct {
58-
Path *string `yaml:"path"`
59-
HealthCheck HealthCheckArgsOrString `yaml:"healthcheck"`
60-
Stickiness *bool `yaml:"stickiness"`
61-
Alias *string `yaml:"alias"`
60+
Path *string `yaml:"path"`
61+
HealthCheck HealthCheckArgsOrString `yaml:"healthcheck"`
62+
Stickiness *bool `yaml:"stickiness"`
63+
Alias *string `yaml:"alias"`
64+
DeregistrationDelay *time.Duration `yaml:"deregistration_delay"`
6265
// TargetContainer is the container load balancer routes traffic to.
6366
TargetContainer *string `yaml:"target_container"`
6467
TargetContainerCamelCase *string `yaml:"targetContainer"` // "targetContainerCamelCase" for backwards compatibility

internal/pkg/manifest/svc.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,12 @@ type HTTPHealthCheckArgs struct {
236236
UnhealthyThreshold *int64 `yaml:"unhealthy_threshold"`
237237
Timeout *time.Duration `yaml:"timeout"`
238238
Interval *time.Duration `yaml:"interval"`
239+
GracePeriod *time.Duration `yaml:"grace_period"`
239240
}
240241

241242
func (h *HTTPHealthCheckArgs) isEmpty() bool {
242-
return h.Path == nil && h.HealthyThreshold == nil && h.UnhealthyThreshold == nil && h.Interval == nil && h.Timeout == nil
243+
return h.Path == nil && h.HealthyThreshold == nil && h.UnhealthyThreshold == nil &&
244+
h.Interval == nil && h.Timeout == nil && h.GracePeriod == nil
243245
}
244246

245247
// HealthCheckArgsOrString is a custom type which supports unmarshaling yaml which

internal/pkg/template/workload.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,14 @@ type LogConfigOpts struct {
161161

162162
// HTTPHealthCheckOpts holds configuration that's needed for HTTP Health Check.
163163
type HTTPHealthCheckOpts struct {
164-
HealthCheckPath string
165-
SuccessCodes string
166-
HealthyThreshold *int64
167-
UnhealthyThreshold *int64
168-
Interval *int64
169-
Timeout *int64
164+
HealthCheckPath string
165+
SuccessCodes string
166+
HealthyThreshold *int64
167+
UnhealthyThreshold *int64
168+
Interval *int64
169+
Timeout *int64
170+
DeregistrationDelay *int64
171+
GracePeriod *int64
170172
}
171173

172174
// AdvancedCount holds configuration for autoscaling and capacity provider
@@ -257,6 +259,7 @@ type WorkloadOpts struct {
257259
WorkloadType string
258260
HealthCheck *ecs.HealthCheck
259261
HTTPHealthCheck HTTPHealthCheckOpts
262+
DeregistrationDelay *int64
260263
AllowedSourceIps []string
261264
RulePriorityLambda string
262265
DesiredCountLambda string

site/content/docs/include/http-config.en.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ http:
2222
unhealthy_threshold: 2
2323
interval: 15s
2424
timeout: 10s
25+
grace_period: 60s
2526
```
2627
2728
<span class="parent-field">http.healthcheck.</span><a id="http-healthcheck-path" href="#http-healthcheck-path" class="field">`path`</a> <span class="type">String</span>
@@ -42,6 +43,12 @@ The approximate amount of time, in seconds, between health checks of an individu
4243
<span class="parent-field">http.healthcheck.</span><a id="http-healthcheck-timeout" href="#http-healthcheck-timeout" class="field">`timeout`</a> <span class="type">Duration</span>
4344
The amount of time, in seconds, during which no response from a target means a failed health check. The default is 5s. Range 5s-300s.
4445

46+
<span class="parent-field">http.healthcheck.</span><a id="http-healthcheck-grace-period" href="#http-healthcheck-grace-period" class="field">`grace_period`</a> <span class="type">Duration</span>
47+
The amount of time to ignore failing target group healthchecks on container start. The default is 60s. This can be useful to fix deployment issues for containers which take a while to become healthy and begin listening for incoming connections, or to speed up deployment of containers guaranteed to start quickly.
48+
49+
<span class="parent-field">http.</span><a id="http-deregistration-delay" href="#http-deregistration-delay" class="field">`deregistration_delay`</a> <span class="type">Duration</span>
50+
The amount of time to wait for targets to drain connections during deregistration. The default is 60s. Setting this to a larger value gives targets more time to gracefully drain connections, but increases the time required for new deployments. Range 0s-3600s.
51+
4552
<span class="parent-field">http.</span><a id="http-target-container" href="#http-target-container" class="field">`target_container`</a> <span class="type">String</span>
4653
A sidecar container that takes the place of a service container.
4754

site/content/docs/manifest/lb-web-service.en.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ List of all available properties for a `'Load Balanced Web Service'` manifest. T
1717
unhealthy_threshold: 2
1818
interval: 15s
1919
timeout: 10s
20+
deregistration_delay: 30s
21+
grace_period: 45s
2022
stickiness: false
2123
allowed_source_ips: ["10.24.34.0/23"]
2224
alias: example.com

site/content/docs/manifest/lb-web-service.ja.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ http:
1616
unhealthy_threshold: 2
1717
interval: 15s
1818
timeout: 10s
19+
deregistration_delay: 30s
20+
grace_period: 45s
1921
stickiness: false
2022
allowed_source_ips: ["10.24.34.0/23"]
2123

0 commit comments

Comments
 (0)