@@ -11,6 +11,33 @@ import { Construct } from "constructs";
1111
1212import { BaseConfig , ConfigType } from "../utils/base_config" ;
1313
14+ /**
15+ * Configuration for a container in a SageMaker model
16+ */
17+ export interface ContainerDefinition {
18+ /**
19+ * The URI of the container image
20+ */
21+ imageUri : string ;
22+
23+ /**
24+ * Environment variables for the container
25+ */
26+ environment ?: Record < string , unknown > ;
27+
28+ /**
29+ * Repository access mode for the container
30+ */
31+ repositoryAccessMode ?: string ;
32+
33+ /**
34+ * Hostname for the container (required for multi-container Direct mode)
35+ * If required and not specified, will default to an index-based name
36+ * example: "container-0"
37+ */
38+ containerHostname ?: string ;
39+ }
40+
1441/**
1542 * Configuration class for MESMEndpoint Construct.
1643 */
@@ -38,13 +65,20 @@ export class MESMEndpointConfig extends BaseConfig {
3865 */
3966 public SECURITY_GROUP_ID : string ;
4067
68+ /**
69+ * List of container definitions for the model
70+ */
71+ public CONTAINERS : ContainerDefinition [ ] ;
72+
4173 /**
4274 * A JSON object which includes ENV variables to be put into the model container.
75+ * @deprecated Use CONTAINERS (ContainerDefinition[]) instead
4376 */
4477 public CONTAINER_ENV : Record < string , unknown > ;
4578
4679 /**
4780 * The repository access mode to use for the SageMaker endpoint container.
81+ * @deprecated Use CONTAINERS (ContainerDefinition) instead
4882 */
4983 public REPOSITORY_ACCESS_MODE : string ;
5084 /**
@@ -57,9 +91,30 @@ export class MESMEndpointConfig extends BaseConfig {
5791 INITIAL_VARIANT_WEIGHT : 1 ,
5892 INITIAL_INSTANCE_COUNT : 1 ,
5993 VARIANT_NAME : "AllTraffic" ,
60- REPOSITORY_ACCESS_MODE : "Platform" ,
94+ CONTAINERS : [ ] ,
6195 ...config
6296 } ) ;
97+
98+ // Convert deprecated interface to container list if needed
99+ if ( this . CONTAINERS . length === 0 && config . CONTAINER_ENV !== undefined ) {
100+ this . CONTAINERS = [
101+ {
102+ imageUri : "" , // Populated later with props.containerImageUri
103+ environment : config . CONTAINER_ENV as Record < string , unknown > ,
104+ repositoryAccessMode : ( config . REPOSITORY_ACCESS_MODE ||
105+ "Platform" ) as string
106+ }
107+ ] ;
108+ } else if ( this . CONTAINERS . length === 0 ) {
109+ // Ensure we always have a CONTAINERS array - default to an empty container definition
110+ this . CONTAINERS = [
111+ {
112+ imageUri : "" ,
113+ environment : { } as Record < string , unknown > ,
114+ repositoryAccessMode : "Platform"
115+ }
116+ ] ;
117+ }
63118 }
64119}
65120
@@ -151,26 +206,35 @@ export class MESMEndpoint extends Construct {
151206 this . config = [ props . config ] ;
152207 }
153208
154- const models = this . config . map (
155- ( config ) =>
156- new CfnModel ( this , `${ id } -${ config . VARIANT_NAME } ` , {
157- executionRoleArn : props . roleArn ,
158- containers : [
159- {
160- image : props . containerImageUri ,
161- environment : config . CONTAINER_ENV ,
162- imageConfig : {
163- repositoryAccessMode :
164- config . REPOSITORY_ACCESS_MODE || "Platform"
165- }
166- }
167- ] ,
168- vpcConfig : {
169- subnets : props . subnetIds ,
170- securityGroupIds : [ config . SECURITY_GROUP_ID ]
171- }
172- } )
173- ) ;
209+ const models = this . config . map ( ( config ) => {
210+ // Set the imageUri for containers that don't have one specified. This
211+ // handles the legacy conversion case where imageUri was initially empty.
212+ config . CONTAINERS = config . CONTAINERS . map ( ( container ) => ( {
213+ ...container ,
214+ imageUri : container . imageUri || props . containerImageUri
215+ } ) ) ;
216+
217+ // Map to the SageMaker container format
218+ const containers = config . CONTAINERS . map ( ( container , index ) => ( {
219+ image : container . imageUri ,
220+ environment : container . environment || { } ,
221+ imageConfig : {
222+ repositoryAccessMode : container . repositoryAccessMode || "Platform"
223+ } ,
224+ containerHostname : container . containerHostname || `container-${ index } `
225+ } ) ) ;
226+
227+ return new CfnModel ( this , `${ id } -${ config . VARIANT_NAME } ` , {
228+ executionRoleArn : props . roleArn ,
229+ containers : containers ,
230+ inferenceExecutionConfig :
231+ containers . length > 1 ? { mode : "Direct" } : undefined ,
232+ vpcConfig : {
233+ subnets : props . subnetIds ,
234+ securityGroupIds : [ config . SECURITY_GROUP_ID ]
235+ }
236+ } ) ;
237+ } ) ;
174238
175239 this . endpointConfig = new CfnEndpointConfig ( this , `${ id } -EndpointConfig` , {
176240 productionVariants : this . config . map ( ( config , i ) => ( {
0 commit comments