-
Notifications
You must be signed in to change notification settings - Fork 4k
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 Script L2 Construct for GameLift #22343
Merged
Merged
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
a2e9c15
feat(gamelift): add Script L2 Construct for GameLift
stevehouel e9cb52a
fix gitignore to add script js file for testing
stevehouel 5145dfc
add missing js file
stevehouel f8fa751
Merge branch 'main' into houes/rfc-436-script
stevehouel edabe7a
Merge branch 'main' into houes/rfc-436-script
stevehouel 1af60f6
Updating IBuild and IScript documentation
stevehouel 0982517
Fix documentation links
stevehouel 6b0686d
Merge branch 'main' into houes/rfc-436-script
mergify[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
export * from './content'; | ||
export * from './build'; | ||
export * from './script'; | ||
|
||
// AWS::GameLift CloudFormation Resources: | ||
export * from './gamelift.generated'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
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 { CfnScript } from './gamelift.generated'; | ||
|
||
/** | ||
* Represents a GameLift realtime server script. | ||
*/ | ||
export interface IScript extends cdk.IResource, iam.IGrantable { | ||
|
||
/** | ||
* The Identifier of the realtime server script. | ||
* | ||
* @attribute | ||
*/ | ||
readonly scriptId: string; | ||
|
||
/** | ||
* The ARN of the realtime server script. | ||
* | ||
* @attribute | ||
*/ | ||
readonly scriptArn: string; | ||
} | ||
|
||
/** | ||
* Base class for new and imported GameLift realtime server script. | ||
*/ | ||
export abstract class ScriptBase extends cdk.Resource implements IScript { | ||
/** | ||
* The Identifier of the realtime server script. | ||
*/ | ||
public abstract readonly scriptId: string; | ||
public abstract readonly scriptArn: string; | ||
|
||
public abstract readonly grantPrincipal: iam.IPrincipal; | ||
} | ||
|
||
/** | ||
* Represents a Script content defined outside of this stack. | ||
*/ | ||
export interface ScriptAttributes { | ||
/** | ||
* The ARN of the realtime server script | ||
*/ | ||
readonly scriptArn: string; | ||
/** | ||
* The IAM role assumed by GameLift to access server script in S3. | ||
* @default - undefined | ||
*/ | ||
readonly role?: iam.IRole; | ||
} | ||
|
||
/** | ||
* Properties for a new realtime server script | ||
*/ | ||
export interface ScriptProps { | ||
/** | ||
* Name of this realtime server script | ||
* | ||
* @default No name | ||
*/ | ||
readonly scriptName?: string; | ||
|
||
/** | ||
* Version of this realtime server script | ||
* | ||
* @default No version | ||
*/ | ||
readonly scriptVersion?: string; | ||
|
||
/** | ||
* The game content | ||
*/ | ||
readonly content: Content; | ||
|
||
/** | ||
* The IAM role assumed by GameLift to access server script in S3. | ||
* If providing a custom role, it needs to trust the GameLift service principal (gamelift.amazonaws.com) and be granted sufficient permissions | ||
* to have Read access to a specific key content into a specific S3 bucket. | ||
* Below an example of required permission: | ||
* { | ||
* "Version": "2012-10-17", | ||
* "Statement": [{ | ||
* "Effect": "Allow", | ||
* "Action": [ | ||
* "s3:GetObject", | ||
* "s3:GetObjectVersion" | ||
* ], | ||
* "Resource": "arn:aws:s3:::bucket-name/object-name" | ||
* }] | ||
*} | ||
* | ||
* @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; | ||
} | ||
|
||
/** | ||
* A GameLift script, that is installed and runs on instances in an Amazon GameLift fleet. It consists of | ||
* a zip file with all of the components of the realtime game server script. | ||
* | ||
* @see https://docs.aws.amazon.com/gamelift/latest/developerguide/realtime-script-uploading.html | ||
* | ||
* @resource AWS::GameLift::Script | ||
*/ | ||
export class Script extends ScriptBase { | ||
|
||
/** | ||
* Create a new realtime server script from s3 content | ||
*/ | ||
static fromBucket(scope: Construct, id: string, bucket: s3.IBucket, key: string, objectVersion?: string) { | ||
return new Script(scope, id, { | ||
content: Content.fromBucket(bucket, key, objectVersion), | ||
}); | ||
} | ||
|
||
/** | ||
* Create a new realtime server script from asset content | ||
*/ | ||
static fromAsset(scope: Construct, id: string, path: string, options?: s3_assets.AssetOptions) { | ||
return new Script(scope, id, { | ||
content: Content.fromAsset(path, options), | ||
}); | ||
} | ||
|
||
/** | ||
* Import a script into CDK using its ARN | ||
*/ | ||
static fromScriptArn(scope: Construct, id: string, scriptArn: string): IScript { | ||
return this.fromScriptAttributes(scope, id, { scriptArn }); | ||
} | ||
|
||
/** | ||
* Import an existing realtime server script from its attributes. | ||
*/ | ||
static fromScriptAttributes(scope: Construct, id: string, attrs: ScriptAttributes): IScript { | ||
const scriptArn = attrs.scriptArn; | ||
const scriptId = extractIdFromArn(attrs.scriptArn); | ||
const role = attrs.role; | ||
|
||
class Import extends ScriptBase { | ||
public readonly scriptArn = scriptArn; | ||
public readonly scriptId = scriptId; | ||
public readonly grantPrincipal:iam.IPrincipal; | ||
public readonly role = role | ||
|
||
constructor(s: Construct, i: string) { | ||
super(s, i, { | ||
environmentFromArn: scriptArn, | ||
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. Where is this used? 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. Not really used yet but I wanted to ensure Script env was linked to information provide as parameter (here the ARN) |
||
}); | ||
|
||
this.grantPrincipal = this.role || new iam.UnknownPrincipal({ resource: this }); | ||
} | ||
} | ||
|
||
return new Import(scope, id); | ||
} | ||
|
||
/** | ||
* The Identifier of the realtime server script. | ||
*/ | ||
public readonly scriptId: string; | ||
|
||
/** | ||
* The ARN of the realtime server script. | ||
*/ | ||
public readonly scriptArn: string; | ||
|
||
/** | ||
* The IAM role GameLift assumes to acccess server script content. | ||
*/ | ||
public readonly role: iam.IRole; | ||
|
||
/** | ||
* The principal this GameLift script is using. | ||
*/ | ||
public readonly grantPrincipal: iam.IPrincipal; | ||
|
||
constructor(scope: Construct, id: string, props: ScriptProps) { | ||
super(scope, id, { | ||
physicalName: props.scriptName, | ||
}); | ||
|
||
if (props.scriptName && !cdk.Token.isUnresolved(props.scriptName)) { | ||
if (props.scriptName.length > 1024) { | ||
throw new Error(`Script name can not be longer than 1024 characters but has ${props.scriptName.length} characters.`); | ||
} | ||
} | ||
this.role = props.role ?? new iam.Role(this, 'ServiceRole', { | ||
assumedBy: new iam.ServicePrincipal('gamelift.amazonaws.com'), | ||
}); | ||
this.grantPrincipal = this.role; | ||
const content = props.content.bind(this, this.role); | ||
|
||
const resource = new CfnScript(this, 'Resource', { | ||
name: props.scriptName, | ||
version: props.scriptVersion, | ||
storageLocation: { | ||
bucket: content.s3Location && content.s3Location.bucketName, | ||
key: content.s3Location && content.s3Location.objectKey, | ||
objectVersion: content.s3Location && content.s3Location.objectVersion, | ||
roleArn: this.role.roleArn, | ||
}, | ||
}); | ||
|
||
this.scriptId = this.getResourceNameAttribute(resource.ref); | ||
this.scriptArn = this.getResourceArnAttribute(resource.attrArn, { | ||
service: 'gamelift', | ||
resource: `script/${this.physicalName}`, | ||
arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME, | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Given an opaque (token) ARN, returns a CloudFormation expression that extracts the script | ||
* identifier from the ARN. | ||
* | ||
* Script ARNs look like this: | ||
* | ||
* arn:aws:gamelift:region:account-id:script/script-identifier | ||
* | ||
* ..which means that in order to extract the `script-identifier` component from the ARN, we can | ||
* split the ARN using ":" and select the component in index 5 then split using "/" and select the component in index 1. | ||
* | ||
* @returns the script identifier from his ARN | ||
*/ | ||
function extractIdFromArn(arn: string) { | ||
const splitValue = cdk.Fn.select(5, cdk.Fn.split(':', arn)); | ||
return cdk.Fn.select(1, cdk.Fn.split('/', splitValue)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import * as path from 'path'; | ||
import * as cdk from '@aws-cdk/core'; | ||
import * as gamelift from '../lib'; | ||
|
||
const app = new cdk.App(); | ||
|
||
const stack = new cdk.Stack(app, 'aws-gamelift-script'); | ||
|
||
new gamelift.Script(stack, 'Script', { | ||
content: gamelift.Content.fromAsset(path.join(__dirname, 'my-game-script')), | ||
}); | ||
|
||
app.synth(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
console.log('Hello World'); |
1 change: 1 addition & 0 deletions
1
....snapshot/asset.6019bfc8ab05a24b0ae9b5d8f4585cbfc7d1c30a23286d0b25ce7066a368a5d7/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
console.log('Hello World'); |
32 changes: 32 additions & 0 deletions
32
packages/@aws-cdk/aws-gamelift/test/script.integ.snapshot/aws-gamelift-script.assets.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"version": "21.0.0", | ||
"files": { | ||
"6019bfc8ab05a24b0ae9b5d8f4585cbfc7d1c30a23286d0b25ce7066a368a5d7": { | ||
"source": { | ||
"path": "asset.6019bfc8ab05a24b0ae9b5d8f4585cbfc7d1c30a23286d0b25ce7066a368a5d7", | ||
"packaging": "zip" | ||
}, | ||
"destinations": { | ||
"current_account-current_region": { | ||
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", | ||
"objectKey": "6019bfc8ab05a24b0ae9b5d8f4585cbfc7d1c30a23286d0b25ce7066a368a5d7.zip", | ||
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" | ||
} | ||
} | ||
}, | ||
"9c561e93c7a2947a15dba683670660e922cf493e17b2a6f8ca03cf221442c222": { | ||
"source": { | ||
"path": "aws-gamelift-script.template.json", | ||
"packaging": "file" | ||
}, | ||
"destinations": { | ||
"current_account-current_region": { | ||
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", | ||
"objectKey": "9c561e93c7a2947a15dba683670660e922cf493e17b2a6f8ca03cf221442c222.json", | ||
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" | ||
} | ||
} | ||
} | ||
}, | ||
"dockerImages": {} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I think the explanation from the "About" page communicates, in a short paragraph, what a script is:
I suggest you also copy the one for builds to the
Build
class.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.
Agreed. Update done