Skip to content

Commit 4e8c9c4

Browse files
authored
feat(apprunner): add HealthCheckConfiguration property in Service (#27029)
This PR adds HealthCheckConfiguration property in Service construct. Closes #26972. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent f47d09c commit 4e8c9c4

13 files changed

+923
-1
lines changed

packages/@aws-cdk/aws-apprunner-alpha/README.md

+22
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,25 @@ const service = new apprunner.Service(stack, 'Service', {
215215

216216
service.addSecret('LATER_SECRET', apprunner.Secret.fromSecretsManager(secret, 'field'));
217217
```
218+
219+
## HealthCheck
220+
221+
To configure the health check for the service, use the `healthCheck` attribute.
222+
223+
You can specify it by static methods `HealthCheck.http` or `HealthCheck.tcp`.
224+
225+
```ts
226+
new apprunner.Service(this, 'Service', {
227+
source: apprunner.Source.fromEcrPublic({
228+
imageConfiguration: { port: 8000 },
229+
imageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest',
230+
}),
231+
healthCheck: apprunner.HealthCheck.http({
232+
healthyThreshold: 5,
233+
interval: Duration.seconds(10),
234+
path: '/',
235+
timeout: Duration.seconds(10),
236+
unhealthyThreshold: 10,
237+
}),
238+
});
239+
```

packages/@aws-cdk/aws-apprunner-alpha/lib/service.ts

+151
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,15 @@ export interface ServiceProps {
706706
* @default - no VPC connector, uses the DEFAULT egress type instead
707707
*/
708708
readonly vpcConnector?: IVpcConnector;
709+
710+
/**
711+
* Settings for the health check that AWS App Runner performs to monitor the health of a service.
712+
*
713+
* You can specify it by static methods `HealthCheck.http` or `HealthCheck.tcp`.
714+
*
715+
* @default - no health check configuration
716+
*/
717+
readonly healthCheck?: HealthCheck;
709718
}
710719

711720
/**
@@ -848,6 +857,145 @@ export class GitHubConnection {
848857
}
849858
}
850859

860+
/**
861+
* The health check protocol type
862+
*/
863+
export enum HealthCheckProtocolType {
864+
/**
865+
* HTTP protocol
866+
*/
867+
HTTP = 'HTTP',
868+
869+
/**
870+
* TCP protocol
871+
*/
872+
TCP = 'TCP',
873+
}
874+
875+
/**
876+
* Describes the settings for the health check that AWS App Runner performs to monitor the health of a service.
877+
*/
878+
interface HealthCheckCommonOptions {
879+
/**
880+
* The number of consecutive checks that must succeed before App Runner decides that the service is healthy.
881+
*
882+
* @default 1
883+
*/
884+
readonly healthyThreshold?: number;
885+
886+
/**
887+
* The time interval, in seconds, between health checks.
888+
*
889+
* @default Duration.seconds(5)
890+
*/
891+
readonly interval?: cdk.Duration;
892+
893+
/**
894+
* The time, in seconds, to wait for a health check response before deciding it failed.
895+
*
896+
* @default Duration.seconds(2)
897+
*/
898+
readonly timeout?: cdk.Duration;
899+
900+
/**
901+
* The number of consecutive checks that must fail before App Runner decides that the service is unhealthy.
902+
*
903+
* @default 5
904+
*/
905+
readonly unhealthyThreshold?: number;
906+
}
907+
908+
/**
909+
* Properties used to define HTTP Based healthchecks.
910+
*/
911+
export interface HttpHealthCheckOptions extends HealthCheckCommonOptions {
912+
/**
913+
* The URL that health check requests are sent to.
914+
*
915+
* @default /
916+
*/
917+
readonly path?: string;
918+
}
919+
920+
/**
921+
* Properties used to define TCP Based healthchecks.
922+
*/
923+
export interface TcpHealthCheckOptions extends HealthCheckCommonOptions { }
924+
925+
/**
926+
* Contains static factory methods for creating health checks for different protocols
927+
*/
928+
export class HealthCheck {
929+
/**
930+
* Construct a HTTP health check
931+
*/
932+
public static http(options: HttpHealthCheckOptions = {}): HealthCheck {
933+
return new HealthCheck(
934+
HealthCheckProtocolType.HTTP,
935+
options.healthyThreshold,
936+
options.interval,
937+
options.timeout,
938+
options.unhealthyThreshold,
939+
options.path,
940+
);
941+
}
942+
943+
/**
944+
* Construct a TCP health check
945+
*/
946+
public static tcp(options: TcpHealthCheckOptions = {}): HealthCheck {
947+
return new HealthCheck(
948+
HealthCheckProtocolType.TCP,
949+
options.healthyThreshold,
950+
options.interval,
951+
options.timeout,
952+
options.unhealthyThreshold,
953+
);
954+
}
955+
956+
private constructor(
957+
public readonly healthCheckProtocolType: HealthCheckProtocolType,
958+
public readonly healthyThreshold: number = 1,
959+
public readonly interval: cdk.Duration = cdk.Duration.seconds(5),
960+
public readonly timeout: cdk.Duration = cdk.Duration.seconds(2),
961+
public readonly unhealthyThreshold: number = 5,
962+
public readonly path?: string,
963+
) {
964+
if (this.healthCheckProtocolType === HealthCheckProtocolType.HTTP) {
965+
if (this.path !== undefined && this.path.length === 0) {
966+
throw new Error('path length must be greater than 0');
967+
}
968+
if (this.path === undefined) {
969+
this.path = '/';
970+
}
971+
}
972+
973+
if (this.healthyThreshold < 1 || this.healthyThreshold > 20) {
974+
throw new Error(`healthyThreshold must be between 1 and 20, got ${this.healthyThreshold}`);
975+
}
976+
if (this.unhealthyThreshold < 1 || this.unhealthyThreshold > 20) {
977+
throw new Error(`unhealthyThreshold must be between 1 and 20, got ${this.unhealthyThreshold}`);
978+
}
979+
if (this.interval.toSeconds() < 1 || this.interval.toSeconds() > 20) {
980+
throw new Error(`interval must be between 1 and 20 seconds, got ${this.interval.toSeconds()}`);
981+
}
982+
if (this.timeout.toSeconds() < 1 || this.timeout.toSeconds() > 20) {
983+
throw new Error(`timeout must be between 1 and 20 seconds, got ${this.timeout.toSeconds()}`);
984+
}
985+
}
986+
987+
public bind(): CfnService.HealthCheckConfigurationProperty {
988+
return {
989+
healthyThreshold: this.healthyThreshold,
990+
interval: this.interval?.toSeconds(),
991+
path: this.path,
992+
protocol: this.healthCheckProtocolType,
993+
timeout: this.timeout?.toSeconds(),
994+
unhealthyThreshold: this.unhealthyThreshold,
995+
};
996+
}
997+
}
998+
851999
/**
8521000
* Attributes for the App Runner Service
8531001
*/
@@ -1097,6 +1245,9 @@ export class Service extends cdk.Resource implements iam.IGrantable {
10971245
vpcConnectorArn: this.props.vpcConnector?.vpcConnectorArn,
10981246
},
10991247
},
1248+
healthCheckConfiguration: this.props.healthCheck ?
1249+
this.props.healthCheck.bind() :
1250+
undefined,
11001251
});
11011252

11021253
// grant required privileges for the role

packages/@aws-cdk/aws-apprunner-alpha/rosetta/default.ts-fixture

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Fixture with packages imported, but nothing else
2-
import { Stack, SecretValue } from 'aws-cdk-lib';
2+
import { Duration, Stack, SecretValue } from 'aws-cdk-lib';
33
import { Construct } from 'constructs';
44
import * as apprunner from '@aws-cdk/aws-apprunner-alpha';
55
import * as path from 'path';

packages/@aws-cdk/aws-apprunner-alpha/test/integ.service-health-check-configuration.js.snapshot/cdk.out

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-apprunner-alpha/test/integ.service-health-check-configuration.js.snapshot/cdkintegdashboardandwidgetwithstartandendDefaultTestDeployAssert4D8483F4.assets.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-apprunner-alpha/test/integ.service-health-check-configuration.js.snapshot/cdkintegdashboardandwidgetwithstartandendDefaultTestDeployAssert4D8483F4.template.json

+36
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-apprunner-alpha/test/integ.service-health-check-configuration.js.snapshot/integ-apprunner.assets.json

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
{
2+
"Resources": {
3+
"ServiceInstanceRoleDFA90CEC": {
4+
"Type": "AWS::IAM::Role",
5+
"Properties": {
6+
"AssumeRolePolicyDocument": {
7+
"Statement": [
8+
{
9+
"Action": "sts:AssumeRole",
10+
"Effect": "Allow",
11+
"Principal": {
12+
"Service": "tasks.apprunner.amazonaws.com"
13+
}
14+
}
15+
],
16+
"Version": "2012-10-17"
17+
}
18+
}
19+
},
20+
"ServiceDBC79909": {
21+
"Type": "AWS::AppRunner::Service",
22+
"Properties": {
23+
"HealthCheckConfiguration": {
24+
"HealthyThreshold": 5,
25+
"Interval": 10,
26+
"Path": "/",
27+
"Protocol": "HTTP",
28+
"Timeout": 10,
29+
"UnhealthyThreshold": 10
30+
},
31+
"InstanceConfiguration": {
32+
"InstanceRoleArn": {
33+
"Fn::GetAtt": [
34+
"ServiceInstanceRoleDFA90CEC",
35+
"Arn"
36+
]
37+
}
38+
},
39+
"NetworkConfiguration": {
40+
"EgressConfiguration": {
41+
"EgressType": "DEFAULT"
42+
}
43+
},
44+
"SourceConfiguration": {
45+
"AuthenticationConfiguration": {},
46+
"ImageRepository": {
47+
"ImageConfiguration": {
48+
"Port": "8000"
49+
},
50+
"ImageIdentifier": "public.ecr.aws/aws-containers/hello-app-runner:latest",
51+
"ImageRepositoryType": "ECR_PUBLIC"
52+
}
53+
}
54+
}
55+
}
56+
},
57+
"Parameters": {
58+
"BootstrapVersion": {
59+
"Type": "AWS::SSM::Parameter::Value<String>",
60+
"Default": "/cdk-bootstrap/hnb659fds/version",
61+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
62+
}
63+
},
64+
"Rules": {
65+
"CheckBootstrapVersion": {
66+
"Assertions": [
67+
{
68+
"Assert": {
69+
"Fn::Not": [
70+
{
71+
"Fn::Contains": [
72+
[
73+
"1",
74+
"2",
75+
"3",
76+
"4",
77+
"5"
78+
],
79+
{
80+
"Ref": "BootstrapVersion"
81+
}
82+
]
83+
}
84+
]
85+
},
86+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
87+
}
88+
]
89+
}
90+
}
91+
}

packages/@aws-cdk/aws-apprunner-alpha/test/integ.service-health-check-configuration.js.snapshot/integ.json

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)