Configure AWS GameLift Game Server Groups

The aws:gamelift/gameServerGroup:GameServerGroup resource, part of the Pulumi AWS provider, manages a GameLift FleetIQ game server group that provisions and scales EC2 instances for hosting game servers. This guide focuses on four capabilities: instance type definitions and capacity weighting, spot instance balancing strategies, auto-scaling policies with target tracking, and IAM role configuration.

Game server groups require an EC2 launch template that defines the instance configuration and an IAM role that grants GameLift permissions to manage Auto Scaling groups. The examples are intentionally small. Combine them with your own launch templates, VPC configuration, and monitoring.

Create the required IAM role for GameLift access

Before creating a game server group, you need an IAM role that grants GameLift and Auto Scaling permissions to manage EC2 instances.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const current = aws.getPartition({});
const assumeRole = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        principals: [{
            type: "Service",
            identifiers: [
                "autoscaling.amazonaws.com",
                "gamelift.amazonaws.com",
            ],
        }],
        actions: ["sts:AssumeRole"],
    }],
});
const example = new aws.iam.Role("example", {
    assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
    name: "gamelift-game-server-group-example",
});
const exampleRolePolicyAttachment = new aws.iam.RolePolicyAttachment("example", {
    policyArn: current.then(current => `arn:${current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy`),
    role: example.name,
});
import pulumi
import pulumi_aws as aws

current = aws.get_partition()
assume_role = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "principals": [{
        "type": "Service",
        "identifiers": [
            "autoscaling.amazonaws.com",
            "gamelift.amazonaws.com",
        ],
    }],
    "actions": ["sts:AssumeRole"],
}])
example = aws.iam.Role("example",
    assume_role_policy=assume_role.json,
    name="gamelift-game-server-group-example")
example_role_policy_attachment = aws.iam.RolePolicyAttachment("example",
    policy_arn=f"arn:{current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy",
    role=example.name)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetPartition(ctx, &aws.GetPartitionArgs{}, nil)
		if err != nil {
			return err
		}
		assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Effect: pulumi.StringRef("Allow"),
					Principals: []iam.GetPolicyDocumentStatementPrincipal{
						{
							Type: "Service",
							Identifiers: []string{
								"autoscaling.amazonaws.com",
								"gamelift.amazonaws.com",
							},
						},
					},
					Actions: []string{
						"sts:AssumeRole",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		example, err := iam.NewRole(ctx, "example", &iam.RoleArgs{
			AssumeRolePolicy: pulumi.String(assumeRole.Json),
			Name:             pulumi.String("gamelift-game-server-group-example"),
		})
		if err != nil {
			return err
		}
		_, err = iam.NewRolePolicyAttachment(ctx, "example", &iam.RolePolicyAttachmentArgs{
			PolicyArn: pulumi.Sprintf("arn:%v:iam::aws:policy/GameLiftGameServerGroupPolicy", current.Partition),
			Role:      example.Name,
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var current = Aws.GetPartition.Invoke();

    var assumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "autoscaling.amazonaws.com",
                            "gamelift.amazonaws.com",
                        },
                    },
                },
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
            },
        },
    });

    var example = new Aws.Iam.Role("example", new()
    {
        AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
        Name = "gamelift-game-server-group-example",
    });

    var exampleRolePolicyAttachment = new Aws.Iam.RolePolicyAttachment("example", new()
    {
        PolicyArn = $"arn:{current.Apply(getPartitionResult => getPartitionResult.Partition)}:iam::aws:policy/GameLiftGameServerGroupPolicy",
        Role = example.Name,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetPartitionArgs;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.iam.RolePolicyAttachment;
import com.pulumi.aws.iam.RolePolicyAttachmentArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var current = AwsFunctions.getPartition(GetPartitionArgs.builder()
            .build());

        final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers(                    
                        "autoscaling.amazonaws.com",
                        "gamelift.amazonaws.com")
                    .build())
                .actions("sts:AssumeRole")
                .build())
            .build());

        var example = new Role("example", RoleArgs.builder()
            .assumeRolePolicy(assumeRole.json())
            .name("gamelift-game-server-group-example")
            .build());

        var exampleRolePolicyAttachment = new RolePolicyAttachment("exampleRolePolicyAttachment", RolePolicyAttachmentArgs.builder()
            .policyArn(String.format("arn:%s:iam::aws:policy/GameLiftGameServerGroupPolicy", current.partition()))
            .role(example.name())
            .build());

    }
}
resources:
  example:
    type: aws:iam:Role
    properties:
      assumeRolePolicy: ${assumeRole.json}
      name: gamelift-game-server-group-example
  exampleRolePolicyAttachment:
    type: aws:iam:RolePolicyAttachment
    name: example
    properties:
      policyArn: arn:${current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy
      role: ${example.name}
variables:
  current:
    fn::invoke:
      function: aws:getPartition
      arguments: {}
  assumeRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            principals:
              - type: Service
                identifiers:
                  - autoscaling.amazonaws.com
                  - gamelift.amazonaws.com
            actions:
              - sts:AssumeRole

The assume role policy allows both gamelift.amazonaws.com and autoscaling.amazonaws.com to assume the role. The GameLiftGameServerGroupPolicy is an AWS-managed policy that grants the necessary permissions for FleetIQ to manage your Auto Scaling group and EC2 instances.

Create a game server group with basic scaling

Game server groups manage fleets of EC2 instances, balancing capacity across instance types while GameLift FleetIQ handles game server placement.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.gamelift.GameServerGroup("example", {
    gameServerGroupName: "example",
    instanceDefinitions: [
        {
            instanceType: "c5.large",
        },
        {
            instanceType: "c5a.large",
        },
    ],
    launchTemplate: {
        id: exampleAwsLaunchTemplate.id,
    },
    maxSize: 1,
    minSize: 1,
    roleArn: exampleAwsIamRole.arn,
}, {
    dependsOn: [exampleAwsIamRolePolicyAttachment],
});
import pulumi
import pulumi_aws as aws

example = aws.gamelift.GameServerGroup("example",
    game_server_group_name="example",
    instance_definitions=[
        {
            "instance_type": "c5.large",
        },
        {
            "instance_type": "c5a.large",
        },
    ],
    launch_template={
        "id": example_aws_launch_template["id"],
    },
    max_size=1,
    min_size=1,
    role_arn=example_aws_iam_role["arn"],
    opts = pulumi.ResourceOptions(depends_on=[example_aws_iam_role_policy_attachment]))
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/gamelift"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := gamelift.NewGameServerGroup(ctx, "example", &gamelift.GameServerGroupArgs{
			GameServerGroupName: pulumi.String("example"),
			InstanceDefinitions: gamelift.GameServerGroupInstanceDefinitionArray{
				&gamelift.GameServerGroupInstanceDefinitionArgs{
					InstanceType: pulumi.String("c5.large"),
				},
				&gamelift.GameServerGroupInstanceDefinitionArgs{
					InstanceType: pulumi.String("c5a.large"),
				},
			},
			LaunchTemplate: &gamelift.GameServerGroupLaunchTemplateArgs{
				Id: pulumi.Any(exampleAwsLaunchTemplate.Id),
			},
			MaxSize: pulumi.Int(1),
			MinSize: pulumi.Int(1),
			RoleArn: pulumi.Any(exampleAwsIamRole.Arn),
		}, pulumi.DependsOn([]pulumi.Resource{
			exampleAwsIamRolePolicyAttachment,
		}))
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.GameLift.GameServerGroup("example", new()
    {
        GameServerGroupName = "example",
        InstanceDefinitions = new[]
        {
            new Aws.GameLift.Inputs.GameServerGroupInstanceDefinitionArgs
            {
                InstanceType = "c5.large",
            },
            new Aws.GameLift.Inputs.GameServerGroupInstanceDefinitionArgs
            {
                InstanceType = "c5a.large",
            },
        },
        LaunchTemplate = new Aws.GameLift.Inputs.GameServerGroupLaunchTemplateArgs
        {
            Id = exampleAwsLaunchTemplate.Id,
        },
        MaxSize = 1,
        MinSize = 1,
        RoleArn = exampleAwsIamRole.Arn,
    }, new CustomResourceOptions
    {
        DependsOn =
        {
            exampleAwsIamRolePolicyAttachment,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.gamelift.GameServerGroup;
import com.pulumi.aws.gamelift.GameServerGroupArgs;
import com.pulumi.aws.gamelift.inputs.GameServerGroupInstanceDefinitionArgs;
import com.pulumi.aws.gamelift.inputs.GameServerGroupLaunchTemplateArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new GameServerGroup("example", GameServerGroupArgs.builder()
            .gameServerGroupName("example")
            .instanceDefinitions(            
                GameServerGroupInstanceDefinitionArgs.builder()
                    .instanceType("c5.large")
                    .build(),
                GameServerGroupInstanceDefinitionArgs.builder()
                    .instanceType("c5a.large")
                    .build())
            .launchTemplate(GameServerGroupLaunchTemplateArgs.builder()
                .id(exampleAwsLaunchTemplate.id())
                .build())
            .maxSize(1)
            .minSize(1)
            .roleArn(exampleAwsIamRole.arn())
            .build(), CustomResourceOptions.builder()
                .dependsOn(exampleAwsIamRolePolicyAttachment)
                .build());

    }
}
resources:
  example:
    type: aws:gamelift:GameServerGroup
    properties:
      gameServerGroupName: example
      instanceDefinitions:
        - instanceType: c5.large
        - instanceType: c5a.large
      launchTemplate:
        id: ${exampleAwsLaunchTemplate.id}
      maxSize: 1
      minSize: 1
      roleArn: ${exampleAwsIamRole.arn}
    options:
      dependsOn:
        - ${exampleAwsIamRolePolicyAttachment}

The instanceDefinitions array lists EC2 instance types that GameLift can use. The launchTemplate references your EC2 launch template that defines AMI, security groups, and user data. The minSize and maxSize properties set Auto Scaling boundaries. The roleArn must reference the IAM role created in the previous example, and the dependsOn ensures the role policy attachment completes before creating the group.

Configure spot instances with auto-scaling policies

Production deployments often use spot instances to reduce costs while maintaining target utilization through auto-scaling.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.gamelift.GameServerGroup("example", {
    autoScalingPolicy: {
        estimatedInstanceWarmup: 60,
        targetTrackingConfiguration: {
            targetValue: 75,
        },
    },
    balancingStrategy: "SPOT_ONLY",
    gameServerGroupName: "example",
    gameServerProtectionPolicy: "FULL_PROTECTION",
    instanceDefinitions: [
        {
            instanceType: "c5.large",
            weightedCapacity: "1",
        },
        {
            instanceType: "c5.2xlarge",
            weightedCapacity: "2",
        },
    ],
    launchTemplate: {
        id: exampleAwsLaunchTemplate.id,
        version: "1",
    },
    maxSize: 1,
    minSize: 1,
    roleArn: exampleAwsIamRole.arn,
    tags: {
        Name: "example",
    },
    vpcSubnets: [
        "subnet-12345678",
        "subnet-23456789",
    ],
}, {
    dependsOn: [exampleAwsIamRolePolicyAttachment],
});
import pulumi
import pulumi_aws as aws

example = aws.gamelift.GameServerGroup("example",
    auto_scaling_policy={
        "estimated_instance_warmup": 60,
        "target_tracking_configuration": {
            "target_value": 75,
        },
    },
    balancing_strategy="SPOT_ONLY",
    game_server_group_name="example",
    game_server_protection_policy="FULL_PROTECTION",
    instance_definitions=[
        {
            "instance_type": "c5.large",
            "weighted_capacity": "1",
        },
        {
            "instance_type": "c5.2xlarge",
            "weighted_capacity": "2",
        },
    ],
    launch_template={
        "id": example_aws_launch_template["id"],
        "version": "1",
    },
    max_size=1,
    min_size=1,
    role_arn=example_aws_iam_role["arn"],
    tags={
        "Name": "example",
    },
    vpc_subnets=[
        "subnet-12345678",
        "subnet-23456789",
    ],
    opts = pulumi.ResourceOptions(depends_on=[example_aws_iam_role_policy_attachment]))
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/gamelift"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := gamelift.NewGameServerGroup(ctx, "example", &gamelift.GameServerGroupArgs{
			AutoScalingPolicy: &gamelift.GameServerGroupAutoScalingPolicyArgs{
				EstimatedInstanceWarmup: pulumi.Int(60),
				TargetTrackingConfiguration: &gamelift.GameServerGroupAutoScalingPolicyTargetTrackingConfigurationArgs{
					TargetValue: pulumi.Float64(75),
				},
			},
			BalancingStrategy:          pulumi.String("SPOT_ONLY"),
			GameServerGroupName:        pulumi.String("example"),
			GameServerProtectionPolicy: pulumi.String("FULL_PROTECTION"),
			InstanceDefinitions: gamelift.GameServerGroupInstanceDefinitionArray{
				&gamelift.GameServerGroupInstanceDefinitionArgs{
					InstanceType:     pulumi.String("c5.large"),
					WeightedCapacity: pulumi.String("1"),
				},
				&gamelift.GameServerGroupInstanceDefinitionArgs{
					InstanceType:     pulumi.String("c5.2xlarge"),
					WeightedCapacity: pulumi.String("2"),
				},
			},
			LaunchTemplate: &gamelift.GameServerGroupLaunchTemplateArgs{
				Id:      pulumi.Any(exampleAwsLaunchTemplate.Id),
				Version: pulumi.String("1"),
			},
			MaxSize: pulumi.Int(1),
			MinSize: pulumi.Int(1),
			RoleArn: pulumi.Any(exampleAwsIamRole.Arn),
			Tags: pulumi.StringMap{
				"Name": pulumi.String("example"),
			},
			VpcSubnets: pulumi.StringArray{
				pulumi.String("subnet-12345678"),
				pulumi.String("subnet-23456789"),
			},
		}, pulumi.DependsOn([]pulumi.Resource{
			exampleAwsIamRolePolicyAttachment,
		}))
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.GameLift.GameServerGroup("example", new()
    {
        AutoScalingPolicy = new Aws.GameLift.Inputs.GameServerGroupAutoScalingPolicyArgs
        {
            EstimatedInstanceWarmup = 60,
            TargetTrackingConfiguration = new Aws.GameLift.Inputs.GameServerGroupAutoScalingPolicyTargetTrackingConfigurationArgs
            {
                TargetValue = 75,
            },
        },
        BalancingStrategy = "SPOT_ONLY",
        GameServerGroupName = "example",
        GameServerProtectionPolicy = "FULL_PROTECTION",
        InstanceDefinitions = new[]
        {
            new Aws.GameLift.Inputs.GameServerGroupInstanceDefinitionArgs
            {
                InstanceType = "c5.large",
                WeightedCapacity = "1",
            },
            new Aws.GameLift.Inputs.GameServerGroupInstanceDefinitionArgs
            {
                InstanceType = "c5.2xlarge",
                WeightedCapacity = "2",
            },
        },
        LaunchTemplate = new Aws.GameLift.Inputs.GameServerGroupLaunchTemplateArgs
        {
            Id = exampleAwsLaunchTemplate.Id,
            Version = "1",
        },
        MaxSize = 1,
        MinSize = 1,
        RoleArn = exampleAwsIamRole.Arn,
        Tags = 
        {
            { "Name", "example" },
        },
        VpcSubnets = new[]
        {
            "subnet-12345678",
            "subnet-23456789",
        },
    }, new CustomResourceOptions
    {
        DependsOn =
        {
            exampleAwsIamRolePolicyAttachment,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.gamelift.GameServerGroup;
import com.pulumi.aws.gamelift.GameServerGroupArgs;
import com.pulumi.aws.gamelift.inputs.GameServerGroupAutoScalingPolicyArgs;
import com.pulumi.aws.gamelift.inputs.GameServerGroupAutoScalingPolicyTargetTrackingConfigurationArgs;
import com.pulumi.aws.gamelift.inputs.GameServerGroupInstanceDefinitionArgs;
import com.pulumi.aws.gamelift.inputs.GameServerGroupLaunchTemplateArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new GameServerGroup("example", GameServerGroupArgs.builder()
            .autoScalingPolicy(GameServerGroupAutoScalingPolicyArgs.builder()
                .estimatedInstanceWarmup(60)
                .targetTrackingConfiguration(GameServerGroupAutoScalingPolicyTargetTrackingConfigurationArgs.builder()
                    .targetValue(75.0)
                    .build())
                .build())
            .balancingStrategy("SPOT_ONLY")
            .gameServerGroupName("example")
            .gameServerProtectionPolicy("FULL_PROTECTION")
            .instanceDefinitions(            
                GameServerGroupInstanceDefinitionArgs.builder()
                    .instanceType("c5.large")
                    .weightedCapacity("1")
                    .build(),
                GameServerGroupInstanceDefinitionArgs.builder()
                    .instanceType("c5.2xlarge")
                    .weightedCapacity("2")
                    .build())
            .launchTemplate(GameServerGroupLaunchTemplateArgs.builder()
                .id(exampleAwsLaunchTemplate.id())
                .version("1")
                .build())
            .maxSize(1)
            .minSize(1)
            .roleArn(exampleAwsIamRole.arn())
            .tags(Map.of("Name", "example"))
            .vpcSubnets(            
                "subnet-12345678",
                "subnet-23456789")
            .build(), CustomResourceOptions.builder()
                .dependsOn(exampleAwsIamRolePolicyAttachment)
                .build());

    }
}
resources:
  example:
    type: aws:gamelift:GameServerGroup
    properties:
      autoScalingPolicy:
        estimatedInstanceWarmup: 60
        targetTrackingConfiguration:
          targetValue: 75
      balancingStrategy: SPOT_ONLY
      gameServerGroupName: example
      gameServerProtectionPolicy: FULL_PROTECTION
      instanceDefinitions:
        - instanceType: c5.large
          weightedCapacity: '1'
        - instanceType: c5.2xlarge
          weightedCapacity: '2'
      launchTemplate:
        id: ${exampleAwsLaunchTemplate.id}
        version: '1'
      maxSize: 1
      minSize: 1
      roleArn: ${exampleAwsIamRole.arn}
      tags:
        Name: example
      vpcSubnets:
        - subnet-12345678
        - subnet-23456789
    options:
      dependsOn:
        - ${exampleAwsIamRolePolicyAttachment}

The balancingStrategy set to SPOT_ONLY uses only spot instances. The autoScalingPolicy defines target tracking that scales the group to maintain 75% utilization. The weightedCapacity property lets you assign different capacity values to instance types (c5.2xlarge counts as 2 units). The gameServerProtectionPolicy set to FULL_PROTECTION prevents termination of instances running active game servers. The vpcSubnets property places instances in specific subnets for network isolation.

Beyond these examples

These snippets focus on specific game server group features: instance type definitions and weighted capacity, spot instance balancing and cost optimization, and IAM role configuration for GameLift access. They’re intentionally minimal rather than full game hosting deployments.

The examples reference pre-existing infrastructure such as EC2 launch templates and VPC subnets for production configurations. They focus on configuring the game server group rather than provisioning the surrounding infrastructure.

To keep things focused, common game server group patterns are omitted, including:

  • Launch template configuration (AMI, user data, security groups)
  • Game server protection during scale-down events
  • VPC subnet selection and availability zone distribution
  • Custom auto-scaling metrics beyond target tracking

These omissions are intentional: the goal is to illustrate how each game server group feature is wired, not provide drop-in game hosting modules. See the GameLift GameServerGroup resource reference for all available configuration options.

Let's configure AWS GameLift Game Server Groups

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

IAM & Permissions
What IAM permissions does my Game Server Group need?
The IAM role requires a trust policy allowing autoscaling.amazonaws.com and gamelift.amazonaws.com to assume the role, plus the AWS managed policy GameLiftGameServerGroupPolicy attached.
Why do I need to use dependsOn with the IAM role policy attachment?
The game server group requires the IAM role policy to be fully attached before creation. Use dependsOn to ensure the policy attachment completes first.
Instance Protection & Scaling
What's the difference between NO_PROTECTION and FULL_PROTECTION?
NO_PROTECTION (default) allows instances with active game servers to be terminated during scale-down, potentially dropping players. FULL_PROTECTION prevents termination while game servers are active, except during forced deletion.
What balancing strategies are available for Spot and On-Demand instances?
You can choose SPOT_ONLY, SPOT_PREFERRED (default), or ON_DEMAND_ONLY. This controls how GameLift FleetIQ balances instance types.
What does weightedCapacity do in instance definitions?
weightedCapacity assigns a capacity weight to each instance type, allowing larger instances to count for more capacity units during scaling. For example, a c5.2xlarge with weight 2 counts as two c5.large instances with weight 1.
Configuration & Immutability
What properties are immutable after creation?
You cannot change gameServerGroupName, maxSize, minSize, autoScalingPolicy, or vpcSubnets after creation. These require resource replacement.
What VPC subnets are used by default?
If you don’t specify vpcSubnets, GameLift FleetIQ uses all supported Availability Zones by default.
Can I specify a launch template version?
Yes, the launchTemplate configuration accepts both id and an optional version parameter.

Using a different cloud?

Explore compute guides for other cloud providers: