Skip to content

Commit a015589

Browse files
authored
fix: [notebook]: pin the source code in experimental notebook (#158)
* use s3_assets * update template * update srcCodeAsset * rm DockerImage * update Policy for notebook * doc update * add UT * refine notebook role policy * refine NotebookIamRole policy * refine notebookRole Co-authored-by: Yong Liu <yonmzn@amazon.com>
1 parent 1cb477c commit a015589

File tree

9 files changed

+128
-8956
lines changed

9 files changed

+128
-8956
lines changed

docs/en/workshop/a-molecular-unfolding/evaluate-your-own-model.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ This solution is an open-source project under Apache License Version 2.0. You ca
1818

1919
2. Clone the project to your own workspace.
2020

21-
3. Change `githubRepo` path in the source/src/molecular-unfolding/cdk/construct-notebook.ts file to be your Git repository.
22-
23-
4. Make changes to source code. If you want to make changes for quantum algorithms, you can modify code under this directory **source/src/molecular-unfolding/utility**.
21+
3. Make changes to source code. If you want to make changes for quantum algorithms, you can modify code under this directory **source/src/molecular-unfolding/utility**.
2422

2523
## Deploy stack to your AWS account from CDK
2624

docs/en/workshop/a-molecular-unfolding/notebook-experiment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Here we focus on the first phase of MD, ligand expansion, which aims to reduce s
4141

4242
Figure 7: Notebook URL on the stack's Output tab
4343

44-
4. Open the file under the directory **source/src/molecular-folding/molecular_unfolding.ipynb** and choose the kernel **qcenv**.
44+
4. Open the file under the directory **molecular-folding/molecular_unfolding.ipynb** and choose the kernel **qcenv**.
4545

4646
5. Navigate through the notebook, which consists of four Steps:
4747

docs/zh/workshop/a-molecular-unfolding/evaluate-your-own-model.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020

2121
2. 将项目克隆到您自己的工作区。
2222

23-
3. 修改文件`source/src/molecular-unfolding/cdk/construct-notebook.ts`中的`githubRepo`路径为您的Git仓库。
24-
25-
4. 修改源代码。如果您想要修改量子算法,可以在目录`source/src/molecular-unfolding/utility`下修改代码。
23+
3. 修改源代码。如果您想要修改量子算法,可以在目录`source/src/molecular-unfolding/utility`下修改代码。
2624

2725
### 将堆栈从 CDK 部署到您的 AWS 账户
2826

docs/zh/workshop/a-molecular-unfolding/notebook-experiment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
![deployment output](../../images/deploy_output_notebook.png)
4444
图 7: 笔记本链接
4545

46-
4. 打开笔记本文件**source/src/molecular-folding/molecular_unfolding.ipynbn**,并确保笔记本的核为**qcenv**
46+
4. 打开笔记本文件**molecular-folding/molecular_unfolding.ipynb**,并确保笔记本的核为**qcenv**
4747

4848
5. 浏览整个笔记本。它由四个步骤组成:
4949

source/package-lock.json

Lines changed: 60 additions & 8909 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"devDependencies": {
2525
"@types/aws-lambda": "^8.10.92",
2626
"@types/jest": "^27.0.3",
27+
"@types/mustache": "^4.1.3",
2728
"@types/node": "14.17.7",
2829
"@typescript-eslint/eslint-plugin": "^4.29.0",
2930
"@typescript-eslint/parser": "^4.29.0",
@@ -42,10 +43,11 @@
4243
"dependencies": {
4344
"@aws-cdk/aws-batch-alpha": "^2.20.0-alpha.0",
4445
"@aws-sdk/client-cloudformation": "^3.48.0",
45-
"aws-cdk-lib": "^2.20.0",
4646
"aws-cdk": "^2.20.0",
47+
"aws-cdk-lib": "^2.20.0",
4748
"cdk-bootstrapless-synthesizer": "^2.2.0",
4849
"constructs": "^10.0.0",
50+
"mustache": "^4.2.0",
4951
"source-map-support": "^0.5.16"
5052
},
5153
"bundledDependencies": [],

source/src/molecular-unfolding/cdk/construct-notebook.ts

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ import {
1919
readFileSync,
2020
} from 'fs';
2121

22+
import * as path from 'path';
23+
2224
import {
2325
aws_s3 as s3,
2426
aws_kms as kms,
2527
aws_ec2 as ec2,
28+
aws_s3_assets as s3_assets,
29+
Fn,
2630
} from 'aws-cdk-lib';
2731

2832
import {
@@ -35,6 +39,7 @@ import {
3539
Construct,
3640
} from 'constructs';
3741

42+
import * as Mustache from 'mustache';
3843
import {
3944
RoleUtil,
4045
} from './utils/utils-role';
@@ -62,60 +67,46 @@ export class Notebook extends Construct {
6267
this.props = props;
6368
const INSTANCE_TYPE = 'ml.c5.xlarge';
6469

65-
this.roleUtil = RoleUtil.newInstance(this, props);
66-
67-
const githubRepo = 'https://github.com/awslabs/quantum-computing-exploration-for-drug-discovery-on-aws';
70+
const srcCodeAsset = new s3_assets.Asset(this, 'srcCodeAsset', {
71+
path: path.join(__dirname, '../../'),
72+
});
6873

69-
const defaultCodeRepository = this.node.tryGetContext('default_code_repository') || githubRepo;
74+
this.roleUtil = RoleUtil.newInstance(this, props);
7075

7176
const notebookRole = this.roleUtil.createNotebookIamRole();
7277

78+
srcCodeAsset.grantRead(notebookRole);
79+
7380
let onStartContent = readFileSync(`${__dirname}/resources/onStart.template`, 'utf-8');
7481

75-
const base64Encode = (str: string): string => Buffer.from(str, 'binary').toString('base64');
76-
const onStartContentBase64 = base64Encode(onStartContent);
82+
const rawOnStartContent = Mustache.render(onStartContent, {
83+
s3_code_path: srcCodeAsset.s3ObjectUrl,
84+
});
7785

7886
const installBraketSdk = new CfnNotebookInstanceLifecycleConfig(this, 'install-braket-sdk', {
7987
onStart: [{
80-
content: onStartContentBase64,
88+
content: Fn.base64(ec2.UserData.custom(rawOnStartContent).render()),
8189
}],
8290
});
8391

8492
const qcNotebookKey = new kms.Key(this, 'qcNotebookKey', {
8593
enableKeyRotation: true,
8694
});
8795

88-
let notebookInstance = null;
89-
if (defaultCodeRepository.startsWith('https://')) {
90-
notebookInstance = new CfnNotebookInstance(this, 'Notebook', {
91-
instanceType: INSTANCE_TYPE,
92-
roleArn: notebookRole.roleArn,
93-
rootAccess: 'Enabled', // Lifecycle configurations need root access to be able to set up a notebook instance
94-
lifecycleConfigName: installBraketSdk.attrNotebookInstanceLifecycleConfigName,
95-
volumeSizeInGb: 50,
96-
kmsKeyId: qcNotebookKey.keyId,
97-
securityGroupIds: [this.props.notebookSg.securityGroupId],
98-
subnetId: this.props.vpc.selectSubnets({
99-
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
100-
}).subnetIds[0],
101-
directInternetAccess: 'Disabled',
102-
defaultCodeRepository: defaultCodeRepository,
103-
});
104-
} else {
105-
notebookInstance = new CfnNotebookInstance(this, 'Notebook', {
106-
instanceType: INSTANCE_TYPE,
107-
roleArn: notebookRole.roleArn,
108-
rootAccess: 'Enabled',
109-
lifecycleConfigName: installBraketSdk.attrNotebookInstanceLifecycleConfigName,
110-
volumeSizeInGb: 50,
111-
kmsKeyId: qcNotebookKey.keyId,
112-
securityGroupIds: [this.props.notebookSg.securityGroupId],
113-
subnetId: this.props.vpc.selectSubnets({
114-
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
115-
}).subnetIds[0],
116-
directInternetAccess: 'Disabled',
117-
});
118-
}
96+
const notebookInstance = new CfnNotebookInstance(this, 'Notebook', {
97+
instanceType: INSTANCE_TYPE,
98+
roleArn: notebookRole.roleArn,
99+
rootAccess: 'Enabled',
100+
lifecycleConfigName: installBraketSdk.attrNotebookInstanceLifecycleConfigName,
101+
volumeSizeInGb: 50,
102+
kmsKeyId: qcNotebookKey.keyId,
103+
securityGroupIds: [this.props.notebookSg.securityGroupId],
104+
subnetId: this.props.vpc.selectSubnets({
105+
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
106+
}).subnetIds[0],
107+
directInternetAccess: 'Disabled',
108+
});
109+
119110
this.notebookUrl = `https://console.aws.amazon.com/sagemaker/home?region=${this.props.region}#/notebook-instances/openNotebook/${notebookInstance.attrNotebookInstanceName}?view=classic`;
120111
}
121112

source/src/molecular-unfolding/cdk/resources/onStart.template

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ pip3 install jupyter ipykernel
2424
2525
python3 -m ipykernel install --user --name=qcenv
2626
27+
aws s3 cp {{&s3_code_path}} /home/ec2-user/SageMaker/code.zip
28+
29+
cd /home/ec2-user/SageMaker/
30+
unzip code.zip -d ./
31+
rm code.zip
32+
2733
EOS
2834

2935
exit 0

source/test/notebook.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import {
2323

2424
import {
2525
Template,
26+
Match,
2627
} from 'aws-cdk-lib/assertions';
2728

29+
2830
import {
2931
NotebookNestStack,
3032
} from '../src/molecular-unfolding/cdk/stack-notebook';
@@ -64,4 +66,28 @@ describe('Notebook', () => {
6466
template.resourceCountIs('AWS::SageMaker::NotebookInstanceLifecycleConfig', 1);
6567
});
6668

69+
test('NotebookInstanceLifecycleConfig is configured correctly', ()=>{
70+
const template = initializeNestStackTemplate();
71+
template.hasResourceProperties('AWS::SageMaker::NotebookInstanceLifecycleConfig', {
72+
OnStart: [
73+
{
74+
Content: {
75+
'Fn::Base64': {
76+
'Fn::Join': [
77+
'',
78+
[
79+
Match.anyValue(),
80+
{
81+
'Fn::Sub': Match.anyValue(),
82+
},
83+
Match.anyValue(),
84+
],
85+
],
86+
},
87+
},
88+
},
89+
],
90+
});
91+
});
92+
6793
});

0 commit comments

Comments
 (0)