-
Notifications
You must be signed in to change notification settings - Fork 0
/
base.ts
114 lines (101 loc) · 4.38 KB
/
base.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
/* tslint:disable:no-submodule-imports quotemark no-unused-expression */
import {
BlockDeviceVolume,
CfnLaunchTemplate,
EbsDeviceVolumeType,
Instance,
InstanceSize,
MachineImage,
Peer,
Port,
SecurityGroup,
Subnet, UserData,
Vpc,
WindowsVersion,
InstanceType
} from "aws-cdk-lib/aws-ec2";
import {App, CfnOutput, Stack, StackProps} from "aws-cdk-lib";
import {ManagedPolicy, Role, ServicePrincipal} from "aws-cdk-lib/aws-iam";
export interface BaseConfig extends StackProps {
readonly instanceSize: InstanceSize;
readonly vpcId: string;
readonly subnetId: string;
readonly subnetAvailabilityZone: string;
readonly sshKeyName: string;
readonly volumeSizeGiB: number;
readonly niceDCVDisplayDriverUrl: string;
readonly niceDCVServerUrl: string;
readonly openPorts: number[];
readonly allowInboundCidr: string;
readonly user: String;
}
export abstract class BaseEc2Stack extends Stack {
protected props: BaseConfig;
constructor(scope: App, id: string, props: BaseConfig) {
super(scope, id, props);
this.props = props;
const { vpcId, subnetId, subnetAvailabilityZone, sshKeyName, volumeSizeGiB, openPorts, allowInboundCidr, user } = props;
const vpc = Vpc.fromLookup(this, "Vpc", { vpcId });
const securityGroup = new SecurityGroup(this, `SecurityGroup-${user}`, {
vpc,
description: `Allow RDP, and NICE DCV access for ${user}`,
securityGroupName: `InboundAccessFromRdpDcvFor${user}`
});
for (const port of openPorts) {
securityGroup.connections.allowFrom(Peer.ipv4(allowInboundCidr), Port.tcp(port));
}
const role = new Role(this, `${id}S3Read-${user}`, {
roleName: `${id}.GraphicsDriverS3Access-${user}`,
assumedBy: new ServicePrincipal('ec2.amazonaws.com'),
managedPolicies: [
ManagedPolicy.fromAwsManagedPolicyName('AmazonS3ReadOnlyAccess')
],
});
const launchTemplate = new CfnLaunchTemplate(this, `TeamBuildingCloudGamingLaunchTemplate-${user}`, {
launchTemplateData: {
keyName: sshKeyName,
instanceType: this.getInstanceType().toString(),
networkInterfaces: [{
subnetId,
deviceIndex: 0,
description: "ENI",
groups: [securityGroup.securityGroupId]
}],
instanceMarketOptions: {
spotOptions: {
blockDurationMinutes: 120,
instanceInterruptionBehavior: "stop",
}
}
},
launchTemplateName: `TeamBuildingCloudGamingInstanceLaunchTemplate-${user}/${this.getInstanceType().toString()}`,
});
const ec2Instance = new Instance(this, `EC2Instance-${user}`, {
instanceType: this.getInstanceType(),
vpc,
securityGroup,
vpcSubnets: vpc.selectSubnets({ subnets: [Subnet.fromSubnetAttributes(this, 'publicSubnet', {subnetId, availabilityZone: subnetAvailabilityZone})] }),
keyName: sshKeyName,
userData: this.getUserdata(),
machineImage: MachineImage.latestWindows(WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE),
blockDevices: [
{
deviceName: "/dev/sda1",
volume: BlockDeviceVolume.ebs(volumeSizeGiB, {
volumeType: EbsDeviceVolumeType.GP3,
encrypted: true
}),
}
],
role,
instanceName: `TeamBuildingCloudGaming-${user}/${this.getInstanceType().toString()}`
});
new CfnOutput(this, `Public IP`, { value: ec2Instance.instancePublicIp });
new CfnOutput(this, `Credentials`, { value: `https://${this.region}.console.aws.amazon.com/ec2/v2/home?region=${this.region}#ConnectToInstance:instanceId=${ec2Instance.instanceId}` });
new CfnOutput(this, `InstanceId`, { value: ec2Instance.instanceId });
new CfnOutput(this, `KeyName`, { value: sshKeyName });
new CfnOutput(this, `LaunchTemplateId`, { value: launchTemplate.launchTemplateName! });
}
protected abstract getUserdata(): UserData;
protected abstract getInstanceType(): InstanceType;
}