AWS for Games Blog

Automating Deployments to Amazon GameLift

One of the perks of building a multiplayer game in Lumberyard is using Amazon GameLift to manage the backend. Amazon GameLift is our managed service for deploying, operating, and scaling session-based multiplayer game servers in the cloud. Teams making multiplayer games must have a backend strong enough to handle sudden player population spikes, and GameLift takes the work and uncertainty out of building and managing those systems.

As a GameLift engineer working with our internal development teams at Amazon Game Studios (AGS), I’m all about automation. I want every commit to produce a new build, pass a set of automated tests, and be staged for QA testing, all without manual intervention. I also want this level of automation extended to cover backend game servers, particularly for AGS multiplayer games being hosted on GameLift.

While Amazon GameLift does make it easy for developers to host their servers in the cloud, the task of deploying a new build of a game requires several manual steps. I wanted to fully automate the build update process by extending the AGS continuous build system to include deployment of updated server code into Amazon GameLift.

This post walks through my approach to automating Amazon GameLift deployments and includes a Python script that you can plug directly into your build system to do the same. By following these steps, GameLift users can create new server stacks in about 30 minutes.

Approaching Automation

We’ll start by recapping the Amazon GameLift deployment model, which involves three key resources:

  • Build: The bits representing everything needed to run the game server.
  • Fleet: A set of EC2 instances running a particular build.
  • Alias: A friendly name for a fleet, which clients use to connect to the fleet. While build and fleet IDs change with each deployment, the alias ID that clients connect to remains static. For example, a client might be coded to always connect to the fleet with the alias “latest-mainline-build.”

The tasks of deploying new game builds and deploying build updates involve a similar set of steps:

  1. Upload the latest game server build to Amazon GameLift.
  2. Create a new fleet from that build and configure it.
  3. Create a new alias or update an existing alias to point to the new fleet.
  4. (build updates only) Terminate the fleet hosting the previous build, so we’re not accumulating unused resources.

AWS CloudFormation allows you to manage sets of AWS resources (including Amazon GameLift resources) together as single logical unit referred to as a stack. A stack is instantiated from a template, which is a JSON document describing a set of AWS resources. In my approach, the three Amazon GameLift resources (build, fleet, and alias) compose a logical stack, and we’ll leverage CloudFormation to create and update these stacks for us.

To simplify the process, I created a small Python command-line script that uploads the build to GameLift, then executes a Create Stack or Update Stack command in CloudFormation. CloudFormation automates all the steps required by GameLift to deploy a new game build or update. Specifically, it creates a new fleet with our newly uploaded build, configures the new fleet, and either creates a new alias or updates an existing alias that points to the new fleet. For build updates, it also scales down and terminates the old fleet. Since the update command is repeatable and cleans up old resources, it’s perfect for plugging into automated processes like a continuous build system.

The Python command-line script works in conjunction with a locally available CloudFormation template. The template defines all the properties of a fleet that generally don’t change between updates, such as launch parameters and port settings. CloudFormation uses this template when configuring a new fleet. Following the DevOps spirit of “infrastructure as code,” wherein all infrastructure is created and configured via repeatable automated processes, I suggest checking these templates into source control so you can track and review changes as needed over time.

A nice side effect of leveraging CloudFormation for updates is that it gives you an audit log of all updates made to a stack over time (shown below). You can view your current stacks in the CloudFormation section of the AWS Console.

Script Walkthrough

The Python script interacts with the AWS CLI, automating the same commands you would normally type manually, making it easy to follow along. Use the same script to either create a new stack or update an existing stack, providing parameters at the command line. The full set of options can be viewed by passing the --help option, as shown below.

> python manage-gamelift-stack.py --help

Create new or update existing Amazon GameLift stacks via AWS CloudFormation

optional arguments:
-h, --help show this help message and exit
--action {create,update}
Choose to create a new stack or update an existing one
--stack-name STACK_NAME
Name of the CloudFormation stack to create or update.
(Must contain only letters, numbers, dashes and start
with an alpha character)
--build-root BUILD_ROOT
Directory containing everything required to run your
game server per the Amazon GameLift upload-build command
--build-name BUILD_NAME
Friendly name for build
--build-version BUILD_VERSION
(Optional) Friendly version string for build
--alias-name ALIAS_NAME
Friendly name for alias
--from-template FROM_TEMPLATE
File containing a CloudFormation template defining a
stack of Amazon GameLift resources

Deploy a New Game Build

To start off, we’ll create a new stack and give it the friendly name “QA-Stack”. The process of creating a new stack will create a new GameLift alias, which our game clients will use to connect to the new fleet.

python manage-gamelift-stack.py –-action create –-stack-name “QA-Stack” –-alias-name “QA-Alias” –-build-root “./dev/Project_Dedicated” –-build-name “mainline@12456” –-from-template “./gamelift-sample-template.json”

Creating a new stack can take up to 30 minutes to run, as it is also uploading a build to GameLift and setting up a new fleet and alias. Once finished, the script will output the ID of the newly created alias (see example output below). This alias ID is what game clients must use when connecting to the fleet. As the software in the stack is updated, the underlying build and fleet IDs will change, but the alias ID will remain static.

Stack creation completed with newly created alias id: alias-0dbc24ac-2e24-4dad-91e1-0341e594fdd7

Deploy a Game Build Update

Now that we have a stack up and running, let’s examine how to update its software. We’ll leverage the same script, this time using the update action and the name of the stack we created earlier (“QA-Stack”). Specify the path to the updated build files and a new build name, as well as the CloudFormation template, to use with this deployment. Notice we don’t specify an alias name when updating, as the alias name and ID won’t change as part of the update. While GameLift does allow multiple builds to have the same name and version (the system will assign a unique build ID), I suggest tagging the build name or version with a unique identifier tying it back to your source control or build systems to aid in debugging.

python manage-gamelift-stack.py –-action update –-stack-name “QA-Stack” –-build-root “./dev/Project_Dedicated” –-build-name “mainline@98765” –-from-template “./gamelift-sample-template.json”

The update command doesn’t create a new alias, but it does clean up by terminating the previous fleet. You can expect the update process to take the same amount of time as creating a new stack. The final line output to the console will reflect this.

Stack update and clean up complete

Download Automation Components

Use these resources to create your own automation solution:

  • Python script: This script requires that the AWS CLI be installed on your path. Python, which is also required, is included in the AWS CLI install.

Download this Python script

  • CloudFormation template: Use this sample template (.json file) to create a template for your game build. If you have multiple game builds requiring more than one fleet configuration, simply copy and adjust the template for each required variation. The sample template has the correct properties filled out for the multiplayer sample project that ships with Lumberyard.

Download this sample template

Recap

With the provided Python script and leveraging CloudFormation stacks under the covers, we’ve effectively automated the process of deploying new builds to Amazon GameLift in half an hour. This process begins in one step, either manually from the command line or plugged directly into an automated build system. We’ve also reduced the risk of manual mistakes by defining our infrastructure configuration in source-controlled templates.

For more information on GameLift, watch our presentation from GDC 2016. In this talk, Chris Byskal and I explain how GameLift can help multiplayer games scale their server loads to respond to sudden changes in player populations.

Geoff Pare is a principal engineer on the Lumberyard team and has spent the last 10 years at Amazon building and operating distributed systems. He specializes in infrastructure management at scale, and GameLift combines his love of gaming with cloud computing. He’s currently playing Offworld Trading Company.