Automate uploads of Dedicated Servers and creation of Build Configurations (using Extend)
Automating dedicated server uploads and build configuration creation for AccelByte Multiplayer Servers (AMS) enables you to seamlessly start testing new game server builds on AMS. This guide covers the steps to create such automation, to be used in, for example, your CI/CD pipeline or build machine. Before automating the process, make sure you understand the concepts of how to Upload a Dedicated Server build and how to Use build configurations with development fleets.
Prerequisites
- Make sure you have an IAM client with the correct permissions. To learn how to create an IAM client, see Create an IAM client.
- For private cloud add the permission
ADMIN:NAMESPACE:{namespace}:ARMADA:FLEET (Create)
(for creating build configurations) andAMS:UPLOAD (Create, Update)
(for uploading your dedicated server image). - For shared cloud use the Dedicated Server Tools template, which includes the required Dedicated Server Toolkit and Dedicated Server permissions.
- For private cloud add the permission
- Download AMS Command Line Interface (CLI) tools to your build machine. Note that the download does not require authentication, so your pipeline could download the latest version from, for example,
https://cdn.prod.ams.accelbyte.io/linux_amd64/ams
.
Uploading a Dedicated Server Image
Use the AMS CLI in your script to upload your dedicated server image to AMS. The CLI tool can be run manually on the command line, but in this guide we will call it programmatically.
Creating a Build Configuration via the API
Call the API endpoint to create a build configuration, details of which are provided below. Note that, instead of calling the API endpoint directly, we recommend using the AccelByte Extend SDK, which aims to help developers invoke AccelByte Gaming Services (AGS) by simplifying getting an access token and calling the required endpoints.
Alternatively, send a request to the server-configurations endpoint, as described in this section of the AccelByte API explorer.
- name: A unique build configuration name (commonly matching your game or build version, e.g.,
"mygame-v0001"
). - imageId: The dedicated server image ID from your uploaded build.
- commandLineArguments: The command line arguments for launching your dedicated server.
- expiresAt: When the build configuration expires and will be cleaned up, e.g. 2025-04-18T10:20:00.000Z.
Example script: Uploading an Image and creating a Build Configuration (Extend)
The example script below uploads an dedicated server image and creates a build configuration for that image. Adapt it according to your build system needs. The script outputs the ID of the uploaded image and the name of the created Build Configuration. After running the script the build configuration will be visible in Admin Portal and can be used when claiming a dedicated server. This script uses the AccelByte Extend SDK.
Before running the sample, set the following environment variables:
export AB_BASE_URL="https://<yourenvironment>.accelbyte.io" # For shared cloud use https://<studionamespace>-<gamenamespace>.prod.gamingservices.accelbyte.io
export AB_CLIENT_ID="your_client_id"
export AB_CLIENT_SECRET="your_client_secret"
export AB_NAMESPACE="your_namespace"
import accelbyte_py_sdk
import accelbyte_py_sdk.services.auth as auth_service
import json
import os
import re
import subprocess
from accelbyte_py_sdk.api.ams.models import ApiDevelopmentServerConfigurationCreateRequest
from accelbyte_py_sdk.api.ams.operations.development import DevelopmentServerConfigurationCreate
from accelbyte_py_sdk.core import EnvironmentConfigRepository, run_request
from datetime import datetime, timedelta
BUILD_VERSION = datetime.now().strftime('%Y-%m-%d_%H-%M')
# Constants, update these with your actual values
CONFIG_NAME = f"mygame_{BUILD_VERSION}" # Unique configuration name (max 128 chars)
COMMAND_LINE = "-dsid ${dsid} -port ${default_port}" # Command line arguments passed to your DS
AMS_CLI_PATH = "./ams-cli" # AMS CLI executable path.
DS_FOLDER_PATH = "build" # Filepath containing your DS executable
DS_EXECUTABLE_NAME = "runserver" # Filename of your DS executable
DS_IMAGE_NAME = f"image-{BUILD_VERSION}" # Unique image name
AB_BASE_URL, AB_CLIENT_ID, AB_CLIENT_SECRET, AB_NAMESPACE = (
os.getenv(var) for var in ["AB_BASE_URL", "AB_CLIENT_ID", "AB_CLIENT_SECRET", "AB_NAMESPACE"]
)
def upload_image():
if not os.path.exists(AMS_CLI_PATH):
print("AMS CLI not found")
exit(1)
hostname = AB_BASE_URL.split("//")[-1]
command = [
AMS_CLI_PATH,
"upload",
"-c", AB_CLIENT_ID,
"-s", AB_CLIENT_SECRET,
"-e", DS_EXECUTABLE_NAME,
"-n", DS_IMAGE_NAME,
"-H", hostname,
"-p", DS_FOLDER_PATH
]
try:
# Execute the CLI to upload the DS
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Upload successful.")
image_id = re.search(r'img_[a-zA-Z0-9_-]+', result.stderr.decode()).group(0)
print(f"DS Image ID: {image_id}")
return image_id
except subprocess.CalledProcessError as e:
print("An error occurred during the upload process:" + e.stderr.decode())
def create_build_config(image_id):
# Initialize the SDK (uses AB_BASE_URL, AB_CLIENT_ID, AB_CLIENT_SECRET, and AB_NAMESPACE)
accelbyte_py_sdk.initialize()
# Login using client credentials
token, error = auth_service.login_client()
if error:
print("Login failed:", error)
exit(1)
# Set expiration to 30 days from now
expires_at = (datetime.utcnow() + timedelta(days=30)).isoformat() + "Z"
# Build the request body
body = ApiDevelopmentServerConfigurationCreateRequest.create(
command_line_arguments=COMMAND_LINE,
expires_at=expires_at,
image_id=image_id,
name=CONFIG_NAME
)
# Create the operation using the extend SDK's create method
operation = DevelopmentServerConfigurationCreate.create(
body=body,
namespace=AB_NAMESPACE
)
# Execute the operation
result, error = run_request(operation)
if error:
print("Error creating configuration:", error)
exit(1)
print("Your build configuration:")
print(json.dumps(result.to_dict(), indent=2))
if __name__ == "__main__":
for var_name in ["AMS_CLI_PATH", "AB_CLIENT_ID", "AB_NAMESPACE", "AB_CLIENT_SECRET", "DS_EXECUTABLE_NAME", "DS_IMAGE_NAME", "DS_FOLDER_PATH"]:
var_value = globals().get(var_name)
if var_value is None or var_value == "":
raise ValueError(f"Missing or empty required variable: {var_name}")
image_id = upload_image()
if image_id is None or image_id == "":
exit(1)
create_build_config(image_id)
print("Done.")