Skip to content

Commit

Permalink
feat(gamelift): add BuildFleet L2 Construct for GameLift (#22835)
Browse files Browse the repository at this point in the history
Following aws/aws-cdk-rfcs#436 I have written the Gamelift BuildFleet L2 resource which create a Fleet resource.

----

### 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*
  • Loading branch information
stevehouel authored Nov 9, 2022
1 parent f2e5447 commit 834fab4
Show file tree
Hide file tree
Showing 27 changed files with 2,891 additions and 24 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-gamelift/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_modules
*.generated.ts
dist
.jsii
.DS_Store

.LAST_BUILD
.nyc_output
Expand All @@ -23,5 +24,4 @@ junit.xml
!**/*.snapshot/**/asset.*/**

#include game build js file
!test/my-game-build/*.js
!test/my-game-script/*.js
261 changes: 253 additions & 8 deletions packages/@aws-cdk/aws-gamelift/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ configuration or game server fleet management system.

## GameLift Hosting

### Defining a GameLift Fleet

GameLift helps you deploy, operate, and scale dedicated game servers for
session-based multiplayer games. It helps you regulate the resources needed to
host your games, finds available game servers to host new game sessions, and
puts players into games.

### Uploading builds and scripts to GameLift

Before deploying your GameLift-enabled multiplayer game servers for hosting with the GameLift service, you need to upload
Expand Down Expand Up @@ -110,6 +103,258 @@ new gamelift.Script(this, 'Script', {
});
```

### Defining a GameLift Fleet

#### Creating a custom game server fleet

Your uploaded game servers are hosted on GameLift virtual computing resources,
called instances. You set up your hosting resources by creating a fleet of
instances and deploying them to run your game servers. You can design a fleet
to fit your game's needs.

```ts
new gamelift.BuildFleet(this, 'Game server fleet', {
fleetName: 'test-fleet',
content: gamelift.Build.fromAsset(this, 'Build', path.join(__dirname, 'CustomerGameServer')),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.C4, ec2.InstanceSize.LARGE),
runtimeConfiguration: {
serverProcesses: [{
launchPath: 'test-launch-path',
}],
},
});
```

### Managing game servers launch configuration

GameLift uses a fleet's runtime configuration to determine the type and number
of processes to run on each instance in the fleet. At a minimum, a runtime
configuration contains one server process configuration that represents one
game server executable. You can also define additional server process
configurations to run other types of processes related to your game. Each
server process configuration contains the following information:

* The file name and path of an executable in your game build.

* Optionally Parameters to pass to the process on launch.

* The number of processes to run concurrently.

A GameLift instance is limited to 50 processes running concurrently.

```ts
declare const build: gamelift.Build;
// Server processes can be delcared in a declarative way through the constructor
const fleet = new gamelift.BuildFleet(this, 'Game server fleet', {
fleetName: 'test-fleet',
content: build,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.C4, ec2.InstanceSize.LARGE),
runtimeConfiguration: {
serverProcesses: [{
launchPath: '/local/game/GameLiftExampleServer.x86_64',
parameters: '-logFile /local/game/logs/myserver1935.log -port 1935',
concurrentExecutions: 100,
}]
}
});
```

See [Managing how game servers are launched for hosting](https://docs.aws.amazon.com/gamelift/latest/developerguide/fleets-multiprocess.html)
in the *Amazon GameLift Developer Guide*.

### Defining an instance type

GameLift uses Amazon Elastic Compute Cloud (Amazon EC2) resources, called
instances, to deploy your game servers and host game sessions for your players.
When setting up a new fleet, you decide what type of instances your game needs
and how to run game server processes on them (using a runtime configuration). All instances in a fleet use the same type of resources and the same runtime
configuration. You can edit a fleet's runtime configuration and other fleet
properties, but the type of resources cannot be changed.

```ts
declare const build: gamelift.Build;
new gamelift.BuildFleet(this, 'Game server fleet', {
fleetName: 'test-fleet',
content: build,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.C5, ec2.InstanceSize.LARGE),
runtimeConfiguration: {
serverProcesses: [{
launchPath: '/local/game/GameLiftExampleServer.x86_64',
}]
}
});
```

### Using Spot instances

When setting up your hosting resources, you have the option of using Spot
Instances, On-Demand Instances, or a combination.

By default, fleet are using on demand capacity.

```ts
declare const build: gamelift.Build;
new gamelift.BuildFleet(this, 'Game server fleet', {
fleetName: 'test-fleet',
content: build,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.C4, ec2.InstanceSize.LARGE),
runtimeConfiguration: {
serverProcesses: [{
launchPath: '/local/game/GameLiftExampleServer.x86_64',
}]
},
useSpot: true
});
```

### Allowing Ingress traffic

The allowed IP address ranges and port settings that allow inbound traffic to
access game sessions on this fleet.

New game sessions are assigned an IP address/port number combination, which
must fall into the fleet's allowed ranges. Fleets with custom game builds must
have permissions explicitly set. For Realtime Servers fleets, GameLift
automatically opens two port ranges, one for TCP messaging and one for UDP.

```ts
declare const build: gamelift.Build;

const fleet = new gamelift.BuildFleet(this, 'Game server fleet', {
fleetName: 'test-fleet',
content: build,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.C4, ec2.InstanceSize.LARGE),
runtimeConfiguration: {
serverProcesses: [{
launchPath: '/local/game/GameLiftExampleServer.x86_64',
}]
},
ingressRules: [{
source: gamelift.Peer.anyIpv4(),
port: gamelift.Port.tcpRange(100, 200),
}]
});
// Allowing a specific CIDR for port 1111 on UDP Protocol
fleet.addIngressRule(gamelift.Peer.ipv4('1.2.3.4/32'), gamelift.Port.udp(1111));
```

### Managing locations

A single Amazon GameLift fleet has a home Region by default (the Region you
deploy it to), but it can deploy resources to any number of GameLift supported
Regions. Select Regions based on where your players are located and your
latency needs.

By default, home region is used as default location but we can add new locations if needed and define desired capacity

```ts
declare const build: gamelift.Build;

// Locations can be added directly through constructor
const fleet = new gamelift.BuildFleet(this, 'Game server fleet', {
fleetName: 'test-fleet',
content: build,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.C4, ec2.InstanceSize.LARGE),
runtimeConfiguration: {
serverProcesses: [{
launchPath: '/local/game/GameLiftExampleServer.x86_64',
}]
},
locations: [ {
region: 'eu-west-1',
capacity: {
desiredCapacity: 5,
minSize: 2,
maxSize: 10
}
}, {
region: 'us-east-1',
capacity: {
desiredCapacity: 5,
minSize: 2,
maxSize: 10
}
}]
});

// Or through dedicated methods
fleet.addLocation('ap-southeast-1', 5, 2, 10);
```

### Specifying an IAM role for a Fleet

Some GameLift features require you to extend limited access to your AWS
resources. This is done by creating an AWS IAM role. The GameLift Fleet class
automatically created an IAM role with all the minimum necessary permissions
for GameLift to access your ressources. If you wish, you may
specify your own IAM role.

```ts
declare const build: gamelift.Build;
const role = new iam.Role(this, 'Role', {
assumedBy: new iam.CompositePrincipal(new iam.ServicePrincipal('gamelift.amazonaws.com'))
});
role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchAgentServerPolicy'));

const fleet = new gamelift.BuildFleet(this, 'Game server fleet', {
fleetName: 'test-fleet',
content: build,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.C5, ec2.InstanceSize.LARGE),
runtimeConfiguration: {
serverProcesses: [{
launchPath: '/local/game/GameLiftExampleServer.x86_64',
}]
},
role: role
});

// Actions can also be grantted through dedicated method
fleet.grant(role, 'gamelift:ListFleets');
```

### Monitoring your Fleet

GameLift is integrated with CloudWatch, so you can monitor the performance of
your game servers via logs and metrics.

#### Metrics

GameLift Fleet sends metrics to CloudWatch so that you can collect and analyze
the activity of your Fleet, including game and player sessions and server
processes.

You can then use CloudWatch alarms to alert you, for example, when matches has
been rejected (potential matches that were rejected by at least one player
since the last report) exceed a certain thresold which could means that you may
have an issue in your matchmaking rules.

CDK provides methods for accessing GameLift Fleet metrics with default configuration,
such as `metricActiveInstances`, or `metricIdleInstances` (see [`IFleet`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-gamelift.IFleet.html)
for a full list). CDK also provides a generic `metric` method that can be used
to produce metric configurations for any metric provided by GameLift Fleet,
Game sessions or server processes; the configurations are pre-populated with
the correct dimensions for the matchmaking configuration.

```ts
declare const fleet: gamelift.BuildFleet;
// Alarm that triggers when the per-second average of not used instances exceed 10%
const instancesUsedRatio = new cloudwatch.MathExpression({
expression: '1 - (activeInstances / idleInstances)',
usingMetrics: {
activeInstances: fleet.metric('ActiveInstances', { statistic: cloudwatch.Statistic.SUM }),
idleInstances: fleet.metricIdleInstances(),
},
});
new cloudwatch.Alarm(this, 'Alarm', {
metric: instancesUsedRatio,
threshold: 0.1,
evaluationPeriods: 3,
});
```

See: [Monitoring Using CloudWatch Metrics](https://docs.aws.amazon.com/gamelift/latest/developerguide/monitoring-cloudwatch.html)
in the *Amazon GameLift Developer Guide*.

## GameLift FleetIQ

The GameLift FleetIQ solution is a game hosting layer that supplements the full
Expand Down Expand Up @@ -184,7 +429,7 @@ new gamelift.GameServerGroup(this, 'Game server group', {
See [Manage game server groups](https://docs.aws.amazon.com/gamelift/latest/fleetiqguide/gsg-integrate-gameservergroup.html)
in the *Amazon GameLift FleetIQ Developer Guide*.

### Specifying an IAM role
### Specifying an IAM role for GameLift

The GameLift FleetIQ class automatically creates an IAM role with all the minimum necessary
permissions for GameLift to access your Amazon EC2 Auto Scaling groups. If you wish, you may
Expand Down
Loading

0 comments on commit 834fab4

Please sign in to comment.