Skip to content

Commit d0b791c

Browse files
stevehouelmadeline-k
authored andcommitted
feat(gamelift): add Build L2 constructs for GameLift (aws#22313)
Following [aws-cdk-rfcs](aws/aws-cdk-rfcs#436) I have written the first `Build` L2 resource which create a GameLift Build element based on a S3 location. ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent e052605 commit d0b791c

File tree

20 files changed

+1419
-31
lines changed

20 files changed

+1419
-31
lines changed

Diff for: packages/@aws-cdk/aws-gamelift/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ junit.xml
2121
!**/*.integ.snapshot/**/asset.*/*.d.ts
2222

2323
!**/*.integ.snapshot/**/asset.*/**
24+
25+
#include game build js file
26+
!test/my-game-build/*.js

Diff for: packages/@aws-cdk/aws-gamelift/README.md

+75-23
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,83 @@
99
>
1010
> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib
1111
12+
![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)
13+
14+
> The APIs of higher level constructs in this module are experimental and under active development.
15+
> They are subject to non-backward compatible changes or removal in any future version. These are
16+
> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be
17+
> announced in the release notes. This means that while you may use them, you may need to update
18+
> your source code when upgrading to a newer version of this package.
19+
1220
---
1321

1422
<!--END STABILITY BANNER-->
1523

16-
This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
17-
18-
```ts nofixture
19-
import * as gamelift from '@aws-cdk/aws-gamelift';
24+
[Amazon GameLift](https://docs.aws.amazon.com/gamelift/latest/developerguide/gamelift-intro.html) is a service used
25+
to deploy, operate, and scale dedicated, low-cost servers in the cloud for session-based multiplayer games. Built
26+
on AWS global computing infrastructure, GameLift helps deliver high-performance, high-reliability game servers
27+
while dynamically scaling your resource usage to meet worldwide player demand.
28+
29+
GameLift is composed of three main components:
30+
31+
* GameLift FlexMatch which is a customizable matchmaking service for
32+
multiplayer games. With FlexMatch, you can
33+
build a custom set of rules that defines what a multiplayer match looks like
34+
for your game, and determines how to
35+
evaluate and select compatible players for each match. You can also customize
36+
key aspects of the matchmaking
37+
process to fit your game, including fine-tuning the matching algorithm.
38+
39+
* GameLift hosting for custom or realtime servers which helps you deploy,
40+
operate, and scale dedicated game servers. It regulates the resources needed to
41+
host games, finds available game servers to host new game sessions, and puts
42+
players into games.
43+
44+
* GameLift FleetIQ to optimize the use of low-cost Amazon Elastic Compute Cloud
45+
(Amazon EC2) Spot Instances for cloud-based game hosting. With GameLift
46+
FleetIQ, you can work directly with your hosting resources in Amazon EC2 and
47+
Amazon EC2 Auto Scaling while taking advantage of GameLift optimizations to
48+
deliver inexpensive, resilient game hosting for your players
49+
50+
This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. It allows you to define components for your matchmaking
51+
configuration or game server fleet management system.
52+
53+
## GameLift Hosting
54+
55+
### Defining a GameLift Fleet
56+
57+
GameLift helps you deploy, operate, and scale dedicated game servers for
58+
session-based multiplayer games. It helps you regulate the resources needed to
59+
host your games, finds available game servers to host new game sessions, and
60+
puts players into games.
61+
62+
### Uploading builds and scripts to GameLift
63+
64+
Before deploying your GameLift-enabled multiplayer game servers for hosting with the GameLift service, you need to upload
65+
your game server files. This section provides guidance on preparing and uploading custom game server build
66+
files or Realtime Servers server script files. When you upload files, you create a GameLift build or script resource, which
67+
you then deploy on fleets of hosting resources.
68+
69+
### Upload a custom server build to GameLift
70+
71+
Before uploading your configured game server to GameLift for hosting, package the game build files into a build directory.
72+
This directory must include all components required to run your game servers and host game sessions, including the following:
73+
74+
* Game server binaries – The binary files required to run the game server. A build can include binaries for multiple game
75+
servers built to run on the same platform. For a list of supported platforms, see [Download Amazon GameLift SDKs](https://docs.aws.amazon.com/gamelift/latest/developerguide/gamelift-supported.html).
76+
77+
* Dependencies – Any dependent files that your game server executables require to run. Examples include assets, configuration
78+
files, and dependent libraries.
79+
80+
* Install script – A script file to handle tasks that are required to fully install your game build on GameLift hosting
81+
servers. Place this file at the root of the build directory. GameLift runs the install script as part of fleet creation.
82+
83+
You can set up any application in your build, including your install script, to access your resources securely on other AWS
84+
services.
85+
86+
```ts
87+
declare const bucket: s3.Bucket;
88+
new gamelift.Build(this, 'Build', {
89+
content: gamelift.Content.fromBucket(bucket, "sample-asset-key")
90+
});
2091
```
21-
22-
<!--BEGIN CFNONLY DISCLAIMER-->
23-
24-
There are no official hand-written ([L2](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) constructs for this service yet. Here are some suggestions on how to proceed:
25-
26-
- Search [Construct Hub for GameLift construct libraries](https://constructs.dev/search?q=gamelift)
27-
- Use the automatically generated [L1](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_l1_using) constructs, in the same way you would use [the CloudFormation AWS::GameLift resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_GameLift.html) directly.
28-
29-
30-
<!--BEGIN CFNONLY DISCLAIMER-->
31-
32-
There are no hand-written ([L2](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) constructs for this service yet.
33-
However, you can still use the automatically generated [L1](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_l1_using) constructs, and use this service exactly as you would using CloudFormation directly.
34-
35-
For more information on the resources and properties available for this service, see the [CloudFormation documentation for AWS::GameLift](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_GameLift.html).
36-
37-
(Read the [CDK Contributing Guide](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and submit an RFC if you are interested in contributing to this construct library.)
38-
39-
<!--END CFNONLY DISCLAIMER-->

Diff for: packages/@aws-cdk/aws-gamelift/lib/build.ts

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import * as iam from '@aws-cdk/aws-iam';
2+
import * as s3 from '@aws-cdk/aws-s3';
3+
import * as s3_assets from '@aws-cdk/aws-s3-assets';
4+
import * as cdk from '@aws-cdk/core';
5+
import { Construct } from 'constructs';
6+
import { Content } from './content';
7+
import { CfnBuild } from './gamelift.generated';
8+
9+
/**
10+
* Represents a GameLift server build.
11+
*/
12+
export interface IBuild extends cdk.IResource, iam.IGrantable {
13+
14+
/**
15+
* The Identifier of the build.
16+
*
17+
* @attribute
18+
*/
19+
readonly buildId: string;
20+
}
21+
22+
/**
23+
* Base class for new and imported GameLift server build.
24+
*/
25+
export abstract class BuildBase extends cdk.Resource implements IBuild {
26+
/**
27+
* The Identifier of the build.
28+
*/
29+
public abstract readonly buildId: string;
30+
31+
public abstract readonly grantPrincipal: iam.IPrincipal;
32+
}
33+
34+
/**
35+
* The operating system that the game server binaries are built to run on.
36+
*/
37+
export enum OperatingSystem {
38+
AMAZON_LINUX = 'AMAZON_LINUX',
39+
AMAZON_LINUX_2 = 'AMAZON_LINUX_2',
40+
WINDOWS_2012 = 'WINDOWS_2012'
41+
}
42+
43+
44+
/**
45+
* Represents a Build content defined outside of this stack.
46+
*/
47+
export interface BuildAttributes {
48+
/**
49+
* The identifier of the build
50+
*/
51+
readonly buildId: string;
52+
/**
53+
* The IAM role assumed by GameLift to access server build in S3.
54+
* @default - undefined
55+
*/
56+
readonly role?: iam.IRole;
57+
}
58+
59+
/**
60+
* Properties for a new build
61+
*/
62+
export interface BuildProps {
63+
/**
64+
* Name of this build
65+
*
66+
* @default No name
67+
*/
68+
readonly buildName?: string;
69+
70+
/**
71+
* Version of this build
72+
*
73+
* @default No version
74+
*/
75+
readonly buildVersion?: string;
76+
77+
/**
78+
* The operating system that the game server binaries are built to run on.
79+
*
80+
* @default No version
81+
*/
82+
readonly operatingSystem?: OperatingSystem;
83+
84+
/**
85+
* The game build file storage
86+
*/
87+
readonly content: Content;
88+
89+
/**
90+
* The IAM role assumed by GameLift to access server build in S3.
91+
* If providing a custom role, it needs to trust the GameLift service principal (gamelift.amazonaws.com) and be granted sufficient permissions
92+
* to have Read access to a specific key content into a specific S3 bucket.
93+
* Below an example of required permission:
94+
* {
95+
* "Version": "2012-10-17",
96+
* "Statement": [{
97+
* "Effect": "Allow",
98+
* "Action": [
99+
* "s3:GetObject",
100+
* "s3:GetObjectVersion"
101+
* ],
102+
* "Resource": "arn:aws:s3:::bucket-name/object-name"
103+
* }]
104+
*}
105+
*
106+
* @see https://docs.aws.amazon.com/gamelift/latest/developerguide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-storage-loc
107+
*
108+
* @default - a role will be created with default permissions.
109+
*/
110+
readonly role?: iam.IRole;
111+
}
112+
113+
/**
114+
* A GameLift build, that is installed and runs on instances in an Amazon GameLift fleet. It consists of
115+
* a zip file with all of the components of the game server build.
116+
*
117+
* @see https://docs.aws.amazon.com/gamelift/latest/developerguide/gamelift-build-cli-uploading.html
118+
*
119+
* @resource AWS::GameLift::Build
120+
*/
121+
export class Build extends BuildBase {
122+
123+
/**
124+
* Create a new Build from s3 content
125+
*/
126+
static fromBucket(scope: Construct, id: string, bucket: s3.IBucket, key: string, objectVersion?: string) {
127+
return new Build(scope, id, {
128+
content: Content.fromBucket(bucket, key, objectVersion),
129+
});
130+
}
131+
132+
/**
133+
* Create a new Build from asset content
134+
*/
135+
static fromAsset(scope: Construct, id: string, path: string, options?: s3_assets.AssetOptions) {
136+
return new Build(scope, id, {
137+
content: Content.fromAsset(path, options),
138+
});
139+
}
140+
141+
/**
142+
* Import a build into CDK using its identifier
143+
*/
144+
static fromBuildId(scope: Construct, id: string, buildId: string): IBuild {
145+
return this.fromBuildAttributes(scope, id, { buildId });
146+
}
147+
148+
/**
149+
* Import an existing build from its attributes.
150+
*/
151+
static fromBuildAttributes(scope: Construct, id: string, attrs: BuildAttributes): IBuild {
152+
class Import extends BuildBase {
153+
public readonly buildId = attrs.buildId;
154+
public readonly grantPrincipal = attrs.role ?? new iam.UnknownPrincipal({ resource: this });
155+
}
156+
157+
return new Import(scope, id);
158+
}
159+
160+
/**
161+
* The Identifier of the build.
162+
*/
163+
public readonly buildId: string;
164+
165+
/**
166+
* The IAM role GameLift assumes to acccess server build content.
167+
*/
168+
public readonly role: iam.IRole;
169+
170+
/**
171+
* The principal this GameLift Build is using.
172+
*/
173+
public readonly grantPrincipal: iam.IPrincipal;
174+
175+
constructor(scope: Construct, id: string, props: BuildProps) {
176+
super(scope, id, {
177+
physicalName: props.buildName,
178+
});
179+
180+
if (props.buildName && !cdk.Token.isUnresolved(props.buildName)) {
181+
if (props.buildName.length > 1024) {
182+
throw new Error(`Build name can not be longer than 1024 characters but has ${props.buildName.length} characters.`);
183+
}
184+
}
185+
this.role = props.role ?? new iam.Role(this, 'ServiceRole', {
186+
assumedBy: new iam.ServicePrincipal('gamelift.amazonaws.com'),
187+
});
188+
this.grantPrincipal = this.role;
189+
const content = props.content.bind(this, this.role);
190+
191+
const resource = new CfnBuild(this, 'Resource', {
192+
name: props.buildName,
193+
version: props.buildVersion,
194+
operatingSystem: props.operatingSystem,
195+
storageLocation: {
196+
bucket: content.s3Location && content.s3Location.bucketName,
197+
key: content.s3Location && content.s3Location.objectKey,
198+
objectVersion: content.s3Location && content.s3Location.objectVersion,
199+
roleArn: this.role.roleArn,
200+
},
201+
});
202+
203+
this.buildId = resource.ref;
204+
}
205+
206+
207+
}

0 commit comments

Comments
 (0)