Skip to content

Commit

Permalink
feat(aws-lambda-sagemakerendpoint): new pattern aws-lambda-sagemakere…
Browse files Browse the repository at this point in the history
…ndpoint 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]>
  • Loading branch information
tabdunabi and tabdunabi authored Feb 22, 2021
1 parent f4b22d8 commit ea4ab3b
Show file tree
Hide file tree
Showing 28 changed files with 13,029 additions and 720 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
lib/*.js
test/*.js
*.d.ts
coverage
test/lambda/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
lib/*.js
test/*.js
*.js.map
*.d.ts
node_modules
*.generated.ts
dist
.jsii

.LAST_BUILD
.nyc_output
coverage
.nycrc
.LAST_PACKAGE
*.snk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Exclude typescript source and config
*.ts
tsconfig.json
coverage
.nyc_output
*.tgz
*.snk
*.tsbuildinfo

# Include javascript files and typescript declarations
!*.js
!*.d.ts

# Exclude jsii outdir
dist

# Include .jsii
!.jsii

# Include .jsii
!.jsii

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as iam from '@aws-cdk/aws-iam';
import * as sagemaker from '@aws-cdk/aws-sagemaker';
import * as defaults from '@aws-solutions-constructs/core';

/**
* @summary The properties for the LambdaToSagemakerEndpoint class
*/
export interface LambdaToSagemakerEndpointProps {
/**
* Existing instance of Lambda Function object, if this is set then the lambdaFunctionProps is ignored
*
* @default - None
*/
readonly existingLambdaObj?: lambda.Function;
/**
* User provided props to override the default props for the Lambda function
*
* @default - Default props are used
*/
readonly lambdaFunctionProps?: lambda.FunctionProps;
/**
* Existing Sagemaker Enpoint object, if this is set then the modelProps, endpointConfigProps, and endpointProps are ignored
*
* @default - None
*/
readonly existingSagemakerEndpointObj?: sagemaker.CfnEndpoint;
/**
* User provided props to create Sagemaker Model
*
* @default - None
*/
readonly modelProps?: sagemaker.CfnModelProps | any;
/**
* User provided props to create Sagemaker Endpoint Configuration
*
* @default - Default props are used
*/
readonly endpointConfigProps?: sagemaker.CfnEndpointConfigProps;
/**
* User provided props to create Sagemaker Endpoint
*
* @default - Default props are used
*/
readonly endpointProps?: sagemaker.CfnEndpointProps;
/**
* An existing VPC for the construct to use (construct will NOT create a new VPC in this case)
*
* @default - None
*/
readonly existingVpc?: ec2.IVpc;
/**
* Properties to override default properties if deployVpc is true
*
* @default - None
*/
readonly vpcProps?: ec2.VpcProps;
/**
* Whether to deploy a new VPC
*
* @default - false
*/
readonly deployVpc?: boolean;
}

/**
* @summary The LambdaToSagemakerEndpoint class.
*/
export class LambdaToSagemakerEndpoint extends cdk.Construct {
public readonly lambdaFunction: lambda.Function;
public readonly sagemakerEndpoint: sagemaker.CfnEndpoint;
public readonly sagemakerEndpointConfig?: sagemaker.CfnEndpointConfig;
public readonly sagemakerModel?: sagemaker.CfnModel;
public readonly vpc?: ec2.IVpc;

/**
* @summary Constructs a new instance of the LambdaToSagemakerEndpoint class.
* @param {cdk.App} scope - represents the scope for all the resources.
* @param {string} id - this is a scope-unique id.
* @param {LambdaToSagemakerEndpointProps} props - user provided props for the construct.
* @since 1.87.1
* @access public
*/
constructor(scope: cdk.Construct, id: string, props: LambdaToSagemakerEndpointProps) {
super(scope, id);

if (props.deployVpc || props.existingVpc) {
if (props.deployVpc && props.existingVpc) {
throw new Error('More than 1 VPC specified in the properties');
}

// create the VPC
this.vpc = defaults.buildVpc(scope, {
defaultVpcProps: defaults.DefaultIsolatedVpcProps(),
existingVpc: props.existingVpc,
userVpcProps: props.vpcProps,
constructVpcProps: {
enableDnsHostnames: true,
enableDnsSupport: true,
},
});

// Add S3 VPC Gateway Endpoint, required by Sagemaker to access Models artifacts via AWS private network
defaults.AddAwsServiceEndpoint(scope, this.vpc, defaults.ServiceEndpointTypes.S3);
// Add SAGEMAKER_RUNTIME VPC Interface Endpoint, required by the lambda function to invoke the Sagemaker endpoint
defaults.AddAwsServiceEndpoint(scope, this.vpc, defaults.ServiceEndpointTypes.SAGEMAKER_RUNTIME);
}

// Build Sagemaker Endpoint (inclduing Sagemaker's Endpoint Configuration and Model)
[this.sagemakerEndpoint, this.sagemakerEndpointConfig, this.sagemakerModel] = defaults.BuildSagemakerEndpoint(
this,
{
...props,
vpc: this.vpc,
}
);

// Setup the Lambda function
this.lambdaFunction = defaults.buildLambdaFunction(this, {
existingLambdaObj: props.existingLambdaObj,
lambdaFunctionProps: props.lambdaFunctionProps,
vpc: this.vpc,
});

// Add SAGEMAKER_ENDPOINT_NAME environment variable
this.lambdaFunction.addEnvironment('SAGEMAKER_ENDPOINT_NAME', this.sagemakerEndpoint.attrEndpointName);

// Add permission to invoke the SageMaker endpoint
this.lambdaFunction.addToRolePolicy(
new iam.PolicyStatement({
actions: ['sagemaker:InvokeEndpoint'],
resources: [this.sagemakerEndpoint.ref],
})
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"name": "@aws-solutions-constructs/aws-lambda-sagemakerendpoint",
"version": "0.0.0",
"description": "CDK constructs for defining an interaction between an AWS Lambda function and an Amazon SageMaker inference endpoint.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/awslabs/aws-solutions-constructs.git",
"directory": "source/patterns/@aws-solutions-constructs/aws-lambda-sagemakerendpoint"
},
"author": {
"name": "Amazon Web Services",
"url": "https://aws.amazon.com",
"organization": true
},
"license": "Apache-2.0",
"scripts": {
"build": "tsc -b .",
"lint": "eslint -c ../eslintrc.yml --ext=.js,.ts . && tslint --project .",
"lint-fix": "eslint -c ../eslintrc.yml --ext=.js,.ts --fix .",
"test": "jest --coverage",
"clean": "tsc -b --clean",
"watch": "tsc -b -w",
"integ": "cdk-integ",
"integ-assert": "cdk-integ-assert",
"integ-no-clean": "cdk-integ --no-clean",
"jsii": "jsii",
"jsii-pacmak": "jsii-pacmak",
"build+lint+test": "npm run jsii && npm run lint && npm test && npm run integ-assert",
"snapshot-update": "npm run jsii && npm test -- -u && npm run integ-assert"
},
"jsii": {
"outdir": "dist",
"targets": {
"java": {
"package": "software.amazon.awsconstructs.services.lambdasagemakerendpoint",
"maven": {
"groupId": "software.amazon.awsconstructs",
"artifactId": "lambdasqs"
}
},
"dotnet": {
"namespace": "Amazon.Constructs.AWS.LambdaSagemakerEndpoint",
"packageId": "Amazon.Constructs.AWS.LambdaSagemakerEndpoint",
"signAssembly": true,
"iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png"
},
"python": {
"distName": "aws-solutions-constructs.aws-lambda-sagemakerendpoint",
"module": "aws_solutions_constructs.aws_lambda_sagemakerendpoint"
}
}
},
"dependencies": {
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-sagemaker": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-solutions-constructs/core": "0.0.0",
"constructs": "^3.2.0"
},
"devDependencies": {
"@aws-cdk/assert": "0.0.0",
"@types/jest": "^24.0.23",
"@types/node": "^10.3.0"
},
"jest": {
"moduleFileExtensions": [
"js"
]
},
"peerDependencies": {
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-lambda": "0.0.0",
"@aws-cdk/aws-sagemaker": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-solutions-constructs/core": "0.0.0",
"constructs": "^3.2.0"
}
}
Loading

0 comments on commit ea4ab3b

Please sign in to comment.