-
Notifications
You must be signed in to change notification settings - Fork 30
/
mobile-apps-rendering.ts
121 lines (108 loc) · 3.67 KB
/
mobile-apps-rendering.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { GuEc2App } from '@guardian/cdk';
import { AccessScope } from '@guardian/cdk/lib/constants';
import type { GuStackProps } from '@guardian/cdk/lib/constructs/core';
import { GuStack } from '@guardian/cdk/lib/constructs/core';
import { GuAllowPolicy } from '@guardian/cdk/lib/constructs/iam';
import type { GuAsgCapacity } from '@guardian/cdk/lib/types';
import type { App, CfnElement } from 'aws-cdk-lib';
import { Duration } from 'aws-cdk-lib';
import type { InstanceSize } from 'aws-cdk-lib/aws-ec2';
import { InstanceClass, InstanceType, Peer } from 'aws-cdk-lib/aws-ec2';
import {
HostedZone,
RecordSet,
RecordTarget,
RecordType,
} from 'aws-cdk-lib/aws-route53';
import * as ssm from 'aws-cdk-lib/aws-ssm';
interface AppsStackProps extends GuStackProps {
recordPrefix: string;
asgCapacity: GuAsgCapacity;
appsRenderingDomain: string;
hostedZoneId: string;
targetCpuUtilisation: number;
instanceSize: InstanceSize;
}
export class MobileAppsRendering extends GuStack {
constructor(scope: App, id: string, props: AppsStackProps) {
super(scope, id, props);
const appName = 'mobile-apps-rendering';
const domainName = `${props.recordPrefix}.${props.appsRenderingDomain}`;
const hostedZone = HostedZone.fromHostedZoneAttributes(
this,
'HostedZone',
{
zoneName: props.appsRenderingDomain,
hostedZoneId: props.hostedZoneId,
},
);
const scalingTargetCpuUtilisation = props.targetCpuUtilisation;
const artifactBucketName = ssm.StringParameter.valueForStringParameter(
this,
'/account/services/artifact.bucket',
);
const appsRenderingApp = new GuEc2App(this, {
applicationPort: 3040,
app: 'mobile-apps-rendering',
access: {
scope: AccessScope.INTERNAL,
cidrRanges: [Peer.ipv4('10.0.0.0/8')],
},
instanceType: InstanceType.of(
InstanceClass.T4G,
props.instanceSize,
),
certificateProps: {
domainName,
hostedZoneId: props.hostedZoneId,
},
monitoringConfiguration: {
noMonitoring: true,
},
roleConfiguration: {
additionalPolicies: [
new GuAllowPolicy(this, 'GetParametersByPath', {
resources: ['*'],
actions: ['ssm:GetParametersByPath'],
}),
],
},
userData: `#!/bin/bash -ev
groupadd mapi
useradd -r -m -s /usr/bin/nologin -g mapi ${appName}
export App=${appName}
export Stack=${this.stack}
export Stage=${this.stage}
export NODE_ENV=production
aws s3 cp s3://${artifactBucketName}/${this.stack}/${this.stage}/${appName}/${appName}.zip /tmp
mkdir -p /opt/${appName}
unzip /tmp/${appName}.zip -d /opt/${appName}
chown -R ${appName}:mapi /opt/${appName}
mkdir -p /usr/share/${appName}/logs
chown -R ${appName}:mapi /usr/share/${appName}
ln -s /usr/share/${appName}/logs /var/log/${appName}
chown -R ${appName}:mapi /var/log/${appName}
export PM2_HOME="/usr/share/${appName}"
export ASSETS_MANIFEST="/opt/${appName}/manifest.json"
/usr/local/node/pm2 start --name ${appName} --uid ${appName} --gid mapi /opt/${appName}/server.js
/opt/aws-kinesis-agent/configure-aws-kinesis-agent ${this.region} mobile-log-aggregation-${this.stage} '/var/log/${appName}/*'
/usr/local/node/pm2 logrotate -u ${appName}`,
scaling: props.asgCapacity,
});
const asg = appsRenderingApp.autoScalingGroup;
asg.scaleOnCpuUtilization('CpuScalingPolicy', {
targetUtilizationPercent: scalingTargetCpuUtilisation,
});
const recordSet = new RecordSet(this, 'DnsRecord', {
recordType: RecordType.CNAME,
target: RecordTarget.fromValues(
appsRenderingApp.loadBalancer.loadBalancerDnsName,
),
zone: hostedZone,
recordName: props.recordPrefix,
ttl: Duration.hours(1),
});
const defaultChild = recordSet.node.defaultChild as CfnElement;
defaultChild.overrideLogicalId('DnsRecord');
}
}