constructor()

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}`,
        });
    }