-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(gamelift): add Build L2 constructs for GameLift #22313
Changes from 4 commits
ca35900
b9fc99d
65f63c4
4198d32
e2cb700
a782433
efd89d0
39699ac
c630331
fd85aa8
53d4263
fe4be27
6f24103
23c3f3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import * as s3 from '@aws-cdk/aws-s3'; | ||
import * as s3_assets from '@aws-cdk/aws-s3-assets'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import { Construct } from 'constructs'; | ||
import { Content } from './content'; | ||
import { CfnBuild } from './gamelift.generated'; | ||
|
||
/** | ||
* Represents a GameLift server build. | ||
*/ | ||
export interface IBuild extends cdk.IResource, iam.IGrantable { | ||
|
||
/** | ||
* The Identifier of the build. | ||
* | ||
* @attribute | ||
*/ | ||
readonly buildId: string; | ||
} | ||
|
||
/** | ||
* Base class for new and imported GameLift server build. | ||
*/ | ||
export abstract class BuildBase extends cdk.Resource implements IBuild { | ||
/** | ||
* The Identifier of the build. | ||
*/ | ||
public abstract readonly buildId: string; | ||
|
||
public abstract readonly grantPrincipal: iam.IPrincipal; | ||
} | ||
|
||
/** | ||
* The operating system that the game server binaries are built to run on. | ||
*/ | ||
export enum OperatingSystem { | ||
AMAZON_LINUX = 'AMAZON_LINUX', | ||
AMAZON_LINUX_2 = 'AMAZON_LINUX_2', | ||
WINDOWS_2012 = 'WINDOWS_2012' | ||
} | ||
|
||
|
||
/** | ||
* Represents a Build content defined outside of this stack. | ||
*/ | ||
export interface BuildAttributes { | ||
/** | ||
* The identifier of the build | ||
*/ | ||
readonly buildId: string; | ||
/** | ||
* The IAM role assumed by GameLift to access server build in S3. | ||
* @default - undefined | ||
*/ | ||
readonly role?: iam.IRole; | ||
} | ||
|
||
/** | ||
* Properties for a new build | ||
*/ | ||
export interface BuildProps { | ||
/** | ||
* Name of this build | ||
* | ||
* @default No name | ||
*/ | ||
readonly buildName?: string; | ||
|
||
/** | ||
* Version of this build | ||
* | ||
* @default No version | ||
*/ | ||
readonly buildVersion?: string; | ||
|
||
/** | ||
* The operating system that the game server binaries are built to run on. | ||
* | ||
* @default No version | ||
*/ | ||
readonly operatingSystem?: OperatingSystem; | ||
|
||
/** | ||
* The game build file storage | ||
*/ | ||
readonly content: Content; | ||
|
||
/** | ||
* The IAM role assumed by GameLift to access server build in S3. | ||
* If providing a custom role, it needs to trust the GameLift service principal (gamelift.amazonaws.com) and be granted sufficient permissions. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please explain to the user which permissions are sufficient. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have improved documentation and added a required policy sample |
||
* | ||
* @see https://docs.aws.amazon.com/gamelift/latest/developerguide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-access-storage-loc | ||
* | ||
* @default - a role will be created with default permissions. | ||
*/ | ||
readonly role?: iam.IRole; | ||
} | ||
|
||
/** | ||
* Create a GameLift server build | ||
* | ||
* @resource AWS::GameLift::Build | ||
*/ | ||
export class Build extends BuildBase { | ||
|
||
/** | ||
* Create a new Build from s3 content | ||
*/ | ||
static fromBucket(scope: Construct, id: string, bucket: s3.IBucket, key: string, objectVersion?: string) { | ||
return new Build(scope, id, { | ||
content: Content.fromBucket(bucket, key, objectVersion), | ||
}); | ||
} | ||
|
||
/** | ||
* Create a new Build from asset content | ||
*/ | ||
static fromAsset(scope: Construct, id: string, path: string, options?: s3_assets.AssetOptions) { | ||
return new Build(scope, id, { | ||
content: Content.fromAsset(path, options), | ||
}); | ||
} | ||
|
||
/** | ||
* Import a build into CDK using its identifier | ||
*/ | ||
static fromBuildId(scope: Construct, id: string, buildId: string): IBuild { | ||
return this.fromBuildAttributes(scope, id, { buildId }); | ||
} | ||
|
||
/** | ||
* Import an existing build from its attributes. | ||
*/ | ||
static fromBuildAttributes(scope: Construct, id: string, attrs: BuildAttributes): IBuild { | ||
class Import extends BuildBase { | ||
public readonly buildId = attrs.buildId; | ||
public readonly grantPrincipal = attrs.role ?? new iam.UnknownPrincipal({ resource: this }); | ||
} | ||
|
||
return new Import(scope, id); | ||
} | ||
|
||
/** | ||
* The Identifier of the build. | ||
*/ | ||
public readonly buildId: string; | ||
|
||
/** | ||
* The IAM role GameLift assumes to acccess server build content. | ||
*/ | ||
public readonly role: iam.IRole; | ||
|
||
/** | ||
* The principal this GameLift Build is using. | ||
*/ | ||
public readonly grantPrincipal: iam.IPrincipal; | ||
|
||
constructor(scope: Construct, id: string, props: BuildProps) { | ||
super(scope, id, { | ||
physicalName: props.buildName, | ||
}); | ||
|
||
if (props.buildName) { | ||
stevehouel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (props.buildName.length > 1024) { | ||
throw new Error(`Build name can not be longer than 1024 characters but has ${props.buildName.length} characters.`); | ||
} | ||
} | ||
this.role = props.role ?? new iam.Role(this, 'ServiceRole', { | ||
assumedBy: new iam.ServicePrincipal('gamelift.amazonaws.com'), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to confirm: you don't need to pass any policies? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am granting read access to for an S3 bucket + dedicated content key on binding phase for a content (see content.ts on bind methods) but otherwise no specific needs here or any specific policy |
||
}); | ||
this.grantPrincipal = this.role; | ||
const content = props.content.bind(this, this.role); | ||
|
||
const resource = new CfnBuild(this, 'Resource', { | ||
name: props.buildName, | ||
version: props.buildVersion, | ||
operatingSystem: props.operatingSystem, | ||
storageLocation: { | ||
bucket: content.s3Location && content.s3Location.bucketName, | ||
key: content.s3Location && content.s3Location.objectKey, | ||
objectVersion: content.s3Location && content.s3Location.objectVersion, | ||
roleArn: this.role.roleArn, | ||
}, | ||
}); | ||
|
||
this.buildId = resource.ref; | ||
} | ||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section is about server builds, but there is no mention of anything called "build" in this paragraph.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
documentation has been updated