Skip to content

Commit

Permalink
feat(sagemaker): network isolation for a model (#30657)
Browse files Browse the repository at this point in the history
### Issue # (if applicable)

None

### Reason for this change

SageMaker model supports for the [network isolation](https://docs.aws.amazon.com/sagemaker/latest/dg/mkt-algo-model-internet-free.html) function. But Model construct does not support this.

### Description of changes

Add `networkIsolation` to `ModelProps`

```ts
const model = new sagemaker.Model(this, 'ContainerModel', {
  containers: [
    {
      image,
      modelData,
    }
  ],
  networkIsolation: true, // Added
});
```

### Description of how you validated changes

Added both unit and integ tests

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
badmintoncryer committed Aug 13, 2024
1 parent 5b3b2d1 commit f1af7fc
Show file tree
Hide file tree
Showing 8 changed files with 477 additions and 13 deletions.
25 changes: 25 additions & 0 deletions packages/@aws-cdk/aws-sagemaker-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,31 @@ const model = new sagemaker.Model(this, 'InferencePipelineModel', {
});
```

### Model Properties

#### Network Isolation

If you enable [network isolation](https://docs.aws.amazon.com/sagemaker/latest/dg/mkt-algo-model-internet-free.html), the containers can't make any outbound network calls, even to other AWS services such as Amazon S3. Additionally, no AWS credentials are made available to the container runtime environment.

To enable network isolation, set the `networkIsolation` property to `true`:

```typescript
import * as sagemaker from '@aws-cdk/aws-sagemaker-alpha';

declare const image: sagemaker.ContainerImage;
declare const modelData: sagemaker.ModelData;

const model = new sagemaker.Model(this, 'ContainerModel', {
containers: [
{
image,
modelData,
}
],
networkIsolation: true,
});
```

### Container Images

Inference code can be stored in the Amazon EC2 Container Registry (Amazon ECR), which is specified
Expand Down
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-sagemaker-alpha/lib/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,17 @@ export interface ModelProps {
* @default true
*/
readonly allowAllOutbound?: boolean;

/**
* Whether to enable network isolation for the model container.
*
* When enabled, no inbound or outbound network calls can be made to or from the model container.
*
* @see https://docs.aws.amazon.com/sagemaker/latest/dg/mkt-algo-model-internet-free.html
*
* @default false
*/
readonly networkIsolation?: boolean;
}

/**
Expand Down Expand Up @@ -312,6 +323,7 @@ export class Model extends ModelBase {
primaryContainer: cdk.Lazy.any({ produce: () => this.renderPrimaryContainer() }),
vpcConfig: cdk.Lazy.any({ produce: () => this.renderVpcConfig() }),
containers: cdk.Lazy.any({ produce: () => this.renderContainers() }),
enableNetworkIsolation: props.networkIsolation,
});
this.modelName = this.getResourceNameAttribute(model.attrModelName);
this.modelArn = this.getResourceArnAttribute(model.ref, {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,169 @@
"HuggingFaceModelRoleDefaultPolicy50587D35",
"HuggingFaceModelRoleDA17DA00"
]
},
"NetworkIsolationModelRole562D6C7F": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "sagemaker.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/AmazonSageMakerFullAccess"
]
]
}
]
}
},
"NetworkIsolationModelRoleDefaultPolicy84ACFE88": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":ecr:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":repository/",
{
"Fn::Sub": "cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}"
}
]
]
}
},
{
"Action": "ecr:GetAuthorizationToken",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"s3:GetBucket*",
"s3:GetObject*",
"s3:List*"
],
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":s3:::",
{
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":s3:::",
{
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
}
]
]
}
]
}
],
"Version": "2012-10-17"
},
"PolicyName": "NetworkIsolationModelRoleDefaultPolicy84ACFE88",
"Roles": [
{
"Ref": "NetworkIsolationModelRole562D6C7F"
}
]
}
},
"NetworkIsolationModel29FE9107": {
"Type": "AWS::SageMaker::Model",
"Properties": {
"Containers": [
{
"Image": {
"Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:442a71de95281cb26bd41da567c79060206108b97bdde93cb4ce5f213f50013a"
}
},
{
"Image": {
"Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:442a71de95281cb26bd41da567c79060206108b97bdde93cb4ce5f213f50013a"
},
"ModelDataUrl": {
"Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/126d48fa0e32fbef5078b9d88658b35ad29d4291eb86675a64c75fa4f1338916.gz"
}
},
{
"Image": {
"Fn::Sub": "${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-container-assets-${AWS::AccountId}-${AWS::Region}:442a71de95281cb26bd41da567c79060206108b97bdde93cb4ce5f213f50013a"
},
"ModelDataUrl": {
"Fn::Sub": "https://s3.${AWS::Region}.${AWS::URLSuffix}/cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/126d48fa0e32fbef5078b9d88658b35ad29d4291eb86675a64c75fa4f1338916.gz"
}
}
],
"EnableNetworkIsolation": true,
"ExecutionRoleArn": {
"Fn::GetAtt": [
"NetworkIsolationModelRole562D6C7F",
"Arn"
]
}
},
"DependsOn": [
"NetworkIsolationModelRoleDefaultPolicy84ACFE88",
"NetworkIsolationModelRole562D6C7F"
]
}
},
"Mappings": {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f1af7fc

Please sign in to comment.