From 709843476a2adbfb84f1e718833e6b6547ca1c5e Mon Sep 17 00:00:00 2001 From: Xia Zhao Date: Fri, 23 Aug 2024 14:56:51 -0700 Subject: [PATCH] fix(stepfunctions-tasks): SageMakerCreateTrainingJob does not correctly support empty inputDataConfig --- .../cdk.out | 2 +- .../integ-stepfunctions-sagemaker.assets.json | 6 +- ...nteg-stepfunctions-sagemaker.template.json | 238 ++++++++++++ .../integ.json | 2 +- .../manifest.json | 41 +- .../tree.json | 353 +++++++++++++++++- .../sagemaker/integ.create-training-job.ts | 15 + .../lib/sagemaker/create-training-job.ts | 13 +- .../sagemaker/create-training-job.test.ts | 52 +++ 9 files changed, 710 insertions(+), 12 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/cdk.out index 560dae10d018f..bd5311dc372de 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"33.0.0"} \ No newline at end of file +{"version":"36.0.5"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.assets.json index 348af0fc6edfa..97dc6a63ed732 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.assets.json @@ -1,7 +1,7 @@ { - "version": "33.0.0", + "version": "36.0.5", "files": { - "11bc70dd89e4afb387b1b639ea823eb492c0e7a7dd664e50aa483f10ef3e204a": { + "5052c67d354503fa1171f1d73a3f241505423ddfffd57ff1d7985c2ae028c0db": { "source": { "path": "integ-stepfunctions-sagemaker.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "11bc70dd89e4afb387b1b639ea823eb492c0e7a7dd664e50aa483f10ef3e204a.json", + "objectKey": "5052c67d354503fa1171f1d73a3f241505423ddfffd57ff1d7985c2ae028c0db.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.template.json index c3525778207e9..61099aecf6a53 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ-stepfunctions-sagemaker.template.json @@ -332,6 +332,239 @@ ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "TrainTaskAnotherSagemakerRoleBD8363A2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sagemaker.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "cloudwatch:PutMetricData", + "ecr:GetAuthorizationToken", + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:DescribeLogStreams", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "CreateTrainingJob" + } + ] + } + }, + "TrainTaskAnotherSagemakerRoleDefaultPolicy67E5C282": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "TrainingData3FDB6D34", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "TrainingData3FDB6D34", + "Arn" + ] + }, + "/result/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "EncryptionKey1B843E66", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TrainTaskAnotherSagemakerRoleDefaultPolicy67E5C282", + "Roles": [ + { + "Ref": "TrainTaskAnotherSagemakerRoleBD8363A2" + } + ] + } + }, + "StateMachineAnotherRoleB3F4936A": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachineAnotherRoleDefaultPolicy5D4FD497": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "sagemaker:CreateTrainingJob", + "sagemaker:DescribeTrainingJob", + "sagemaker:StopTrainingJob" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":sagemaker:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":training-job/mytrainingjob*" + ] + ] + } + }, + { + "Action": "sagemaker:ListTags", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "iam:PassRole", + "Condition": { + "StringEquals": { + "iam:PassedToService": "sagemaker.amazonaws.com" + } + }, + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TrainTaskAnotherSagemakerRoleBD8363A2", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineAnotherRoleDefaultPolicy5D4FD497", + "Roles": [ + { + "Ref": "StateMachineAnotherRoleB3F4936A" + } + ] + } + }, + "StateMachineAnother9B75AA58": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"TrainTaskAnother\",\"States\":{\"TrainTaskAnother\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::sagemaker:createTrainingJob\",\"Parameters\":{\"TrainingJobName\":\"mytrainingjob\",\"RoleArn\":\"", + { + "Fn::GetAtt": [ + "TrainTaskAnotherSagemakerRoleBD8363A2", + "Arn" + ] + }, + "\",\"AlgorithmSpecification\":{\"TrainingInputMode\":\"FastFile\",\"AlgorithmName\":\"BlazingText\"},\"OutputDataConfig\":{\"S3OutputPath\":\"https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Ref": "TrainingData3FDB6D34" + }, + "/result/\"},\"ResourceConfig\":{\"InstanceCount\":1,\"InstanceType\":\"ml.m4.xlarge\",\"VolumeSizeInGB\":10},\"StoppingCondition\":{\"MaxRuntimeInSeconds\":3600}}}}}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineAnotherRoleB3F4936A", + "Arn" + ] + } + }, + "DependsOn": [ + "StateMachineAnotherRoleDefaultPolicy5D4FD497", + "StateMachineAnotherRoleB3F4936A" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" } }, "Outputs": { @@ -339,6 +572,11 @@ "Value": { "Ref": "StateMachine2E01A3A5" } + }, + "stateMachineArn2": { + "Value": { + "Ref": "StateMachineAnother9B75AA58" + } } }, "Parameters": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ.json index 77a3a44fc5844..22cdd90ed9927 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "33.0.0", + "version": "36.0.5", "testCases": { "integ.create-training-job": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/manifest.json index 43d36434b4bfc..8726f6828a015 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "33.0.0", + "version": "36.0.5", "artifacts": { "integ-stepfunctions-sagemaker.assets": { "type": "cdk:asset-manifest", @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "integ-stepfunctions-sagemaker.template.json", + "terminationProtection": false, "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/11bc70dd89e4afb387b1b639ea823eb492c0e7a7dd664e50aa483f10ef3e204a.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/5052c67d354503fa1171f1d73a3f241505423ddfffd57ff1d7985c2ae028c0db.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -75,12 +76,48 @@ "data": "StateMachine2E01A3A5" } ], + "/integ-stepfunctions-sagemaker/TrainTaskAnother/SagemakerRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TrainTaskAnotherSagemakerRoleBD8363A2" + } + ], + "/integ-stepfunctions-sagemaker/TrainTaskAnother/SagemakerRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TrainTaskAnotherSagemakerRoleDefaultPolicy67E5C282" + } + ], + "/integ-stepfunctions-sagemaker/StateMachineAnother/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineAnotherRoleB3F4936A" + } + ], + "/integ-stepfunctions-sagemaker/StateMachineAnother/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineAnotherRoleDefaultPolicy5D4FD497" + } + ], + "/integ-stepfunctions-sagemaker/StateMachineAnother/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineAnother9B75AA58" + } + ], "/integ-stepfunctions-sagemaker/stateMachineArn": [ { "type": "aws:cdk:logicalId", "data": "stateMachineArn" } ], + "/integ-stepfunctions-sagemaker/stateMachineArn2": [ + { + "type": "aws:cdk:logicalId", + "data": "stateMachineArn2" + } + ], "/integ-stepfunctions-sagemaker/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/tree.json index 3f52cb2cf799f..936ce08ac7128 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.js.snapshot/tree.json @@ -483,6 +483,349 @@ "version": "0.0.0" } }, + "TrainTaskAnother": { + "id": "TrainTaskAnother", + "path": "integ-stepfunctions-sagemaker/TrainTaskAnother", + "children": { + "SagemakerRole": { + "id": "SagemakerRole", + "path": "integ-stepfunctions-sagemaker/TrainTaskAnother/SagemakerRole", + "children": { + "ImportSagemakerRole": { + "id": "ImportSagemakerRole", + "path": "integ-stepfunctions-sagemaker/TrainTaskAnother/SagemakerRole/ImportSagemakerRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-stepfunctions-sagemaker/TrainTaskAnother/SagemakerRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sagemaker.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "policies": [ + { + "policyName": "CreateTrainingJob", + "policyDocument": { + "Statement": [ + { + "Action": [ + "cloudwatch:PutMetricData", + "ecr:GetAuthorizationToken", + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:DescribeLogStreams", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "integ-stepfunctions-sagemaker/TrainTaskAnother/SagemakerRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-stepfunctions-sagemaker/TrainTaskAnother/SagemakerRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "TrainingData3FDB6D34", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "TrainingData3FDB6D34", + "Arn" + ] + }, + "/result/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "EncryptionKey1B843E66", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "TrainTaskAnotherSagemakerRoleDefaultPolicy67E5C282", + "roles": [ + { + "Ref": "TrainTaskAnotherSagemakerRoleBD8363A2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions_tasks.SageMakerCreateTrainingJob", + "version": "0.0.0" + } + }, + "StateMachineAnother": { + "id": "StateMachineAnother", + "path": "integ-stepfunctions-sagemaker/StateMachineAnother", + "children": { + "Role": { + "id": "Role", + "path": "integ-stepfunctions-sagemaker/StateMachineAnother/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "integ-stepfunctions-sagemaker/StateMachineAnother/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-stepfunctions-sagemaker/StateMachineAnother/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "integ-stepfunctions-sagemaker/StateMachineAnother/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "integ-stepfunctions-sagemaker/StateMachineAnother/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "sagemaker:CreateTrainingJob", + "sagemaker:DescribeTrainingJob", + "sagemaker:StopTrainingJob" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":sagemaker:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":training-job/mytrainingjob*" + ] + ] + } + }, + { + "Action": "sagemaker:ListTags", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": "iam:PassRole", + "Condition": { + "StringEquals": { + "iam:PassedToService": "sagemaker.amazonaws.com" + } + }, + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TrainTaskAnotherSagemakerRoleBD8363A2", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "StateMachineAnotherRoleDefaultPolicy5D4FD497", + "roles": [ + { + "Ref": "StateMachineAnotherRoleB3F4936A" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-stepfunctions-sagemaker/StateMachineAnother/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"TrainTaskAnother\",\"States\":{\"TrainTaskAnother\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::sagemaker:createTrainingJob\",\"Parameters\":{\"TrainingJobName\":\"mytrainingjob\",\"RoleArn\":\"", + { + "Fn::GetAtt": [ + "TrainTaskAnotherSagemakerRoleBD8363A2", + "Arn" + ] + }, + "\",\"AlgorithmSpecification\":{\"TrainingInputMode\":\"FastFile\",\"AlgorithmName\":\"BlazingText\"},\"OutputDataConfig\":{\"S3OutputPath\":\"https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Ref": "TrainingData3FDB6D34" + }, + "/result/\"},\"ResourceConfig\":{\"InstanceCount\":1,\"InstanceType\":\"ml.m4.xlarge\",\"VolumeSizeInGB\":10},\"StoppingCondition\":{\"MaxRuntimeInSeconds\":3600}}}}}" + ] + ] + }, + "roleArn": { + "Fn::GetAtt": [ + "StateMachineAnotherRoleB3F4936A", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, "stateMachineArn": { "id": "stateMachineArn", "path": "integ-stepfunctions-sagemaker/stateMachineArn", @@ -491,6 +834,14 @@ "version": "0.0.0" } }, + "stateMachineArn2": { + "id": "stateMachineArn2", + "path": "integ-stepfunctions-sagemaker/stateMachineArn2", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "integ-stepfunctions-sagemaker/BootstrapVersion", @@ -518,7 +869,7 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.2.69" + "version": "10.3.0" } } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.ts index 3d3e138e080cd..827ace050ffd1 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/sagemaker/integ.create-training-job.ts @@ -51,6 +51,21 @@ const sm = new StateMachine(stack, 'StateMachine', { }), }); +const smWithoutInputData = new StateMachine(stack, 'StateMachineAnother', { + definition: new SageMakerCreateTrainingJob(stack, 'TrainTaskAnother', { + algorithmSpecification: { + algorithmName: 'BlazingText', + trainingInputMode: InputMode.FAST_FILE, + }, + outputDataConfig: { s3OutputLocation: S3Location.fromBucket(trainingData, 'result/') }, + trainingJobName: 'mytrainingjob', + }), +}); + new CfnOutput(stack, 'stateMachineArn', { value: sm.stateMachineArn, }); + +new CfnOutput(stack, 'stateMachineArn2', { + value: smWithoutInputData.stateMachineArn, +}); diff --git a/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts index ff2ac0c76e94e..22b77e783089d 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/sagemaker/create-training-job.ts @@ -50,8 +50,10 @@ export interface SageMakerCreateTrainingJobProps extends sfn.TaskStateBaseProps /** * Describes the various datasets (e.g. train, validation, test) and the Amazon S3 location where stored. + * + * @default - No inputDataConfig */ - readonly inputDataConfig: Channel[]; + readonly inputDataConfig?: Channel[]; /** * Tags to be applied to the train job. @@ -120,7 +122,7 @@ export class SageMakerCreateTrainingJob extends sfn.TaskStateBase implements iam /** * The Input Data Config. */ - private readonly inputDataConfig: Channel[]; + private readonly inputDataConfig?: Channel[]; /** * The resource config for the task. @@ -177,7 +179,7 @@ export class SageMakerCreateTrainingJob extends sfn.TaskStateBase implements iam : { ...props.algorithmSpecification, trainingInputMode: InputMode.FILE }; // set the S3 Data type of the input data config objects to be 'S3Prefix' if not defined - this.inputDataConfig = props.inputDataConfig.map((config) => { + this.inputDataConfig = props.inputDataConfig?.map((config) => { if (!config.dataSource.s3DataSource.s3DataType) { return { ...config, @@ -266,7 +268,10 @@ export class SageMakerCreateTrainingJob extends sfn.TaskStateBase implements iam }; } - private renderInputDataConfig(config: Channel[]): { [key: string]: any } { + private renderInputDataConfig(config?: Channel[]): { [key: string]: any } { + if (!config) { + return {}; + } return { InputDataConfig: config.map((channel) => ({ ChannelName: channel.channelName, diff --git a/packages/aws-cdk-lib/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts b/packages/aws-cdk-lib/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts index 7ed4df320de10..536af2f5af59f 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions-tasks/test/sagemaker/create-training-job.test.ts @@ -89,6 +89,58 @@ test('create basic training job', () => { }); }); +test('create basic training job without inputDataConfig', () => { + // WHEN + const task = new SageMakerCreateTrainingJob(stack, 'TrainSagemaker', { + trainingJobName: 'MyTrainJob', + algorithmSpecification: { + algorithmName: 'BlazingText', + }, + outputDataConfig: { + s3OutputLocation: tasks.S3Location.fromBucket(s3.Bucket.fromBucketName(stack, 'OutputBucket', 'mybucket'), 'myoutputpath'), + }, + }); + + // THEN + expect(stack.resolve(task.toStateJson())).toEqual({ + Type: 'Task', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::sagemaker:createTrainingJob', + ], + ], + }, + End: true, + Parameters: { + AlgorithmSpecification: { + AlgorithmName: 'BlazingText', + TrainingInputMode: 'File', + }, + OutputDataConfig: { + S3OutputPath: { + 'Fn::Join': ['', ['https://s3.', { Ref: 'AWS::Region' }, '.', { Ref: 'AWS::URLSuffix' }, '/mybucket/myoutputpath']], + }, + }, + ResourceConfig: { + InstanceCount: 1, + InstanceType: 'ml.m4.xlarge', + VolumeSizeInGB: 10, + }, + RoleArn: { 'Fn::GetAtt': ['TrainSagemakerSagemakerRole89E8C593', 'Arn'] }, + StoppingCondition: { + MaxRuntimeInSeconds: 3600, + }, + TrainingJobName: 'MyTrainJob', + }, + }); +}); + test('Task throws if WAIT_FOR_TASK_TOKEN is supplied as service integration pattern', () => { expect(() => { new SageMakerCreateTrainingJob(stack, 'TrainSagemaker', {