Configuring your cloud provider
This document describes the steps required to set up your Cloud provider for use with GameFabric. This setup is also known as Bring Your Own Cloud (BYOC), where GameFabric manages resources within your Cloud provider account.
Currently supported Cloud providers are Google Cloud (GCP), Azure, and Amazon Web Services (AWS).
Public documentation is currently limited to Google Cloud and AWS. For setup instructions for other Cloud providers, please contact your Customer Success Manager at Nitrado.
Pre-requisites
Make sure you understand the hosting models and have your environment set up before configuring cloud capacity.
Google Cloud
GCP prerequisites
- You must already have an existing Google Cloud organization
- You must possess the necessary permissions to manage principals and billing accounts in your organization
If any of those pre-requisites are not met, like if you don't yet have an organization, you must contact Nitrado as the steps are different from what is described below.
Creating a Principal
- Visit the Cloud Resource Manager page
- Click the Create Folder button and name it Nitrado
- You might have to press F5 for the folder to become visible
- Select the Nitrado folder
- Click the Add Principal button
- Input
[email protected]as the value for New Principal
Allowing project management
The Nitrado principal requires the permissions to manage all resources within the Nitrado folder. Everything else within your organization is invisible and inaccessible to Nitrado.
Assign the following roles to the [email protected] principal:
- Folder Admin
- Owner
- Project Creator
Now follow the same steps in the Organization page, but instead, assign the following role to our Principal:
- Organization Viewer
Allowing billing management
In order to link your billing account to the projects managed by Nitrado, and to create Billing Reports, the Nitrado principal requires following the steps below:
- Visit the billing configuration page
- Select your billing account
- Click the Add Principal button
- Assign the following roles
Billing Account UserBilling Account Viewer
Confirming the GCP setup
After you have completed the steps above, please contact Nitrado to confirm that the setup is complete.
Amazon Web Services
AWS prerequisites
- You must already have an existing AWS account
- You must possess the necessary permissions to create IAM resources in your account
Background
To access another organization or account, set up a chain of roles. Roles are AWS IAM identities that have specific permissions, defined by Policies. Roles are intended to be assumed by other IAM entities like users, groups, or even other roles. By chaining those roles together (i.e., allowing a role to assume another role), GameFabric operators can access your organization/account. This setup allows delegating game server cluster management to GameFabric operators to provision and manage AWS resources without having to grant broad access to their organization.

In order to set this up, we recommend using a tool like Terraform or OpenTofu, as they allow to simply declare the desired resources. Particularly for configuring various policy documents, this is helpful.
Set up account federation
In the AWS management console, navigate to IAM > Roles, and create a new IAM Role with a custom trust policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowGamefabricSAML",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::339712714940:saml-provider/AWSSSO_5495e4acbcad9a8a_DO_NOT_DELETE"
},
"Action": [
"sts:AssumeRoleWithSAML",
"sts:TagSession"
],
"Condition": {
"StringEquals": {
"SAML:aud": "https://signin.aws.amazon.com/saml"
}
}
},
{
"Sid": "AllowGamefabricOperatorsRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::339712714940:role/gamefabric-operators"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}resource "aws_iam_role" "gamefabric_operators" {
name = "gamefabric-operators"
assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
tags = {
role = "gamefabric-operators"
provider = "gamefabric"
}
}
# This document is what is required to grant Nitrado access to your org
data "aws_iam_policy_document" "assume_role_policy" {
statement {
effect = "Allow"
actions = [
"sts:AssumeRoleWithSAML",
"sts:TagSession",
"sts:AssumeRole"
]
principals {
type = "Federated"
identifiers = ["arn:aws:iam::339712714940:saml-provider/AWSSSO_5495e4acbcad9a8a_DO_NOT_DELETE"]
}
condition {
test = "StringEquals"
variable = "SAML:aud"
values = ["https://signin.aws.amazon.com/saml"]
}
}
statement {
effect = "Allow"
actions = [
"sts:TagSession",
"sts:AssumeRole"
]
principals {
type = "AWS"
identifiers = ["arn:aws:iam::339712714940:role/gamefabric-operators"]
}
}
}The account ID 339712714940 belongs to the GameFabric organization.
In the role creation wizard, skip the permissions step. Name the role gamefabric-operators, and optionally add a description and tags for adding metadata, for example noting the purpose of the role and being linked to GameFabric.
Next, create one or more policies for the required permissions. The following policies explicitly list all permissions for the required AWS services. AWS restricts the size of these documents to 4KB per document. Adding all the permissions into one policy exceeds the limit for a single policy. We split them up logically such that they are grouped broadly by the resource types they grant access to.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EKS",
"Effect": "Allow",
"Resource": "*",
"Action": [
"eks:AccessKubernetesApi",
"eks:AssociateAccessPolicy",
"eks:CreateAccessEntry",
"eks:CreateAddon",
"eks:CreateCluster",
"eks:CreateNodegroup",
"eks:DeleteAccessEntry",
"eks:DeleteAddon",
"eks:DeleteCluster",
"eks:DeleteNodegroup",
"eks:DescribeAccessEntry",
"eks:DescribeAddon",
"eks:DescribeAddonConfiguration",
"eks:DescribeAddonVersions",
"eks:DescribeCluster",
"eks:DescribeClusterVersions",
"eks:DescribeNodegroup",
"eks:DescribePodIdentityAssociation",
"eks:DescribeUpdate",
"eks:DisassociateAccessPolicy",
"eks:ListAccessEntries",
"eks:ListAddons",
"eks:ListAssociatedAccessPolicies",
"eks:ListClusters",
"eks:ListNodegroups",
"eks:ListUpdates",
"eks:TagResource",
"eks:UntagResource",
"eks:UpdateAccessEntry",
"eks:UpdateAddon",
"eks:UpdateClusterVersion",
"eks:UpdateNodegroupConfig",
"eks:UpdateNodegroupVersion"
]
}
]
}{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2",
"Effect": "Allow",
"Resource": "*",
"Action": [
"ec2:AllocateAddress",
"ec2:AssociateRouteTable",
"ec2:AttachInternetGateway",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateInternetGateway",
"ec2:CreateLaunchTemplate",
"ec2:CreateLaunchTemplateVersion",
"ec2:CreateNatGateway",
"ec2:CreateNetworkAclEntry",
"ec2:CreateRoute",
"ec2:CreateRouteTable",
"ec2:CreateSecurityGroup",
"ec2:CreateSubnet",
"ec2:CreateTags",
"ec2:CreateVpc",
"ec2:DeleteInternetGateway",
"ec2:DeleteLaunchTemplate",
"ec2:DeleteNatGateway",
"ec2:DeleteNetworkAclEntry",
"ec2:DeleteRoute",
"ec2:DeleteRouteTable",
"ec2:DeleteSecurityGroup",
"ec2:DeleteSubnet",
"ec2:DeleteTags",
"ec2:DeleteVolume",
"ec2:DeleteVpc",
"ec2:DescribeAddresses",
"ec2:DescribeAddressesAttribute",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstanceTypes",
"ec2:DescribeInternetGateways",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeNatGateways",
"ec2:DescribeNetworkAcls",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribePlacementGroups",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcs",
"ec2:DetachInternetGateway",
"ec2:DetachVolume",
"ec2:DisassociateAddress",
"ec2:DisassociateRouteTable",
"ec2:GetEbsDefaultKmsKeyId",
"ec2:GetEbsEncryptionByDefault",
"ec2:GetInstanceMetadataDefaults",
"ec2:GetInstanceTypesFromInstanceRequirements",
"ec2:GetSecurityGroupsForVpc",
"ec2:ModifyLaunchTemplate",
"ec2:ModifySubnetAttribute",
"ec2:ModifyVpcAttribute",
"ec2:ReleaseAddress",
"ec2:ReplaceRoute",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RunInstances",
"ec2:StopInstances",
"ec2:TerminateInstances"
]
}
]
}{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Autoscaling",
"Effect": "Allow",
"Resource": "*",
"Action": [
"autoscaling:UpdateAutoScalingGroup",
"autoscaling:DetachInstances",
"autoscaling:DescribeTags",
"autoscaling:DescribeScalingActivities",
"autoscaling:DescribePolicies",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DeletePolicy",
"autoscaling:DeleteLaunchConfiguration",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:CreateLaunchConfiguration",
"autoscaling:CreateAutoScalingGroup",
"autoscaling:AttachInstances"
]
}
]
}{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KeyManagementService",
"Effect": "Allow",
"Resource": "*",
"Action": [
"kms:CreateAlias",
"kms:CreateGrant",
"kms:CreateKey",
"kms:DeleteAlias",
"kms:EnableKeyRotation",
"kms:ListAliases",
"kms:ScheduleKeyDeletion",
"kms:TagResource"
]
},
{
"Sid": "IAM",
"Effect": "Allow",
"Resource": "*",
"Action": [
"iam:AttachRolePolicy",
"iam:CreateOpenIDConnectProvider",
"iam:CreatePolicy",
"iam:CreateRole",
"iam:CreateServiceLinkedRole",
"iam:DeleteOpenIDConnectProvider",
"iam:DeletePolicy",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:GetOpenIDConnectProvider",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListAttachedRolePolicies",
"iam:ListInstanceProfiles",
"iam:ListInstanceProfilesForRole",
"iam:ListOpenIDConnectProviders",
"iam:ListPolicies",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:ListRoles",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:TagOpenIDConnectProvider",
"iam:TagPolicy",
"iam:TagRole"
]
},
{
"Sid": "CloudWatchLogs",
"Effect": "Allow",
"Resource": "*",
"Action": [
"logs:CreateLogGroup",
"logs:DeleteLogGroup",
"logs:DescribeLogGroups",
"logs:ListTagsForResource",
"logs:PutRetentionPolicy",
"logs:TagResource"
]
},
{
"Sid": "SSM",
"Effect": "Allow",
"Resource": ["arn:aws:ssm:*:*:parameter/aws/service/eks/optimized-ami/*"],
"Action": [
"ssm:GetParameter"
]
}
]
}data "aws_iam_policy_document" "deployer_eks" {
statement {
effect = "Allow"
actions = [
"eks:AccessKubernetesApi",
"eks:AssociateAccessPolicy",
"eks:CreateAccessEntry",
"eks:CreateAddon",
"eks:CreateCluster",
"eks:CreateNodegroup",
"eks:DeleteAccessEntry",
"eks:DeleteAddon",
"eks:DeleteCluster",
"eks:DeleteNodegroup",
"eks:DescribeAccessEntry",
"eks:DescribeAddon",
"eks:DescribeAddonConfiguration",
"eks:DescribeAddonVersions",
"eks:DescribeCluster",
"eks:DescribeClusterVersions",
"eks:DescribeNodegroup",
"eks:DescribePodIdentityAssociation",
"eks:DescribeUpdate",
"eks:DisassociateAccessPolicy",
"eks:ListAccessEntries",
"eks:ListAddons",
"eks:ListAssociatedAccessPolicies",
"eks:ListClusters",
"eks:ListNodegroups",
"eks:ListUpdates",
"eks:TagResource",
"eks:UntagResource",
"eks:UpdateAccessEntry",
"eks:UpdateAddon",
"eks:UpdateClusterVersion",
"eks:UpdateNodegroupConfig",
"eks:UpdateNodegroupVersion",
]
resources = ["*"]
}
}
data "aws_iam_policy_document" "deployer_ec2" {
statement {
effect = "Allow"
actions = [
"ec2:AllocateAddress",
"ec2:AssociateRouteTable",
"ec2:AttachInternetGateway",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateInternetGateway",
"ec2:CreateLaunchTemplate",
"ec2:CreateLaunchTemplateVersion",
"ec2:CreateNatGateway",
"ec2:CreateNetworkAclEntry",
"ec2:CreateRoute",
"ec2:CreateRouteTable",
"ec2:CreateSecurityGroup",
"ec2:CreateSubnet",
"ec2:CreateTags",
"ec2:CreateVpc",
"ec2:DeleteInternetGateway",
"ec2:DeleteLaunchTemplate",
"ec2:DeleteNatGateway",
"ec2:DeleteNetworkAclEntry",
"ec2:DeleteRoute",
"ec2:DeleteRouteTable",
"ec2:DeleteSecurityGroup",
"ec2:DeleteSubnet",
"ec2:DeleteTags",
"ec2:DeleteVolume",
"ec2:DeleteVpc",
"ec2:DescribeAddresses",
"ec2:DescribeAddressesAttribute",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstanceTypes",
"ec2:DescribeInternetGateways",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeNatGateways",
"ec2:DescribeNetworkAcls",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribePlacementGroups",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcs",
"ec2:DetachInternetGateway",
"ec2:DetachVolume",
"ec2:DisassociateAddress",
"ec2:DisassociateRouteTable",
"ec2:GetEbsDefaultKmsKeyId",
"ec2:GetEbsEncryptionByDefault",
"ec2:GetInstanceMetadataDefaults",
"ec2:GetInstanceTypesFromInstanceRequirements",
"ec2:GetSecurityGroupsForVpc",
"ec2:ModifyLaunchTemplate",
"ec2:ModifySubnetAttribute",
"ec2:ModifyVpcAttribute",
"ec2:ReleaseAddress",
"ec2:ReplaceRoute",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RunInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
]
resources = ["*"]
}
}
data "aws_iam_policy_document" "deployer_autoscaling" {
statement {
effect = "Allow"
actions = [
"autoscaling:UpdateAutoScalingGroup",
"autoscaling:DetachInstances",
"autoscaling:DescribeTags",
"autoscaling:DescribeScalingActivities",
"autoscaling:DescribePolicies",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DeletePolicy",
"autoscaling:DeleteLaunchConfiguration",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:CreateLaunchConfiguration",
"autoscaling:CreateAutoScalingGroup",
"autoscaling:AttachInstances"
]
resources = ["*"]
}
}
data "aws_iam_policy_document" "deployer_aux" {
statement {
effect = "Allow"
actions = [
"kms:CreateAlias",
"kms:CreateGrant",
"kms:CreateKey",
"kms:DeleteAlias",
"kms:EnableKeyRotation",
"kms:ListAliases",
"kms:ScheduleKeyDeletion",
"kms:TagResource",
]
resources = ["*"]
}
statement {
effect = "Allow"
actions = [
"iam:AttachRolePolicy",
"iam:CreateOpenIDConnectProvider",
"iam:CreatePolicy",
"iam:CreateRole",
"iam:CreateServiceLinkedRole",
"iam:DeleteOpenIDConnectProvider",
"iam:DeletePolicy",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:GetOpenIDConnectProvider",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListAttachedRolePolicies",
"iam:ListInstanceProfiles",
"iam:ListInstanceProfilesForRole",
"iam:ListOpenIDConnectProviders",
"iam:ListPolicies",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:ListRoles",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:TagOpenIDConnectProvider",
"iam:TagPolicy",
"iam:TagRole",
]
resources = ["*"]
}
statement {
effect = "Allow"
actions = [
"logs:CreateLogGroup",
"logs:DeleteLogGroup",
"logs:DescribeLogGroups",
"logs:ListTagsForResource",
"logs:PutRetentionPolicy",
"logs:TagResource",
]
resources = ["*"]
}
statement {
effect = "Allow"
actions = [
"ssm:GetParameter",
]
resources = ["arn:aws:ssm:*:*:parameter/aws/service/eks/optimized-ami/*"]
}
}
# Merge all policy docs together
data "aws_iam_policy_document" "combined_policy_documents" {
source_policy_documents = [
data.aws_iam_policy_document.deployer_eks.json,
data.aws_iam_policy_document.deployer_ec2.json,
data.aws_iam_policy_document.deployer_autoscaling.json,
data.aws_iam_policy_document.deployer_aux.json
]
}
resource "aws_iam_role_policy" "gamefabric_operators" {
name = "gamefabric-operators"
role = aws_iam_role.gamefabric_operators.id
policy = data.aws_iam_policy_document.combined_policy_documents.json
}Using wildcard permissions in policies
It is possible to use wildcards in the statements instead of lists of explicit permissions, e.g. eks:* or ec2:*. Using a wildcard may grant additional permissions to the role that are not needed but can create highly-privileged principals. From a security perspective, we recommend granting the explicit permissions.
You may take steps to add constraints and permission boundaries, but note that this can impact our ability to provision, maintain, or deprovision your cloud clusters.
After creating the policies, attach them to the created role. Navigate to the Role, select the Permissions tab, and click Add permissions > Attach policies. Select the newly created policies, and confirm with Add permissions.
Confirming the delegation setup
After completing the steps above, contact Nitrado and provide us with the ARN of the role you created. We need it to validate the setup and access your account.