Skip to content

Commit 6491555

Browse files
committed
add aws-lambda-sagemakerendpoint pattern with all tests
1 parent b226001 commit 6491555

20 files changed

+11666
-0
lines changed
Lines changed: 5 additions & 0 deletions
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
Lines changed: 15 additions & 0 deletions
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
Lines changed: 21 additions & 0 deletions
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

Lines changed: 132 additions & 0 deletions
Large diffs are not rendered by default.
Loading
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/**
2+
* Copyright 2020 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;
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.Vpc;
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+
* Whether to deploy a natgatway in the new VPC (if deployVpc is true).
81+
* If deployNatGateway is true, the construct creates Public and Private subnets.
82+
* Otherwise, it creates Isolated subnets only
83+
*
84+
* @default - false
85+
*/
86+
readonly deployNatGateway?: boolean;
87+
/**
88+
* IAM Role, with all required permissions, to be assumed by SageMaker to create resources
89+
* The Role is not required if existingSageMakerEndpointObj is provided.
90+
*
91+
* @default - None
92+
*/
93+
readonly role?: iam.Role;
94+
}
95+
96+
/**
97+
* @summary The LambdaToSageMakerEndpoint class.
98+
*/
99+
export class LambdaToSageMakerEndpoint extends cdk.Construct {
100+
public readonly lambdaFunction: lambda.Function;
101+
public readonly sageMakerEndpoint: sagemaker.CfnEndpoint;
102+
public readonly sageMakerEndpointConfig?: sagemaker.CfnEndpointConfig;
103+
public readonly sageMakerModel?: sagemaker.CfnModel;
104+
public readonly vpc?: ec2.Vpc;
105+
106+
/**
107+
* @summary Constructs a new instance of the LambdaToSageMakerEndpoint class.
108+
* @param {cdk.App} scope - represents the scope for all the resources.
109+
* @param {string} id - this is a a scope-unique id.
110+
* @param {LambdaToSageMakerEndpointProps} props - user provided props for the construct.
111+
* @since 1.76.0
112+
* @access public
113+
*/
114+
constructor(scope: cdk.Construct, id: string, props: LambdaToSageMakerEndpointProps) {
115+
super(scope, id);
116+
117+
if (props.deployVpc || props.existingVpc) {
118+
if (props.deployVpc && props.existingVpc) {
119+
throw new Error('More than 1 VPC specified in the properties');
120+
}
121+
122+
// If deployNatGateway is true, create Public and Private subnets. Otherwise, create Isolated subnets only
123+
const subnetConfiguration: ec2.SubnetConfiguration[] = props.deployNatGateway
124+
? [
125+
{
126+
cidrMask: 18,
127+
name: 'Public',
128+
subnetType: ec2.SubnetType.PUBLIC,
129+
},
130+
{
131+
cidrMask: 18,
132+
name: 'Private',
133+
subnetType: ec2.SubnetType.PRIVATE,
134+
},
135+
]
136+
: [
137+
{
138+
cidrMask: 18,
139+
name: 'Isolated',
140+
subnetType: ec2.SubnetType.ISOLATED,
141+
},
142+
];
143+
144+
// create the VPC
145+
this.vpc = defaults.buildVpc(scope, {
146+
existingVpc: props.existingVpc,
147+
userVpcProps: props.vpcProps,
148+
constructVpcProps: {
149+
enableDnsHostnames: true,
150+
enableDnsSupport: true,
151+
// set # NatGateways to 2 if deployNatGateway is true. Otherwise, 0
152+
natGateways: props.deployNatGateway ? 2 : 0,
153+
subnetConfiguration,
154+
},
155+
});
156+
157+
// Add S3 VPC Gateway Endpint, required by SageMaker to access Models artifacts via AWS private network
158+
defaults.AddAwsServiceEndpoint(scope, this.vpc, defaults.ServiceEndpointTypes.S3);
159+
// Add SAGEMAKER_RUNTIME VPC Interface Endpint, required by the lambda function to invoke the SageMaker endpoint
160+
defaults.AddAwsServiceEndpoint(scope, this.vpc, defaults.ServiceEndpointTypes.SAGEMAKER_RUNTIME);
161+
}
162+
163+
// Build SageMaker Endpoint (inclduing SageMaker's Endpoint Configuration and Model)
164+
[this.sageMakerEndpoint, this.sageMakerEndpointConfig, this.sageMakerModel] = defaults.BuildSageMakerEndpoint(
165+
this,
166+
{
167+
...props,
168+
vpc: this.vpc,
169+
}
170+
);
171+
172+
// Setup the Lambda function
173+
this.lambdaFunction = defaults.buildLambdaFunction(this, {
174+
existingLambdaObj: props.existingLambdaObj,
175+
lambdaFunctionProps: props.lambdaFunctionProps,
176+
vpc: this.vpc,
177+
});
178+
179+
// Add ENDPOINT_NAME environment variable
180+
this.lambdaFunction.addEnvironment('ENDPOINT_NAME', this.sageMakerEndpoint.attrEndpointName);
181+
182+
// Add permission to invoke the SageMaker endpoint
183+
this.lambdaFunction.addToRolePolicy(
184+
new iam.PolicyStatement({
185+
actions: ['sagemaker:InvokeEndpoint'],
186+
resources: [this.sageMakerEndpoint.ref],
187+
})
188+
);
189+
}
190+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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-lambda": "0.0.0",
57+
"@aws-cdk/aws-sagemaker": "0.0.0",
58+
"@aws-cdk/aws-ec2": "0.0.0",
59+
"@aws-cdk/core": "0.0.0",
60+
"@aws-solutions-constructs/core": "0.0.0",
61+
"constructs": "^3.2.0"
62+
},
63+
"devDependencies": {
64+
"@aws-cdk/assert": "0.0.0",
65+
"@types/jest": "^24.9.1",
66+
"@types/node": "^10.17.49"
67+
},
68+
"jest": {
69+
"moduleFileExtensions": [
70+
"js"
71+
]
72+
},
73+
"peerDependencies": {
74+
"@aws-cdk/aws-lambda": "0.0.0",
75+
"@aws-cdk/aws-sagemaker": "0.0.0",
76+
"@aws-cdk/core": "0.0.0",
77+
"@aws-solutions-constructs/core": "0.0.0",
78+
"constructs": "^3.2.0",
79+
"@aws-cdk/aws-ec2": "0.0.0"
80+
}
81+
}

0 commit comments

Comments
 (0)