in model_deploy/lib/modelDeploymentStack.ts [32:136]
constructor(scope: cdk.App, id: string, props: ModelDeploymentStackProps) {
super(scope, id, props);
const modelPackageName = new cdk.CfnParameter(this, 'modelPackageName', {
type: 'String',
});
const endpointInstanceType = new cdk.CfnParameter(this, 'endpointInstanceType', {
type: 'String',
default: 'ml.m5.large',
});
const endpointInstanceCount = new cdk.CfnParameter(this, 'endpointInstanceCount', {
type: 'Number',
default: 1,
minValue: 1,
});
const executionRole = new iam.Role(this, 'SageMakerModelExecutionRole', {
assumedBy: new iam.ServicePrincipal('sagemaker.amazonaws.com'),
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSageMakerFullAccess')],
});
const pipelineModelFunctionRole = new iam.Role(this, 'DataFunctionRole', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')],
});
pipelineModelFunctionRole.addToPolicy(
iam.PolicyStatement.fromJson({
Effect: 'Allow',
Action: ['sagemaker:CreateModel', 'sagemaker:DeleteModel', 'sagemaker:DescribeModelPackage'],
Resource: [
`arn:aws:sagemaker:${this.region}:${this.account}:model/${props.projectName}*`,
modelPackageName.valueAsString
],
})
);
pipelineModelFunctionRole.addToPolicy(
iam.PolicyStatement.fromJson({
Effect: 'Allow',
Action: ['iam:PassRole'],
Resource: [executionRole.roleArn],
}));
const pipelineModelFunction = new lambdaNodeJs.NodejsFunction(this, 'PipelineModelFunction', {
runtime: lambda.Runtime.NODEJS_14_X,
handler: 'handler',
entry: path.join(__dirname, '../customResources/pipelineModel/index.ts'),
timeout: cdk.Duration.minutes(1),
reservedConcurrentExecutions: 1,
role: pipelineModelFunctionRole
});
const pipelineModelCustomResourceProvider = new customResource.Provider(
this,
'PipelineModelCustomResourceProvider',
{
onEventHandler: pipelineModelFunction,
logRetention: logs.RetentionDays.ONE_DAY,
}
);
const pipelineModelCustomResource = new cdk.CustomResource(this, 'PipelineModelCustomResource', {
serviceToken: pipelineModelCustomResourceProvider.serviceToken,
properties: {
modelPackageName: modelPackageName.valueAsString,
sagemakerExecutionRole: executionRole.roleArn,
projectName: props.projectName
},
});
pipelineModelCustomResource.node.addDependency(executionRole);
const endpointConfig = new sagemaker.CfnEndpointConfig(this, 'SageMakerModelEndpointConfig', {
productionVariants: [
{
initialInstanceCount: endpointInstanceCount.valueAsNumber,
initialVariantWeight: 1.0,
instanceType: endpointInstanceType.valueAsString,
modelName: pipelineModelCustomResource.ref,
variantName: 'AllTraffic',
},
],
});
endpointConfig.node.addDependency(pipelineModelCustomResource)
const endpoint = new sagemaker.CfnEndpoint(this, 'SageMakerModelEndpoint', {
endpointConfigName: endpointConfig.getAtt('EndpointConfigName').toString(),
});
endpoint.node.addDependency(endpointConfig);
new cdk.CfnOutput(this, 'ModelEndpointOutput', {
value: endpoint.ref,
exportName: `${props.modelEndpointExportNamePrefix}-${props.projectName}`,
});
new cdk.CfnOutput(this, 'ModelEndpointNameOutput', {
value: endpoint.getAtt('EndpointName').toString(),
exportName: `${props.modelEndpointExportNamePrefix}-Name-${props.projectName}`,
});
}