in Lab12-Lambda_EFS_Inference/lib/lambda_efsml-stack.ts [12:132]
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Define one new VPC
const vpc = new ec2.Vpc(this, 'LambdaEFSMLVPC', {
maxAzs: 2,
natGateways: 1,
});
// Define EC2 & Lambda & EFS Security Group
const ec2SecurityGroup = new ec2.SecurityGroup(this, 'LambdaEFSMLEC2SG', {
vpc,
securityGroupName: "LambdaEFSMLEC2SG",
});
const lambdaSecurityGroup = new ec2.SecurityGroup(this, 'LambdaEFSMLLambdaSG', {
vpc,
securityGroupName: "LambdaEFSMLLambdaSG",
});
const efsSecurityGroup = new ec2.SecurityGroup(this, 'LambdaEFSMLEFSSG', {
vpc,
securityGroupName: "LambdaEFSMLEFSSG",
});
ec2SecurityGroup.connections.allowTo(efsSecurityGroup, ec2.Port.tcp(2049));
lambdaSecurityGroup.connections.allowTo(efsSecurityGroup, ec2.Port.tcp(2049));
// Define an EC2 instance to mount EFS system
const myEc2 = new ec2.Instance(this, 'efsInstance', {
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
securityGroup: ec2SecurityGroup,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.XLARGE2),
machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX }),
// keyName: 'zeyao-ap-northeast-1' // replacee with your own keyname
keyName: 'xxxxxx' // replacee with your own keyname
})
ec2SecurityGroup.connections.allowFromAnyIpv4(ec2.Port.tcp(22), 'Allow SSH from Internet')
// Define Elastic File System file system
const fs = new efs.FileSystem(this, 'LambdaEFSMLEFS', {
vpc: vpc,
securityGroup: efsSecurityGroup,
throughputMode: efs.ThroughputMode.PROVISIONED,
provisionedThroughputPerSecond: Size.gibibytes(1)
});
const EfsAccessPoint = new efs.AccessPoint(this, 'EfsAccessPoint', {
fileSystem: fs,
path: '/lambda',
posixUser: {
gid: '1000',
uid: '1000'
},
createAcl: {
ownerGid: '1000',
ownerUid: '1000',
permissions: '777'
}
})
fs.connections.allowDefaultPortFrom(myEc2);
// Mount EFS file system and install ML framework and pre-train model
myEc2.userData.addCommands(
"yum check-update -y",
"yum upgrade -y",
"yum install -y amazon-efs-utils",
"yum install -y nfs-utils",
"file_system_id_1=" + fs.fileSystemId,
"efs_mount_point_1=/mnt/efs/fs1",
"mkdir -p \"${efs_mount_point_1}\"",
"test -f \"/sbin/mount.efs\" && echo \"${file_system_id_1}:/ ${efs_mount_point_1} efs defaults,_netdev\" >> /etc/fstab || " +
"echo \"${file_system_id_1}.efs." + cdk.Stack.of(this).region + ".amazonaws.com:/ ${efs_mount_point_1} nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,_netdev 0 0\" >> /etc/fstab",
"mount -a -t efs,nfs4 defaults",
'echo "Installing Python3"',
'yum install python36 -y',
'echo "Installing virtual environment..."',
'python3 -m venv ${efs_mount_point_1}/lambda/pytorch',
'echo "Installing PyTorch..."',
'source ${efs_mount_point_1}/lambda/pytorch/bin/activate && pip3 install torchvision numpy',
'echo "Downloading and copying model..."',
'mkdir -p ${efs_mount_point_1}/lambda/model',
'echo "Changing folder permissions..."',
'chown -R 1000:1000 ${efs_mount_point_1}/lambda/'
);
// Define Lambda function to execute inference
const executeInferenceFunction = new lambda.Function(this, 'LambdaEFSMLExecuteInference', {
environment: {
'PYTHONPATH': '/mnt/inference/pytorch/lib/python3.6/site-packages',
'TORCH_HOME': '/mnt/inference/model'
},
runtime: lambda.Runtime.PYTHON_3_6,
handler: 'main.lambda_handler',
code: lambda.Code.fromAsset(path.join(__dirname, '..', 'lambda')),
vpc,
vpcSubnets: vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE }),
securityGroup: lambdaSecurityGroup,
timeout: cdk.Duration.minutes(3),
memorySize: 3008,
reservedConcurrentExecutions: 10,
filesystem: lambda.FileSystem.fromEfsAccessPoint(EfsAccessPoint, '/mnt/inference')
})
executeInferenceFunction.role?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonElasticFileSystemClientFullAccess"));
const pcVer = executeInferenceFunction.addVersion('pcVer', undefined, undefined, 5)
new cdk.CfnOutput(this, 'Region', {value: this.region})
new cdk.CfnOutput(this, 'InstancePublicIp', {value: myEc2.instancePublicIp})
/* new cdk.CfnOutput(this, 'Funtion without provisionedConcurr', {value: executeInferenceFunction.functionArn})
new cdk.CfnOutput(this, 'Funtion with provisionedConcurr', {value: pcVer.functionArn}) */
}