Skip to content

Commit

Permalink
release: breaking out ECR Constructs
Browse files Browse the repository at this point in the history
release: breaking out ECR Constructs
  • Loading branch information
drduhe authored Nov 1, 2023
2 parents 18e60b5 + be55fbb commit c8706d6
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 109 deletions.
4 changes: 3 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
export * from "./osml/model_runner/autoscaling/mr_autoscaling";
export * from "./osml/model_runner/mr_dataplane";
export * from "./osml/model_runner/mr_ecr";
export * from "./osml/model_runner/monitoring/mr_monitoring";
export * from "./osml/model_runner/roles/mr_sm_role";
export * from "./osml/model_runner/roles/mr_task_role";
export * from "./osml/model_runner/testing/mr_imagery";
export * from "./osml/model_runner/testing/mr_model_endpoints";
export * from "./osml/model_runner/testing/mr_endpoints";
export * from "./osml/model_runner/testing/mr_status";
export * from "./osml/model_runner/testing/mr_sync";
export * from "./osml/model_runner/testing/mr_model_ecr";
export * from "./osml/osml_account";
export * from "./osml/osml_bucket";
export * from "./osml/osml_ecr_deployment";
Expand Down
49 changes: 4 additions & 45 deletions lib/osml/model_runner/mr_dataplane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,9 @@
* Copyright 2023 Amazon.com, Inc. or its affiliates.
*/

import {
Duration,
region_info,
RemovalPolicy,
SymlinkFollowMode
} from "aws-cdk-lib";
import { Duration, region_info, RemovalPolicy } from "aws-cdk-lib";
import { AttributeType } from "aws-cdk-lib/aws-dynamodb";
import { ISecurityGroup, SecurityGroup } from "aws-cdk-lib/aws-ec2";
import { DockerImageAsset } from "aws-cdk-lib/aws-ecr-assets";
import {
Cluster,
Compatibility,
Expand All @@ -29,7 +23,6 @@ import { LogGroup, RetentionDays } from "aws-cdk-lib/aws-logs";
import { Construct } from "constructs";

import { OSMLAccount } from "../osml_account";
import { OSMLECRDeployment } from "../osml_ecr_deployment";
import { OSMLQueue } from "../osml_queue";
import { OSMLTable } from "../osml_table";
import { OSMLTopic } from "../osml_topic";
Expand Down Expand Up @@ -68,14 +61,7 @@ export class MRDataplaneConfig {
public MR_LOGGING_MEMORY = 512,
public MR_LOGGING_CPU = 512,
public MR_WORKERS_PER_CPU = 1,
public MR_REGION_SIZE = "(8192, 8192)",
public MR_DEFAULT_CONTAINER = "awsosml/osml-model-runner:main",
// repository name for the model runner container
public ECR_MODEL_RUNNER_REPOSITORY = "model-runner-container",
// path to the local source for model runner to build against
public ECR_MODEL_RUNNER_BUILD_PATH = "lib/osml-model-runner",
// build target for model runner container
public ECR_MODEL_RUNNER_TARGET = "model_runner"
public MR_REGION_SIZE = "(8192, 8192)"
) {}
}

Expand All @@ -94,6 +80,7 @@ export interface MRDataplaneProps {
dataplaneConfig?: MRDataplaneConfig;
// subnets to deploy infrastructure into
targetSubnets?: string[];
mrContainerImage: ContainerImage;
}

export class MRDataplane extends Construct {
Expand All @@ -105,8 +92,6 @@ export class MRDataplane extends Construct {
public featureTable: OSMLTable;
public endpointStatisticsTable: OSMLTable;
public regionRequestTable: OSMLTable;
public mrContainerSourceUri: string;
public mrContainerImage: ContainerImage;
public imageStatusTopic: OSMLTopic;
public regionStatusTopic: OSMLTopic;
public imageRequestQueue: OSMLQueue;
Expand All @@ -126,7 +111,6 @@ export class MRDataplane extends Construct {
* - creating the DDB tables
* - creating the SQS queues
* - creating the SNS topics
* - creating the ECR repositories
* - creating the ECR containers
* - creating the ECS cluster
* - creating the ECS task definition
Expand Down Expand Up @@ -172,31 +156,6 @@ export class MRDataplane extends Construct {
region_info.FactName.servicePrincipal("s3.amazonaws.com")
)!;

if (props.account.isDev == true) {
const dockerImageAsset = new DockerImageAsset(this, id, {
directory: this.mrDataplaneConfig.ECR_MODEL_RUNNER_BUILD_PATH,
file: "Dockerfile",
followSymlinks: SymlinkFollowMode.ALWAYS,
target: this.mrDataplaneConfig.ECR_MODEL_RUNNER_TARGET
});
this.mrContainerImage =
ContainerImage.fromDockerImageAsset(dockerImageAsset);
this.mrContainerSourceUri = dockerImageAsset.imageUri;
} else {
const osmlEcrDeployment = new OSMLECRDeployment(
this,
"MRModelRunnerContainer",
{
sourceUri: this.mrDataplaneConfig.MR_DEFAULT_CONTAINER,
repositoryName: this.mrDataplaneConfig.ECR_MODEL_RUNNER_REPOSITORY,
removalPolicy: this.removalPolicy,
vpc: props.osmlVpc.vpc
}
);
this.mrContainerImage = osmlEcrDeployment.containerImage;
this.mrContainerSourceUri = osmlEcrDeployment.ecrContainerUri;
}

// job status table to store worker status info
this.jobStatusTable = new OSMLTable(this, "MRJobStatusTable", {
tableName: this.mrDataplaneConfig.DDB_JOB_STATUS_TABLE,
Expand Down Expand Up @@ -344,7 +303,7 @@ export class MRDataplane extends Construct {
"MRContainerDefinition",
{
containerName: this.mrDataplaneConfig.MR_CONTAINER_NAME,
image: this.mrContainerImage,
image: props.mrContainerImage,
memoryLimitMiB: this.mrDataplaneConfig.MR_CONTAINER_MEMORY,
cpu: this.mrDataplaneConfig.MR_CONTAINER_CPU,
environment: containerEnv,
Expand Down
95 changes: 95 additions & 0 deletions lib/osml/model_runner/mr_ecr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates.
*/

import { RemovalPolicy, SymlinkFollowMode } from "aws-cdk-lib";
import { DockerImageAsset } from "aws-cdk-lib/aws-ecr-assets";
import { ContainerImage } from "aws-cdk-lib/aws-ecs";
import { IRole } from "aws-cdk-lib/aws-iam";
import { Construct } from "constructs";

import { OSMLAccount } from "../osml_account";
import { OSMLECRDeployment } from "../osml_ecr_deployment";
import { OSMLVpc } from "../osml_vpc";

// mutable configuration dataclass for model runner
// for a more detailed breakdown of the configuration see: configuration_guide.md in the documentation directory.
export class MRRepoConfig {
constructor(
public MR_DEFAULT_CONTAINER = "awsosml/osml-model-runner:main",
// repository name for the model runner container
public ECR_MODEL_RUNNER_REPOSITORY = "model-runner-container",
// path to the local source for model runner to build against
public ECR_MODEL_RUNNER_BUILD_PATH = "lib/osml-model-runner",
// build target for model runner container
public ECR_MODEL_RUNNER_TARGET = "model_runner"
) {}
}

export interface MRRepoProps {
// the account that owns the data plane as defined by the OSMLAccount interface
account: OSMLAccount;
// the vpc to deploy into
osmlVpc: OSMLVpc;
// optional role to give the model runner task execution permissions - will be crated if not provided
taskRole?: IRole;
// optional service level configuration that can be provided by the user but will be defaulted if not
mrRepoConfig?: MRRepoConfig;
}

export class MREcr extends Construct {
public mrRepoConfig: MRRepoConfig;
public removalPolicy: RemovalPolicy;
public mrContainerSourceUri: string;
public mrContainerImage: ContainerImage;

/**
* This construct is responsible deploying the ECR container image for
* the model runner service.
* @param scope the scope/stack in which to define this construct.
* @param id the id of this construct within the current scope.
* @param props the properties of this construct.
* @returns the MRDataplane construct
*/
constructor(scope: Construct, id: string, props: MRRepoProps) {
super(scope, id);
// setup a removal policy
this.removalPolicy = props.account.prodLike
? RemovalPolicy.RETAIN
: RemovalPolicy.DESTROY;

// check if a custom configuration was provided
if (props.mrRepoConfig != undefined) {
// import existing pass in MR configuration
this.mrRepoConfig = props.mrRepoConfig;
} else {
// create a new default configuration
this.mrRepoConfig = new MRRepoConfig();
}

if (props.account.isDev == true) {
const dockerImageAsset = new DockerImageAsset(this, id, {
directory: this.mrRepoConfig.ECR_MODEL_RUNNER_BUILD_PATH,
file: "Dockerfile",
followSymlinks: SymlinkFollowMode.ALWAYS,
target: this.mrRepoConfig.ECR_MODEL_RUNNER_TARGET
});
this.mrContainerImage =
ContainerImage.fromDockerImageAsset(dockerImageAsset);
this.mrContainerSourceUri = dockerImageAsset.imageUri;
} else {
const osmlEcrDeployment = new OSMLECRDeployment(
this,
"MRModelRunnerContainer",
{
sourceUri: this.mrRepoConfig.MR_DEFAULT_CONTAINER,
repositoryName: this.mrRepoConfig.ECR_MODEL_RUNNER_REPOSITORY,
removalPolicy: this.removalPolicy,
vpc: props.osmlVpc.vpc
}
);
this.mrContainerImage = osmlEcrDeployment.containerImage;
this.mrContainerSourceUri = osmlEcrDeployment.ecrContainerUri;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates.
*/
import { RemovalPolicy, SymlinkFollowMode } from "aws-cdk-lib";
import { DockerImageAsset } from "aws-cdk-lib/aws-ecr-assets";
import { RemovalPolicy } from "aws-cdk-lib";
import { ContainerImage } from "aws-cdk-lib/aws-ecs";
import { IRole } from "aws-cdk-lib/aws-iam";
import { Construct } from "constructs";
Expand All @@ -11,7 +10,6 @@ import { OSMLHTTPModelEndpoint } from "../../model_endpoints/osml_http_endpoint"
import { OSMLHTTPEndpointRole } from "../../model_endpoints/osml_http_endpoint_role";
import { OSMLSMEndpoint } from "../../model_endpoints/osml_sm_endpoint";
import { OSMLAccount } from "../../osml_account";
import { OSMLECRDeployment } from "../../osml_ecr_deployment";
import { OSMLVpc } from "../../osml_vpc";
import { MRSMRole } from "../roles/mr_sm_role";

Expand All @@ -38,7 +36,6 @@ export class MRModelEndpointsConfig {
public HTTP_ENDPOINT_CPU = 4096,
public HTTP_ENDPOINT_HEALTHCHECK_PATH = "/ping",
public HTTP_ENDPOINT_DOMAIN_NAME = "test-http-model-endpoint",
public MODEL_DEFAULT_CONTAINER = "awsosml/osml-models:main",
// ecr repo names
public ECR_MODEL_REPOSITORY = "model-container",
// path to the control model source
Expand All @@ -60,19 +57,18 @@ export interface MRModelEndpointsProps {
mrModelEndpointsConfig?: MRModelEndpointsConfig;
// optional sage maker iam role to use for endpoint construction - will be defaulted if not provided
smRole?: IRole;
// optional custom model container ECR URIs
modelContainer?: string;
// security groups to apply to the vpc config for SM endpoints
securityGroupId?: string;
// optional deploy custom model resources
deployCenterpointModel?: boolean;
deployFloodModel?: boolean;
deployAircraftModel?: boolean;
deployHttpCenterpointModel?: boolean;
modelContainerImage: ContainerImage;
modelContainerUri: string;
}

export class MREndpoints extends Construct {
public modelContainerEcrDeployment: OSMLECRDeployment;
public removalPolicy: RemovalPolicy;
public mrModelEndpointsConfig: MRModelEndpointsConfig;
public smRole?: IRole;
Expand All @@ -82,8 +78,6 @@ export class MREndpoints extends Construct {
public floodModelEndpoint?: OSMLSMEndpoint;
public aircraftModelEndpoint?: OSMLSMEndpoint;
public securityGroupId: string;
public modelContainerImage: ContainerImage;
public modelContainerUri: string;

/**
* Creates an MRTesting construct.
Expand Down Expand Up @@ -133,36 +127,6 @@ export class MREndpoints extends Construct {
} else {
this.securityGroupId = props.osmlVpc.vpcDefaultSecurityGroup;
}

if (props.account.isDev == true) {
const dockerImageAsset = new DockerImageAsset(this, id, {
directory: this.mrModelEndpointsConfig.ECR_MODELS_PATH,
file: "Dockerfile",
followSymlinks: SymlinkFollowMode.ALWAYS,
target: this.mrModelEndpointsConfig.ECR_MODEL_TARGET
});

this.modelContainerImage =
ContainerImage.fromDockerImageAsset(dockerImageAsset);

this.modelContainerUri = dockerImageAsset.imageUri;
} else {
this.modelContainerEcrDeployment = new OSMLECRDeployment(
this,
"OSMLModelContainer",
{
sourceUri: this.mrModelEndpointsConfig.MODEL_DEFAULT_CONTAINER,
repositoryName: this.mrModelEndpointsConfig.ECR_MODEL_REPOSITORY,
removalPolicy: this.removalPolicy,
vpc: props.osmlVpc.vpc,
vpcSubnets: props.osmlVpc.selectedSubnets
}
);
this.modelContainerImage =
this.modelContainerEcrDeployment.containerImage;
this.modelContainerUri =
this.modelContainerEcrDeployment.ecrContainerUri;
}
}
if (props.deployHttpCenterpointModel != false) {
// check if a role was provided
Expand All @@ -188,7 +152,7 @@ export class MREndpoints extends Construct {
{
account: props.account,
osmlVpc: props.osmlVpc,
image: this.modelContainerImage,
image: props.modelContainerImage,
clusterName: this.mrModelEndpointsConfig.HTTP_ENDPOINT_NAME,
role: this.httpEndpointRole,
memory: this.mrModelEndpointsConfig.HTTP_ENDPOINT_MEMORY,
Expand All @@ -206,11 +170,6 @@ export class MREndpoints extends Construct {
securityGroupId: this.securityGroupId
}
);
if (props.account.isDev == false) {
this.httpCenterpointModelEndpoint.node.addDependency(
this.modelContainerEcrDeployment
);
}
}

if (props.deployCenterpointModel != false) {
Expand All @@ -219,7 +178,7 @@ export class MREndpoints extends Construct {
this,
"OSMLCenterPointModelEndpoint",
{
ecrContainerUri: this.modelContainerUri,
ecrContainerUri: props.modelContainerUri,
modelName: this.mrModelEndpointsConfig.SM_CENTER_POINT_MODEL,
roleArn: this.smRole.roleArn,
instanceType: this.mrModelEndpointsConfig.SM_CPU_INSTANCE_TYPE,
Expand All @@ -234,11 +193,6 @@ export class MREndpoints extends Construct {
subnetIds: props.osmlVpc.selectedSubnets.subnetIds
}
);
if (props.account.isDev == false) {
this.centerPointModelEndpoint.node.addDependency(
this.modelContainerEcrDeployment
);
}
}

if (props.deployFloodModel != false) {
Expand All @@ -247,7 +201,7 @@ export class MREndpoints extends Construct {
this,
"OSMLFloodModelEndpoint",
{
ecrContainerUri: this.modelContainerUri,
ecrContainerUri: props.modelContainerUri,
modelName: this.mrModelEndpointsConfig.SM_FLOOD_MODEL,
roleArn: this.smRole.roleArn,
instanceType: this.mrModelEndpointsConfig.SM_CPU_INSTANCE_TYPE,
Expand All @@ -262,11 +216,6 @@ export class MREndpoints extends Construct {
subnetIds: props.osmlVpc.selectedSubnets.subnetIds
}
);
if (props.account.isDev == false) {
this.floodModelEndpoint.node.addDependency(
this.modelContainerEcrDeployment
);
}
}

if (props.deployAircraftModel != false) {
Expand All @@ -275,7 +224,7 @@ export class MREndpoints extends Construct {
this,
"OSMLAircraftModelEndpoint",
{
ecrContainerUri: this.modelContainerUri,
ecrContainerUri: props.modelContainerUri,
modelName: this.mrModelEndpointsConfig.SM_AIRCRAFT_MODEL,
roleArn: this.smRole.roleArn,
instanceType: this.mrModelEndpointsConfig.SM_GPU_INSTANCE_TYPE,
Expand All @@ -290,11 +239,6 @@ export class MREndpoints extends Construct {
subnetIds: props.osmlVpc.selectedSubnets.subnetIds
}
);
if (props.account.isDev == false) {
this.aircraftModelEndpoint.node.addDependency(
this.modelContainerEcrDeployment
);
}
}
}
}
Loading

0 comments on commit c8706d6

Please sign in to comment.