1

I've got a LambdaInvoke which is part of a state machine. I've specified input_path="$$.Execution" to give it the state machine execution ARN. Now, how do I give the LambdaFunction belonging to the LambdaInvoke access to states:DescribeExecution on the StateMachine it's part of?

Both state_machine.grant_read(lambda_invoke.lambda_function) and lambda_function.role.add_to_policy(aws_iam.PolicyStatement(resources=[state_machine.state_machine_arn], actions=["states:DescribeExecution"]) result in CloudFormation failing because of a "Circular dependency between resources". The list of dependencies:

  1. The default policy of the role of the Lambda function above
  2. The default policy of the role of another Lambda function which launches the state machine
  3. The Lambda function which launches the state machine
  4. The state machine
  5. The Lambda function in step 1
  6. The stack containing the Lambda function which launches the state machine
l0b0
  • 55,365
  • 30
  • 138
  • 223

1 Answers1

2

Irrespective of how a StateMachine is started there are 2 different roles, one for your Lambda function and one for your StateMachine. Lets have a look at sending a message to sqs as an example. You could do that directly with your StateMachine with sqs integration, or you could have a Lambda which would do it for you.

StateMachine Role

The role given to the StateMachine is needed for purposes such as logging, but also depending what integration's you use, such as if you have sqs:sendMessage it will need to have an sqs policy attached to enable that. If you use Lambda Functions in your StateMachine you will need to have a policy for lambda:InvokeFunction.

Lambda Function Role Lets say you have a Lambda which sends a message to SQS you don't use the arn:aws:states:::sqs:sendMessage... in your definition file, then your StateMachine role needs lambda:InvokeFunction permissions only, but your Lambda needs permissions to sqs.

Now for your use case, your Lambda needs to have permissions to states:DescribeExecution, not sqs. If your Lambda function works in the console successfully, and your StateMachine has permissions to execute that function all should work.

If you have a Lambda launching a StateMachine it only needs access to start a StateMachine.

Circular Dependencies Problem

You don't really have a circular dependency problem you have a permissions problem. Other than creating a new role for every time you would Launch a StateMachine, you can't scope a Lambda to one instance, reason being is that there isn't anything you can reference in the condition key context in the IAM json so that approach doesn't work. You can limit the Lambda to only executions for a particular StateMachine but again it would be for all users.

There isn't actually an inherent need for a Lambda, launched by a StateMachine to describe the very StateMachine it was launched from. Reason being is you could simply pass the state of that StateMachine to that function anyway.

Derrops
  • 7,651
  • 5
  • 30
  • 60
  • In that case the question becomes how to combine the output of other entries in the state machine with the context object (`$$`). I can't find documentation for how the `input_path` argument works in detail. – l0b0 May 12 '21 at 22:59
  • In general you really shouldn't use your execution history as state. Any information you need in a given step should be present in your current state. You should refactor for that if that is the case. If you do have a valid use case that you need so much data in your statemachine you should rather externalize it to a DB. Parallel steps merging together will come out as an array https://stackoverflow.com/questions/54105792/parallel-states-merge-the-output-in-step-function – Derrops May 12 '21 at 23:52
  • I've written a [follow-up question](https://stackoverflow.com/q/67512012/96588). – l0b0 May 12 '21 at 23:55