Search code examples
pythonpython-3.xaws-cdkaws-step-functions

Create N tasks in step function. One for each lambda function that exists in list


I'm just trying to create a simple step function where each task runs sequentially: task1 -> task2 -> task3

One task for every lambda in lambda_handler_paths = ['/Users/aaronwest/Code/ce-engineering-test-live/tests/tf-senior-engineer/validators/my-other-function/lambda.zip', '/Users/aaronwest/Code/ce-engineering-test-live/tests/tf-senior-engineer/validators/my-function/lambda.zip']

Here's what I been playing with to try and get something working:

def build_state_machine_definition(validators: list) -> dict:
    """Builds a state machine definition for a given list of tests"""

    # Create initial state
    definition = sfn.Chain.start(state=sfn.Pass(self, "Pass"))

    # Loop over tests and add to state machine definition
    for i, validator in enumerate(validators):
        # Get the name of the  lambda function
        lambda_name = validator.split("/")[-2]
        print("lambda_name: " + str(lambda_name))
        lambda_function = _lambda.Function(
            self,
            f"{lambda_name}-lambda",
            runtime=_lambda.Runtime.PYTHON_3_8,
            code=_lambda.Code.from_asset(validator),
            handler="lambda_function.lambda_handler",
            timeout=Duration.seconds(30),
        )

        if i == len(validators) - 1:
            # This is the last LambdaInvoke task
            definition.next(
                tasks.LambdaInvoke(
                    self, f"{lambda_name}-Validation", lambda_function=lambda_function
                )
            )
        else:
            definition.next(
                tasks.LambdaInvoke(
                    self, f"{lambda_name}-Validate", lambda_function=lambda_function
                )
            )

    return definition


state_machine_definition = build_state_machine_definition(lambda_handler_paths)

# Create a single Step Function
sfn.StateMachine(
    self,
    "StateMachine",
    definition=state_machine_definition,
    timeout=Duration.minutes(10),
)

at the moment I'm receiving RuntimeError: Error: State 'Pass' already has a next state


Solution

  • The next() function on an IChainable does not modify the object, but instead returns a new one that would contain the new chain. This means that you need to store the results of these calls in a variable:

    definition = definition.next(...)
    

    instead of

    definition.next(...)