-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathecs-service.ts
88 lines (79 loc) · 3.15 KB
/
ecs-service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env node
import { Certificate } from '@aws-cdk/aws-certificatemanager';
import { Alarm } from '@aws-cdk/aws-cloudwatch';
import { Vpc } from '@aws-cdk/aws-ec2';
import { Repository } from '@aws-cdk/aws-ecr';
import { Cluster, ContainerImage, PropagatedTagSource } from '@aws-cdk/aws-ecs';
import { ApplicationLoadBalancedFargateService } from '@aws-cdk/aws-ecs-patterns';
import { HttpCodeTarget } from '@aws-cdk/aws-elasticloadbalancingv2';
import { HostedZone } from '@aws-cdk/aws-route53';
import { StringParameter } from '@aws-cdk/aws-ssm';
import cdk = require('@aws-cdk/core');
interface TriviaBackendStackProps extends cdk.StackProps {
domainName: string;
domainZone: string;
}
class TriviaBackendStack extends cdk.Stack {
constructor(parent: cdk.App, name: string, props: TriviaBackendStackProps) {
super(parent, name, props);
// Network infrastructure
const vpc = new Vpc(this, 'VPC', { maxAzs: 2 });
const cluster = new Cluster(this, 'Cluster', {
clusterName: props.domainName.replace(/\./g, '-'),
vpc,
containerInsights: true
});
// Configuration parameters
const domainZone = HostedZone.fromLookup(this, 'Zone', { domainName: props.domainZone });
const imageRepo = Repository.fromRepositoryName(this, 'Repo', 'reinvent-trivia-backend');
const tag = (process.env.IMAGE_TAG) ? process.env.IMAGE_TAG : 'latest';
const image = ContainerImage.fromEcrRepository(imageRepo, tag)
// Lookup pre-existing TLS certificate
const certificateArn = StringParameter.fromStringParameterAttributes(this, 'CertArnParameter', {
parameterName: 'CertificateArn-' + props.domainName
}).stringValue;
const certificate = Certificate.fromCertificateArn(this, 'Cert', certificateArn);
// Fargate service + load balancer
const service = new ApplicationLoadBalancedFargateService(this, 'Service', {
cluster,
taskImageOptions: { image },
desiredCount: 3,
domainName: props.domainName,
domainZone,
certificate,
propagateTags: PropagatedTagSource.SERVICE,
});
// Alarms: monitor 500s and unhealthy hosts on target groups
new Alarm(this, 'TargetGroupUnhealthyHosts', {
alarmName: this.stackName + '-Unhealthy-Hosts',
metric: service.targetGroup.metricUnhealthyHostCount(),
threshold: 1,
evaluationPeriods: 2,
});
new Alarm(this, 'TargetGroup5xx', {
alarmName: this.stackName + '-Http-500',
metric: service.targetGroup.metricHttpCodeTarget(HttpCodeTarget.TARGET_5XX_COUNT),
threshold: 1,
evaluationPeriods: 1,
period: cdk.Duration.minutes(1)
});
}
}
const app = new cdk.App();
new TriviaBackendStack(app, 'TriviaBackendTest', {
domainName: 'api-test.reinvent-trivia.com',
domainZone: 'reinvent-trivia.com',
env: { account: process.env['CDK_DEFAULT_ACCOUNT'], region: 'us-east-1' },
tags: {
project: "reinvent-trivia"
}
});
new TriviaBackendStack(app, 'TriviaBackendProd', {
domainName: 'api.reinvent-trivia.com',
domainZone: 'reinvent-trivia.com',
env: { account: process.env['CDK_DEFAULT_ACCOUNT'], region: 'us-east-1' },
tags: {
project: "reinvent-trivia"
}
});
app.synth();