Configuring your Cloud Provider
This document describes the steps required to set up your Cloud provider for use with GameFabric. Currently supported Cloud providers are Google Cloud (GCP), Azure, and Amazon Web Services (AWS).
Public documentation is currently limited to Google Cloud. For setup instructions for other Cloud providers, please contact your Nitrado Account Manager.
Google Cloud
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 will be 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 User
Billing Account Viewer
Confirming the setup
After you have completed the steps above, please contact Nitrado to confirm that the setup is complete.
Amazon Web Services
Prerequisites
- You must already have an existing AWS account
- You must possess the necessary permissions to create IAM resources in your account
Background
For AWS, to access another organization, you have to setup a chain of roles. Roles are AWS objects that allow scoping permissions. Roles are assumable by principals. Principals are arbitrary entities operating AWS, and specifically, users or groups of users. This setup allows you to delegate game server cluster management to Gamefabric operators by creating a role that is fine-grained to provision resources without having to grant broad access to their organization.
By chaining those roles together (i.e., allowing a role to assume another role), Gamefabric operators can access your organization/account, as long as the chain of Trust Relationship is not broken.
For setting this up, we recommend using a tool like Terraform, as it allows you to simply declare the desired resources. Particularly for configuring various policy documents, this will be helpful. We'll use Terraform in the following. You can adapt this guide and do the following steps manually.
Creating the Role and Assumption Policy
Create an IAM Role and the appropriate role assumption policy using Terraform:
variable "source_saml_principal_arn" {
type = string
description = "ARN of the principal backing the SAML authentication for SSO users from the source account"
default = "arn:aws:iam::339712714940:saml-provider/AWSSSO_5495e4acbcad9a8a_DO_NOT_DELETE"
}
variable "source_role_arn" {
type = string
description = "ARN of the role in the source account to trust"
default = "arn:aws:iam::339712714940:role/gamefabric-operators"
}
resource "aws_iam_role" "gamefabric_operators" {
name = "gamefabric-operators"
assume_role_policy = data.aws_iam_role_policy.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 = [var.source_saml_principal_arn]
}
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 = [ var.source_role_arn ]
}
}
}
output "role_arn" {
value = aws_iam_role.gamefabric_operators.arn
}
The defaults for the variables are linking to the Gamefabric AWS account, specifically, the account ID 339712714940
belongs to the Gamefabric organization. The two ARNs link to the role and the respective SAML provider on our end (see the graphic above).
Creating Policies for Resource Management
Create several IAM policy documents that grant access
data "aws_iam_policy_document" "deployer_eks" {
statement {
effect = "Allow"
actions = [
"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:DescribeNodegroup",
"eks:DescribeUpdate",
"eks:DisassociateAccessPolicy",
"eks:ListAddons",
"eks:ListAssociatedAccessPolicies",
"eks:ListClusters",
"eks:ListNodegroups",
"eks:ListUpdates",
"eks:UpdateNodegroupConfig",
"eks:UpdateNodegroupVersion",
"eks:TagResource",
]
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:CreateNatGateway",
"ec2:CreateNetworkAclEntry",
"ec2:CreateRoute",
"ec2:CreateRouteTable",
"ec2:CreateSecurityGroup",
"ec2:CreateSubnet",
"ec2:CreateVpc",
"ec2:DeleteInternetGateway",
"ec2:DeleteNatGateway",
"ec2:DeleteNetworkAclEntry",
"ec2:DeleteRoute",
"ec2:DeleteRouteTable",
"ec2:DeleteSecurityGroup",
"ec2:DeleteSubnet",
"ec2:DeleteVpc",
"ec2:DescribeAddresses",
"ec2:DescribeAddressesAttribute",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeInternetGateways",
"ec2:DescribeNatGateways",
"ec2:DescribeNetworkAcls",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribePlacementGroups",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcs",
"ec2:DetachInternetGateway",
"ec2:DisassociateAddress",
"ec2:DisassociateRouteTable",
"ec2:GetEbsDefaultKmsKeyId",
"ec2:GetEbsEncryptionByDefault",
"ec2:GetInstanceMetadataDefaults",
"ec2:GetInstanceTypesFromInstanceRequirements",
"ec2:GetSecurityGroupsForVpc",
"ec2:ModifySubnetAttribute",
"ec2:ModifyVpcAttribute",
"ec2:ReleaseAddress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DescribeTags",
]
resources = ["*"]
}
}
data "aws_iam_policy_document" "deployer_autoscaling" {
statement {
effect = "Allow"
actions = [
"autoscaling:AttachRolePolicy",
"autoscaling:CreateOpenIDConnectProvider",
"autoscaling:CreatePolicy",
"autoscaling:CreateRole",
"autoscaling:DeleteOpenIDConnectProvider",
"autoscaling:DeletePolicy",
"autoscaling:DeleteRole",
"autoscaling:DeleteRolePolicy",
"autoscaling:DetachRolePolicy",
"autoscaling:GetOpenIDConnectProvider",
"autoscaling:PutRolePolicy"
]
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:DeleteOpenIDConnectProvider",
"iam:DeletePolicy",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:GetOpenIDConnectProvider",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListInstanceProfiles",
"iam:ListInstanceProfilesForRole",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:PutRolePolicy",
"iam:TagRole",
"iam:TagPolicy",
"iam:ListAttachedRolePolicies",
"iam:PassRole",
"iam:TagOpenIDConnectProvider",
"iam:ListOpenIDConnectProviders",
]
resources = ["*"]
}
statement {
effect = "Allow"
actions = [
"logs:CreateLogGroup",
"logs:DescribeLogGroups",
"logs:ListTagsForResource",
"logs:PutRetentionPolicy",
"logs:TagResource",
"logs:DeleteLogGroup",
]
resources = ["*"]
}
}
# 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
}
Policy Document Size Restrictions
AWS encodes their policy documents in JSON, and restricts the size of these documents rather strictly 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.
Confirming the setup
After you have completed the steps above, please contact Nitrado to confirm that the setup is complete, and provide us with the ARN of the role you created previously, as we need it on our end to access your account.