-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
(aws_stepfunctions_tasks): Unclear how LambdaInvoke works #29473
Comments
This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled. |
experimenting more with the mock server has helped, and it seems that thankfully I don't have to do any JSON decoding on the Lambda response One thing still puzzles me I want to repeat a value from the input at the output of my Lambda task (preferably without doing so from the Lambda side, because this value isn't relevant to that Lambda, only to subsequent steps in my chain) prepare_partitions_task = tasks.LambdaInvoke(
self,
"Invoke-PreparePartitionsLambda",
lambda_function=cast(lambda_.IFunction, self._prepare_partitions_lambda),
invocation_type=tasks.LambdaInvocationType.REQUEST_RESPONSE,
result_selector={
"partitioned.$": "$.Payload",
"batch_size.$": "$.batch_size",
},
) So here But I get:
So the input is not available at the output? (the "input" referenced in the error is just the mocked Lambda response) I'm unclear if it's supposed to be available but it's up to me to manually add that to my mock server config (I hope not, it really feels like that should just be mocking the Lambda output) or if it's just not possible with a I had thought to maybe use |
if instead of using prepare_partitions_task = tasks.LambdaInvoke(
self,
"Invoke-PreparePartitionsLambda",
lambda_function=cast(lambda_.IFunction, self._prepare_partitions_lambda),
invocation_type=tasks.LambdaInvocationType.REQUEST_RESPONSE,
output_path="$.Payload",
result_path="$.partitioned",
) ...then I get:
where "input" referred in the error seems to be the contents of |
This works on the mock server: prepare_partitions_task = tasks.LambdaInvoke(
self,
"Invoke-PreparePartitionsLambda",
lambda_function=cast(lambda_.IFunction, self._prepare_partitions_lambda),
invocation_type=tasks.LambdaInvocationType.REQUEST_RESPONSE,
result_selector={
"partitioned.$": "$.Payload",
"execution_input.$": "States.StringToJson($$.Execution.Input)",
},
).next(
sfn.Pass(
self,
"Batch-size pass-thru",
parameters={
"partitioned.$": "$.partitioned",
"batch_size.$": "$.execution_input.batch_size",
}
)
) however this doesn't work at all if I want to pass through some intermediate output from another step rather than the execution input as above The only solution for that I can think of would be to use a I can do that - I just want to check if this is all expected behaviour and not an inconsistency in the mock server vs real executions? |
ugh, this part was my fault: I had ended up double serializing my json input - the mocked lambda responses were obscuring that from my other statemachine test (passing) so I missed that for a while when this one had all these issues that also explains why I still have a weird problem where
|
I attached a debugger to the mock server and it looked like in the "both" case it had inserted the whole Lambda response under and if I do: output_path="$.partitioned.Payload",
result_path="$.partitioned", then in subsequent step I get: which again looks as if the re-reading the OutputPath docs it seems this is intended behaviour, so my mistake again (seems like the other way around would be more useful though...) Now I went back and tried again with the It looks like this actually does what I need! i.e. effectively applies a The difficulty I had previously in using in particular this part: const fnGetAtt = (expression) => {
return expression[1] && expression[1] === 'Arn' ? expression[0] : expression.join('', expression)
} just substitutes the resource name where an ARN is expected... this is fine for but (it seems to result in a different task type, I get different events in the execution history: I've now rewritten the ASL extractor in Python so that it generates fake ARN where expected: def _fake_arn(value: str) -> str:
return f"arn:aws:lambda:us-east-1:123456789012:function:{value}"
def fn_get_att_resolver(get_att_expr_values: list[str]) -> str:
"""
Best effort to resolve `Fn::GetAtt` expression to string value.
NOTE: we can't easily customise the fake ARN type, for now a
fake Lambda ARN is returned because it's most useful for
Step Functions local mock.
"""
return (
_fake_arn(get_att_expr_values[0])
if (len(get_att_expr_values) > 0 and get_att_expr_values[1] == "Arn")
else "".join(get_att_expr_values)
) i.e. I am using CDK so I've eventually stumbled through all of the above into something that works enough |
Describe the issue
My Lambda function returns JSON data
It's unclear what the return value of the step is though - is it just the JSON that the Lambda itself returns, or is it an "invoke lambda response" JSON? Or something else?
I'm using/attempting to use the Step Functions local testing tool
https://docs.aws.amazon.com/step-functions/latest/dg/sfn-local-mock-cfg-file.html#mock-cfg-mckd-resp-sect:~:text=to%20the%20next.-,Return,-Return%20is%20represented
in the docs there they show example mocked response for a LambdaInvoke step as:
This implies I may need to post-process the output of the lambda step with something like
States.StringToJson($.Payload.body)
?There is a
payloadResponseOnly
option for theLambdaInvoke
construct but again it's not clear what it does.The docs say:
...which is super vague. Does it return
$.Payload.body
? Does it parse it as JSON too? Something else?Whatever it does I am unable to test this option in the local mock tool because it causes it to need a Lambda arn rather than just the Lambda name(?)... I get errors like "CreateStateMachine <= Invalid State Machine Definition: ''SCHEMA_VALIDATION_FAILED: Value is not a valid resource ARN at /States/Process Batch Unit/Branches[0]/States/Invoke-ProcessBatchLambda/Resource" (...since there is no easy way to derive the ASL json from the CDK code I am having to use this other tool
cdk-asl-extractor
to reconstruct it from CF template, but there is no real ARN for the Lambda when testing locally)Links
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_stepfunctions_tasks.LambdaInvoke.html#payload
The text was updated successfully, but these errors were encountered: