Skip to content

Commit ea4ab3b

Browse files
authored
feat(aws-lambda-sagemakerendpoint): new pattern aws-lambda-sagemakerendpoint implementation (#112)
* add SAGEMAKER.RUN_TIME interfrace endpoint * add SAGEMAKER_RUNTIME VPC Interface * add SageMaker endpoint default properties * add SageMaker endpoint helper functions * add aws-lambda-sagemakerendpoint pattern with all tests * fix lint indentation * remove commented line * remove unnecessary added function * add @aws-cdk/aws-iam to dependencies * fix original format change in vpc-helper.ts * fix subnets cidrMask for deployNatGateway=true * fix a typo in sagemaker-helper.ts * update unit/integ test aws-lambda-sagemakerendpoint * fix spaces in lambda example * update vpc-helper.ts unittest * update .viperlightignore * update sagemaker-helper.ts unittests * update lambda-sagemakerendpint unit/integ tests * re-arrange dependencies * change vpc? to ec2.IVpc * update unittests * update package.json * update READ.md * change SageMaker -> Sagemaker * remove .js files from .viperlightignore * fix typo README.md construct import * fix typo README.md * restore package.json for aws-apigateway-sagemakerendpoint * fix a typo in sagemaker-helper.ts * fix typos and and SAGMAKER to env variable * fix typos in README.md * add SAGENAKER to lambda's env variable * change any to modelProps? * add Sagemaker Role permissions * add logic to use user provide role or create one * adjust to new defaultVpcPros and remove deployNatGateWay flag * adjust sagemaker internal role * adjust sagemaker helper unittests * adjust lambda-sagemakerendpoint unittests * update README.md * update construct index.ts * update sagemaker-helper.ts * update README.md * update construct unit and integration tests * update sagemaker-helper.ts unittests * clean commented code in unittests * update aws-lambda-sagemakerendpoint unittest * update aws-lambda-sagemakerendpoint integ * update sagemaker-heper unittest * update sagemaker-heper snap * update sagemaker-heper.ts * update README.md * update index.ts * fix custom role integration test * revert back to fix cfn_nag issue for kmsKeyId * update README.md * update release version * update unittest for the construct to reflect v1.87 changes Co-authored-by: Tarek Abdunabi <[email protected]>
1 parent f4b22d8 commit ea4ab3b

28 files changed

+13029
-720
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
lib/*.js
2+
test/*.js
3+
*.d.ts
4+
coverage
5+
test/lambda/index.js
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
lib/*.js
2+
test/*.js
3+
*.js.map
4+
*.d.ts
5+
node_modules
6+
*.generated.ts
7+
dist
8+
.jsii
9+
10+
.LAST_BUILD
11+
.nyc_output
12+
coverage
13+
.nycrc
14+
.LAST_PACKAGE
15+
*.snk
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Exclude typescript source and config
2+
*.ts
3+
tsconfig.json
4+
coverage
5+
.nyc_output
6+
*.tgz
7+
*.snk
8+
*.tsbuildinfo
9+
10+
# Include javascript files and typescript declarations
11+
!*.js
12+
!*.d.ts
13+
14+
# Exclude jsii outdir
15+
dist
16+
17+
# Include .jsii
18+
!.jsii
19+
20+
# Include .jsii
21+
!.jsii

source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint/README.md

+125
Large diffs are not rendered by default.
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
5+
* with the License. A copy of the License is located at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
10+
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
11+
* and limitations under the License.
12+
*/
13+
14+
import * as cdk from '@aws-cdk/core';
15+
import * as lambda from '@aws-cdk/aws-lambda';
16+
import * as ec2 from '@aws-cdk/aws-ec2';
17+
import * as iam from '@aws-cdk/aws-iam';
18+
import * as sagemaker from '@aws-cdk/aws-sagemaker';
19+
import * as defaults from '@aws-solutions-constructs/core';
20+
21+
/**
22+
* @summary The properties for the LambdaToSagemakerEndpoint class
23+
*/
24+
export interface LambdaToSagemakerEndpointProps {
25+
/**
26+
* Existing instance of Lambda Function object, if this is set then the lambdaFunctionProps is ignored
27+
*
28+
* @default - None
29+
*/
30+
readonly existingLambdaObj?: lambda.Function;
31+
/**
32+
* User provided props to override the default props for the Lambda function
33+
*
34+
* @default - Default props are used
35+
*/
36+
readonly lambdaFunctionProps?: lambda.FunctionProps;
37+
/**
38+
* Existing Sagemaker Enpoint object, if this is set then the modelProps, endpointConfigProps, and endpointProps are ignored
39+
*
40+
* @default - None
41+
*/
42+
readonly existingSagemakerEndpointObj?: sagemaker.CfnEndpoint;
43+
/**
44+
* User provided props to create Sagemaker Model
45+
*
46+
* @default - None
47+
*/
48+
readonly modelProps?: sagemaker.CfnModelProps | any;
49+
/**
50+
* User provided props to create Sagemaker Endpoint Configuration
51+
*
52+
* @default - Default props are used
53+
*/
54+
readonly endpointConfigProps?: sagemaker.CfnEndpointConfigProps;
55+
/**
56+
* User provided props to create Sagemaker Endpoint
57+
*
58+
* @default - Default props are used
59+
*/
60+
readonly endpointProps?: sagemaker.CfnEndpointProps;
61+
/**
62+
* An existing VPC for the construct to use (construct will NOT create a new VPC in this case)
63+
*
64+
* @default - None
65+
*/
66+
readonly existingVpc?: ec2.IVpc;
67+
/**
68+
* Properties to override default properties if deployVpc is true
69+
*
70+
* @default - None
71+
*/
72+
readonly vpcProps?: ec2.VpcProps;
73+
/**
74+
* Whether to deploy a new VPC
75+
*
76+
* @default - false
77+
*/
78+
readonly deployVpc?: boolean;
79+
}
80+
81+
/**
82+
* @summary The LambdaToSagemakerEndpoint class.
83+
*/
84+
export class LambdaToSagemakerEndpoint extends cdk.Construct {
85+
public readonly lambdaFunction: lambda.Function;
86+
public readonly sagemakerEndpoint: sagemaker.CfnEndpoint;
87+
public readonly sagemakerEndpointConfig?: sagemaker.CfnEndpointConfig;
88+
public readonly sagemakerModel?: sagemaker.CfnModel;
89+
public readonly vpc?: ec2.IVpc;
90+
91+
/**
92+
* @summary Constructs a new instance of the LambdaToSagemakerEndpoint class.
93+
* @param {cdk.App} scope - represents the scope for all the resources.
94+
* @param {string} id - this is a scope-unique id.
95+
* @param {LambdaToSagemakerEndpointProps} props - user provided props for the construct.
96+
* @since 1.87.1
97+
* @access public
98+
*/
99+
constructor(scope: cdk.Construct, id: string, props: LambdaToSagemakerEndpointProps) {
100+
super(scope, id);
101+
102+
if (props.deployVpc || props.existingVpc) {
103+
if (props.deployVpc && props.existingVpc) {
104+
throw new Error('More than 1 VPC specified in the properties');
105+
}
106+
107+
// create the VPC
108+
this.vpc = defaults.buildVpc(scope, {
109+
defaultVpcProps: defaults.DefaultIsolatedVpcProps(),
110+
existingVpc: props.existingVpc,
111+
userVpcProps: props.vpcProps,
112+
constructVpcProps: {
113+
enableDnsHostnames: true,
114+
enableDnsSupport: true,
115+
},
116+
});
117+
118+
// Add S3 VPC Gateway Endpoint, required by Sagemaker to access Models artifacts via AWS private network
119+
defaults.AddAwsServiceEndpoint(scope, this.vpc, defaults.ServiceEndpointTypes.S3);
120+
// Add SAGEMAKER_RUNTIME VPC Interface Endpoint, required by the lambda function to invoke the Sagemaker endpoint
121+
defaults.AddAwsServiceEndpoint(scope, this.vpc, defaults.ServiceEndpointTypes.SAGEMAKER_RUNTIME);
122+
}
123+
124+
// Build Sagemaker Endpoint (inclduing Sagemaker's Endpoint Configuration and Model)
125+
[this.sagemakerEndpoint, this.sagemakerEndpointConfig, this.sagemakerModel] = defaults.BuildSagemakerEndpoint(
126+
this,
127+
{
128+
...props,
129+
vpc: this.vpc,
130+
}
131+
);
132+
133+
// Setup the Lambda function
134+
this.lambdaFunction = defaults.buildLambdaFunction(this, {
135+
existingLambdaObj: props.existingLambdaObj,
136+
lambdaFunctionProps: props.lambdaFunctionProps,
137+
vpc: this.vpc,
138+
});
139+
140+
// Add SAGEMAKER_ENDPOINT_NAME environment variable
141+
this.lambdaFunction.addEnvironment('SAGEMAKER_ENDPOINT_NAME', this.sagemakerEndpoint.attrEndpointName);
142+
143+
// Add permission to invoke the SageMaker endpoint
144+
this.lambdaFunction.addToRolePolicy(
145+
new iam.PolicyStatement({
146+
actions: ['sagemaker:InvokeEndpoint'],
147+
resources: [this.sagemakerEndpoint.ref],
148+
})
149+
);
150+
}
151+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"name": "@aws-solutions-constructs/aws-lambda-sagemakerendpoint",
3+
"version": "0.0.0",
4+
"description": "CDK constructs for defining an interaction between an AWS Lambda function and an Amazon SageMaker inference endpoint.",
5+
"main": "lib/index.js",
6+
"types": "lib/index.d.ts",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/awslabs/aws-solutions-constructs.git",
10+
"directory": "source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint"
11+
},
12+
"author": {
13+
"name": "Amazon Web Services",
14+
"url": "https://aws.amazon.com",
15+
"organization": true
16+
},
17+
"license": "Apache-2.0",
18+
"scripts": {
19+
"build": "tsc -b .",
20+
"lint": "eslint -c ../eslintrc.yml --ext=.js,.ts . && tslint --project .",
21+
"lint-fix": "eslint -c ../eslintrc.yml --ext=.js,.ts --fix .",
22+
"test": "jest --coverage",
23+
"clean": "tsc -b --clean",
24+
"watch": "tsc -b -w",
25+
"integ": "cdk-integ",
26+
"integ-assert": "cdk-integ-assert",
27+
"integ-no-clean": "cdk-integ --no-clean",
28+
"jsii": "jsii",
29+
"jsii-pacmak": "jsii-pacmak",
30+
"build+lint+test": "npm run jsii && npm run lint && npm test && npm run integ-assert",
31+
"snapshot-update": "npm run jsii && npm test -- -u && npm run integ-assert"
32+
},
33+
"jsii": {
34+
"outdir": "dist",
35+
"targets": {
36+
"java": {
37+
"package": "software.amazon.awsconstructs.services.lambdasagemakerendpoint",
38+
"maven": {
39+
"groupId": "software.amazon.awsconstructs",
40+
"artifactId": "lambdasqs"
41+
}
42+
},
43+
"dotnet": {
44+
"namespace": "Amazon.Constructs.AWS.LambdaSagemakerEndpoint",
45+
"packageId": "Amazon.Constructs.AWS.LambdaSagemakerEndpoint",
46+
"signAssembly": true,
47+
"iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
48+
},
49+
"python": {
50+
"distName": "aws-solutions-constructs.aws-lambda-sagemakerendpoint",
51+
"module": "aws_solutions_constructs.aws_lambda_sagemakerendpoint"
52+
}
53+
}
54+
},
55+
"dependencies": {
56+
"@aws-cdk/aws-ec2": "0.0.0",
57+
"@aws-cdk/aws-iam": "0.0.0",
58+
"@aws-cdk/aws-lambda": "0.0.0",
59+
"@aws-cdk/aws-sagemaker": "0.0.0",
60+
"@aws-cdk/core": "0.0.0",
61+
"@aws-solutions-constructs/core": "0.0.0",
62+
"constructs": "^3.2.0"
63+
},
64+
"devDependencies": {
65+
"@aws-cdk/assert": "0.0.0",
66+
"@types/jest": "^24.0.23",
67+
"@types/node": "^10.3.0"
68+
},
69+
"jest": {
70+
"moduleFileExtensions": [
71+
"js"
72+
]
73+
},
74+
"peerDependencies": {
75+
"@aws-cdk/aws-ec2": "0.0.0",
76+
"@aws-cdk/aws-iam": "0.0.0",
77+
"@aws-cdk/aws-lambda": "0.0.0",
78+
"@aws-cdk/aws-sagemaker": "0.0.0",
79+
"@aws-cdk/core": "0.0.0",
80+
"@aws-solutions-constructs/core": "0.0.0",
81+
"constructs": "^3.2.0"
82+
}
83+
}

0 commit comments

Comments
 (0)