From dfea72118790ea591d9de720f337c1e14eb11411 Mon Sep 17 00:00:00 2001 From: Colin Francis <131073567+colifran@users.noreply.github.com> Date: Wed, 22 May 2024 08:36:51 -0700 Subject: [PATCH] fix(stepfunctions-tasks): runtime language used to evaluate expressions is ignored (#30302) ### Reason for this change `EvaluateExpression` exposes a runtime property that can be used to configure the runtime language used to evaluate an expression. When the handler for this was migrated into the handler framework we hid the runtime property and didn't make it configurable. As a result, when the runtime property is specified as part of `EvaluateExpressionProps` it ends up being dropped in place of the code generated runtime. ### Description of changes Added a configurable runtime property to the generated `EvalNodejsSingletonFunctionProps` interface and set this property using runtime property on `EvaluateExpressionProps` if one was provided. Otherwise, the current node 18 default is used. ### Description of how you validated changes Unit test for codegen with eval-nodejs-provider. Integ test for default `EvaluateExpression` runtime (we already test a configurable runtime, unfortunately this was the same as the default so this bug was not caught). ### 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* --- ...efaultTestDeployAssert03097648.assets.json | 19 + ...aultTestDeployAssert03097648.template.json | 36 ++ .../index.js | 1 + ...pression-default-runtime-integ.assets.json | 32 ++ ...ession-default-runtime-integ.template.json | 203 ++++++++ .../cdk.out | 1 + .../integ.json | 13 + .../manifest.json | 143 ++++++ .../tree.json | 452 ++++++++++++++++++ ...teg.evaluate-expression-default-runtime.ts | 56 +++ .../lib/custom-resources-framework/classes.ts | 24 +- .../lib/custom-resources-framework/modules.ts | 1 + .../singleton-function-eval-nodejs.ts | 46 ++ .../framework.test.ts | 19 + .../lib/evaluate-expression.ts | 1 + 15 files changed, 1045 insertions(+), 2 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/asset.b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136/index.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.ts create mode 100644 packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/expected/singleton-function-eval-nodejs.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets.json new file mode 100644 index 0000000000000..bbb4843078130 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "EvaluateExpressionIntegDefaultTestDeployAssert03097648.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/EvaluateExpressionIntegDefaultTestDeployAssert03097648.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/asset.b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/asset.b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136/index.js new file mode 100644 index 0000000000000..d3d578f964997 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/asset.b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136/index.js @@ -0,0 +1 @@ +"use strict";var o=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var c=(e,n)=>{for(var s in n)o(e,s,{get:n[s],enumerable:!0})},l=(e,n,s,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of a(n))!p.call(e,r)&&r!==s&&o(e,r,{get:()=>n[r],enumerable:!(t=i(n,r))||t.enumerable});return e};var g=e=>l(o({},"__esModule",{value:!0}),e);var y={};c(y,{handler:()=>u});module.exports=g(y);function x(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}async function u(e){console.log("Event: %j",{...e,ResponseURL:"..."});let n=Object.entries(e.expressionAttributeValues).reduce((s,[t,r])=>s.replace(new RegExp(x(t),"g"),JSON.stringify(r)),e.expression);return console.log(`Expression: ${n}`),[eval][0](n)}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.assets.json new file mode 100644 index 0000000000000..80cc8f0312478 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.assets.json @@ -0,0 +1,32 @@ +{ + "version": "36.0.0", + "files": { + "b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136": { + "source": { + "path": "asset.b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "5e83ca232751b5c70c12bedc5f6577d86957be3f519354a80f9fdfebf2e2b6a8": { + "source": { + "path": "cdk-sfn-evaluate-expression-default-runtime-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "5e83ca232751b5c70c12bedc5f6577d86957be3f519354a80f9fdfebf2e2b6a8.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.template.json new file mode 100644 index 0000000000000..367ba786d526e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk-sfn-evaluate-expression-default-runtime-integ.template.json @@ -0,0 +1,203 @@ +{ + "Resources": { + "Eval41256dc5445742738ed917bc818694e5ServiceRoleA1AB6027": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "Eval41256dc5445742738ed917bc818694e54EB1134F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136.zip" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e5ServiceRoleA1AB6027", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "Eval41256dc5445742738ed917bc818694e5ServiceRoleA1AB6027" + ] + }, + "StateMachineRoleB840431D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachineRoleDefaultPolicyDF1E6607": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + ":*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRoleDefaultPolicyDF1E6607", + "Roles": [ + { + "Ref": "StateMachineRoleB840431D" + } + ] + } + }, + "StateMachine2E01A3A5": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"Sum\",\"States\":{\"Sum\":{\"Next\":\"Multiply\",\"Type\":\"Task\",\"ResultPath\":\"$.c\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + "\",\"Parameters\":{\"expression\":\"$.a + $.b\",\"expressionAttributeValues\":{\"$.a.$\":\"$.a\",\"$.b.$\":\"$.b\"}}},\"Multiply\":{\"Next\":\"Wait\",\"Type\":\"Task\",\"ResultPath\":\"$.d\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + "\",\"Parameters\":{\"expression\":\"$.c * 2\",\"expressionAttributeValues\":{\"$.c.$\":\"$.c\"}}},\"Wait\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.d\",\"Next\":\"Now\"},\"Now\":{\"End\":true,\"Type\":\"Task\",\"ResultPath\":\"$.now\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + "\",\"Parameters\":{\"expression\":\"(new Date()).toUTCString()\",\"expressionAttributeValues\":{}}}}}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + } + }, + "DependsOn": [ + "StateMachineRoleDefaultPolicyDF1E6607", + "StateMachineRoleB840431D" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Outputs": { + "StateMachineARN": { + "Value": { + "Ref": "StateMachine2E01A3A5" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/integ.json new file mode 100644 index 0000000000000..ea89852646656 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "36.0.0", + "testCases": { + "EvaluateExpressionInteg/DefaultTest": { + "stacks": [ + "cdk-sfn-evaluate-expression-default-runtime-integ" + ], + "diffAssets": true, + "assertionStack": "EvaluateExpressionInteg/DefaultTest/DeployAssert", + "assertionStackName": "EvaluateExpressionIntegDefaultTestDeployAssert03097648" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/manifest.json new file mode 100644 index 0000000000000..ecd870f0a9862 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/manifest.json @@ -0,0 +1,143 @@ +{ + "version": "36.0.0", + "artifacts": { + "cdk-sfn-evaluate-expression-default-runtime-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdk-sfn-evaluate-expression-default-runtime-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdk-sfn-evaluate-expression-default-runtime-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdk-sfn-evaluate-expression-default-runtime-integ.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}/5e83ca232751b5c70c12bedc5f6577d86957be3f519354a80f9fdfebf2e2b6a8.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdk-sfn-evaluate-expression-default-runtime-integ.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdk-sfn-evaluate-expression-default-runtime-integ.assets" + ], + "metadata": { + "/cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Eval41256dc5445742738ed917bc818694e5ServiceRoleA1AB6027" + } + ], + "/cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Eval41256dc5445742738ed917bc818694e54EB1134F" + } + ], + "/cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineRoleB840431D" + } + ], + "/cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineRoleDefaultPolicyDF1E6607" + } + ], + "/cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachine2E01A3A5" + } + ], + "/cdk-sfn-evaluate-expression-default-runtime-integ/StateMachineARN": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineARN" + } + ], + "/cdk-sfn-evaluate-expression-default-runtime-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-sfn-evaluate-expression-default-runtime-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-sfn-evaluate-expression-default-runtime-integ" + }, + "EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "EvaluateExpressionIntegDefaultTestDeployAssert03097648": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "EvaluateExpressionIntegDefaultTestDeployAssert03097648.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}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "EvaluateExpressionIntegDefaultTestDeployAssert03097648.assets" + ], + "metadata": { + "/EvaluateExpressionInteg/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/EvaluateExpressionInteg/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "EvaluateExpressionInteg/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/tree.json new file mode 100644 index 0000000000000..775932b6032f9 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.js.snapshot/tree.json @@ -0,0 +1,452 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "cdk-sfn-evaluate-expression-default-runtime-integ": { + "id": "cdk-sfn-evaluate-expression-default-runtime-integ", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ", + "children": { + "Sum": { + "id": "Sum", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Sum", + "children": { + "EvalFunction": { + "id": "EvalFunction", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Sum/EvalFunction", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions_tasks.EvaluateExpression", + "version": "0.0.0" + } + }, + "Eval41256dc5445742738ed917bc818694e5": { + "id": "Eval41256dc5445742738ed917bc818694e5", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/Code/Stage", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/Code/AssetBucket", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3_assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Eval41256dc5445742738ed917bc818694e5/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "b8cec122f25692e8b194663d25a2ee5e0b65e55df966120791d6a3ddc08fc136.zip" + }, + "handler": "index.handler", + "role": { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e5ServiceRoleA1AB6027", + "Arn" + ] + }, + "runtime": "nodejs18.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", + "version": "0.0.0" + } + }, + "Multiply": { + "id": "Multiply", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Multiply", + "children": { + "EvalFunction": { + "id": "EvalFunction", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Multiply/EvalFunction", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions_tasks.EvaluateExpression", + "version": "0.0.0" + } + }, + "Now": { + "id": "Now", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Now", + "children": { + "EvalFunction": { + "id": "EvalFunction", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Now/EvalFunction", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions_tasks.EvaluateExpression", + "version": "0.0.0" + } + }, + "Wait": { + "id": "Wait", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/Wait", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Wait", + "version": "0.0.0" + } + }, + "StateMachine": { + "id": "StateMachine", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine", + "children": { + "Role": { + "id": "Role", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/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": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + ":*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "policyName": "StateMachineRoleDefaultPolicyDF1E6607", + "roles": [ + { + "Ref": "StateMachineRoleB840431D" + } + ] + } + }, + "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": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachine/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"Sum\",\"States\":{\"Sum\":{\"Next\":\"Multiply\",\"Type\":\"Task\",\"ResultPath\":\"$.c\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + "\",\"Parameters\":{\"expression\":\"$.a + $.b\",\"expressionAttributeValues\":{\"$.a.$\":\"$.a\",\"$.b.$\":\"$.b\"}}},\"Multiply\":{\"Next\":\"Wait\",\"Type\":\"Task\",\"ResultPath\":\"$.d\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + "\",\"Parameters\":{\"expression\":\"$.c * 2\",\"expressionAttributeValues\":{\"$.c.$\":\"$.c\"}}},\"Wait\":{\"Type\":\"Wait\",\"SecondsPath\":\"$.d\",\"Next\":\"Now\"},\"Now\":{\"End\":true,\"Type\":\"Task\",\"ResultPath\":\"$.now\",\"Resource\":\"", + { + "Fn::GetAtt": [ + "Eval41256dc5445742738ed917bc818694e54EB1134F", + "Arn" + ] + }, + "\",\"Parameters\":{\"expression\":\"(new Date()).toUTCString()\",\"expressionAttributeValues\":{}}}}}" + ] + ] + }, + "roleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "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": "cdk-sfn-evaluate-expression-default-runtime-integ/StateMachineARN", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-sfn-evaluate-expression-default-runtime-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "EvaluateExpressionInteg": { + "id": "EvaluateExpressionInteg", + "path": "EvaluateExpressionInteg", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "EvaluateExpressionInteg/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "EvaluateExpressionInteg/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "EvaluateExpressionInteg/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "EvaluateExpressionInteg/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "EvaluateExpressionInteg/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.ts new file mode 100644 index 0000000000000..5e14b1c123ae8 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/integ.evaluate-expression-default-runtime.ts @@ -0,0 +1,56 @@ +import { App, Stack, StackProps } from 'aws-cdk-lib'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import { Construct } from 'constructs'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; +import * as cdk from 'aws-cdk-lib'; +import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks'; + +/* + * Stack verification steps: + * * aws stepfunctions start-execution --input '{"a": 3, "b": 4}' --state-machine-arn + * * aws stepfunctions describe-execution --execution-arn + * * The output here should contain `status: "SUCCEEDED"` and `output: "{ a: 3, b: 4, c: 7, d: 14, now: }" + */ + +class TestStack extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + const sum = new tasks.EvaluateExpression(this, 'Sum', { + expression: '$.a + $.b', + resultPath: '$.c', + }); + + const multiply = new tasks.EvaluateExpression(this, 'Multiply', { + expression: '$.c * 2', + resultPath: '$.d', + }); + + const now = new tasks.EvaluateExpression(this, 'Now', { + expression: '(new Date()).toUTCString()', + resultPath: '$.now', + }); + + const statemachine = new sfn.StateMachine(this, 'StateMachine', { + definition: sum + .next(multiply) + .next( + new sfn.Wait(this, 'Wait', { + time: sfn.WaitTime.secondsPath('$.d'), + }), + ) + .next(now), + }); + + new cdk.CfnOutput(this, 'StateMachineARN', { + value: statemachine.stateMachineArn, + }); + } +} + +const app = new App(); + +new integ.IntegTest(app, 'EvaluateExpressionInteg', { + testCases: [new TestStack(app, 'cdk-sfn-evaluate-expression-default-runtime-integ')], + diffAssets: true, +}); diff --git a/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/classes.ts b/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/classes.ts index ed9e24231a699..19311d5120a70 100644 --- a/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/classes.ts +++ b/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/classes.ts @@ -127,6 +127,8 @@ export abstract class HandlerFrameworkClass extends ClassType { export: true, }); + const isEvalNodejsProvider = this.fqn.includes('eval-nodejs-provider'); + this.importExternalModulesInto(scope); const uuid: PropertySpec = { @@ -149,11 +151,29 @@ export abstract class HandlerFrameworkClass extends ClassType { }, }, }; + const properties = [uuid, lambdaPurpose]; + // eval nodejs provider is a one off scenario where the provider makes its runtime property configurable - to maintain this + // functionality we need to expose it as well + if (isEvalNodejsProvider) { + const runtime: PropertySpec = { + name: 'runtime', + type: LAMBDA_MODULE.Runtime, + immutable: true, + optional: true, + docs: { + summary: 'The runtime that this Lambda will use.', + docTags: { + default: 'lambda.Runtime.NODEJS_18_X', + }, + }, + }; + properties.push(runtime); + } const _interface = this.getOrCreateInterface(scope, { name: `${this.name}Props`, export: true, extends: [LAMBDA_MODULE.FunctionOptions], - properties: [uuid, lambdaPurpose], + properties, docs: { summary: `Initialization properties for ${this.name}`, }, @@ -163,7 +183,7 @@ export abstract class HandlerFrameworkClass extends ClassType { new Splat(expr.ident('props')), ['code', expr.directCode(`lambda.Code.fromAsset(path.join(__dirname, '${props.codeDirectory}'))`)], ['handler', expr.lit(props.handler)], - ['runtime', expr.directCode(toLambdaRuntime(props.runtime))], + ['runtime', expr.directCode(`${isEvalNodejsProvider ? 'props.runtime ?? ' : ''}${toLambdaRuntime(props.runtime)}`)], ]); this.buildConstructor({ constructorPropsType: _interface.type, diff --git a/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/modules.ts b/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/modules.ts index 9b2f349a06cd7..591306c7b9439 100644 --- a/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/modules.ts +++ b/packages/@aws-cdk/custom-resource-handlers/lib/custom-resources-framework/modules.ts @@ -46,6 +46,7 @@ class LambdaModule extends ExternalModule { public readonly Function = Type.fromName(this, 'Function'); public readonly SingletonFunction = Type.fromName(this, 'SingletonFunction'); public readonly FunctionOptions = Type.fromName(this, 'FunctionOptions'); + public readonly Runtime = Type.fromName(this, 'Runtime'); public constructor() { super('../../../aws-lambda'); diff --git a/packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/expected/singleton-function-eval-nodejs.ts b/packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/expected/singleton-function-eval-nodejs.ts new file mode 100644 index 0000000000000..d05eb9772f902 --- /dev/null +++ b/packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/expected/singleton-function-eval-nodejs.ts @@ -0,0 +1,46 @@ +/* eslint-disable prettier/prettier,max-len */ +import * as path from "path"; +import { Construct } from "constructs"; +import * as lambda from "../../../aws-lambda"; + +export class EvalNodejsSingletonFunction extends lambda.SingletonFunction { + public constructor(scope: Construct, id: string, props: EvalNodejsSingletonFunctionProps) { + super(scope, id, { + ...props, + "code": lambda.Code.fromAsset(path.join(__dirname, 'my-handler')), + "handler": "index.handler", + "runtime": props.runtime ?? lambda.Runtime.NODEJS_18_X + }); + } +} + +/** + * Initialization properties for EvalNodejsSingletonFunction + */ +export interface EvalNodejsSingletonFunctionProps extends lambda.FunctionOptions { + /** + * A unique identifier to identify this Lambda. + * + * The identifier should be unique across all custom resource providers. + * We recommend generating a UUID per provider. + */ + readonly uuid: string; + + /** + * A descriptive name for the purpose of this Lambda. + * + * If the Lambda does not have a physical name, this string will be + * reflected in its generated name. The combination of lambdaPurpose + * and uuid must be unique. + * + * @default SingletonLambda + */ + readonly lambdaPurpose?: string; + + /** + * The runtime that this Lambda will use. + * + * @default lambda.Runtime.NODEJS_18_X + */ + readonly runtime?: lambda.Runtime; +} \ No newline at end of file diff --git a/packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/framework.test.ts b/packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/framework.test.ts index 14e4ee2491f45..116495b11baa0 100644 --- a/packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/framework.test.ts +++ b/packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/framework.test.ts @@ -90,4 +90,23 @@ describe('framework', () => { const expected = fs.readFileSync(path.resolve(__dirname, 'expected', 'custom-resource-provider-core.ts'), 'utf-8'); expect(result).toContain(expected); }); + + test('codegen eval-nodejs-provider with exposed runtime property', () => { + // GIVEN + const module = new HandlerFrameworkModule('cdk-testing/eval-nodejs-provider'); + const component: ComponentProps = { + type: ComponentType.SINGLETON_FUNCTION, // eval-nodejs-provider is a singleton function + sourceCode, + }; + const outfile = calculateOutfile(sourceCode); + module.build(component, path.dirname(outfile).split('/').pop() ?? 'dist'); + + // WHEN + module.renderTo(`${tmpDir}/result.ts`); + + // THEN + const result = fs.readFileSync(path.resolve(tmpDir, 'result.ts'), 'utf-8'); + const expected = fs.readFileSync(path.resolve(__dirname, 'expected', 'singleton-function-eval-nodejs.ts'), 'utf-8'); + expect(result).toContain(expected); + }); }); diff --git a/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/evaluate-expression.ts b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/evaluate-expression.ts index e6d742a2ed2a9..595edb29882f4 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/evaluate-expression.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/evaluate-expression.ts @@ -119,5 +119,6 @@ function createEvalFn(runtime: lambda.Runtime | undefined, scope: Construct) { return new EvalNodejsSingletonFunction(scope, 'EvalFunction', { uuid, lambdaPurpose, + runtime, }); }