I have an architecture divided in 2 different AWS Accounts. Using AWS SAM, I have a StateMachine (lets call it the parent function) in Account A; and an EventBus, EventRule, and StateMachine (lets call it the child function) all in Account B. The goal is to follow this workflow:
- The parent function sends an event to the EventBus and waits for callback
- The EventRule matches the event from the bus and starts execution of the child function
- The child function finishes execution and sends TaskSuccess or TaskFailure
- The parent function receives the success or failure callback and continues to the next state
So far, the functionality works up until the step 3, where the child function fails during the SendTaskSuccess
and SendTaskFailure
states. The message it gives me is this:
User: arn:aws:sts::Account-B:assumed-role/ChildStateMachineRole/id is not authorized to access this resource (Service: Sfn, Status Code: 400)
As far as I understand from the documentation, the policies for the roles need to allow states:SendTaskSuccess
and states:SendTaskFailure
, and so I added those statements to the policy of the role that starts the execution of the child StateMachine and the role that the EventRule assumes when triggered. But I keep getting the same error.
Here are the relevant AWS SAM definitions:
EventBridge Bus
CustomEventBus:
Type: AWS::Events::EventBus
Properties:
Name: CustomEventBus
CustomEventBusPolicy:
Type: AWS::Events::EventBusPolicy
Properties:
EventBusName: CustomEventBus
StatementId: AllowCrossAccountEvents
Statement:
Effect: Allow
Principal:
AWS: arn:aws:iam::Account-A:root
Action: events:PutEvents
Resource: CustomEventBus.Arn
Parent StateMachine
ParentStateMachine:
Type: AWS::Serverless::StateMachine
Properties:
Policies:
- Statement:
- Effect: Allow
Action:
- events:PutEvents
Resource: CustomEventBus.Arn
{
"States": {
"PutEventState": {
"Type": "Task",
"Resource": "arn:aws:states:::events:putEvents.waitForTaskToken",
"Parameters": {
"Entries": [
{
"Detail": {
"TaskToken.$": "$$.Task.Token",
},
"EventBusName": "CustomEventBus",
}
]
},
"End": true
}
}
}
EventBridge Rule
CustomEventRule:
Type: AWS::Events::Rule
Properties:
EventBusName: CustomEventBus
State: ENABLED
Targets:
- Arn: ChildStateMachine
RoleArn: CustomEventRole.Arn
CustomEventRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws
Action: sts:AssumeRole
Policies:
- PolicyName: ChildStateMachineExecutionPolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- states:StartExecution
Resource: ChildStateMachine.Arn
- Effect: Allow
Action:
- states:SendTaskSuccess
- states:SendTaskFailure
Resource: "*"
Child StateMachine
ChildStateMachine:
Type: AWS::Serverless::StateMachine
Properties:
Role: ChildStateMachineRole.Arn
ChildStateMachineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: states.amazonaws
Action: sts:AssumeRole
Policies:
- PolicyName: ChildStateMachineRolePolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- states:StartExecution
Resource: ChildStateMachine.Arn
- Effect: Allow
Action:
- states:SendTaskSuccess
- states:SendTaskFailure
Resource: "*"
{
"States": {
"SendTaskSuccess": {
"Type": "Task",
"Parameters": {
"Output.$": "$.SomeOutput",
"TaskToken.$": "$.TaskToken"
},
"Resource": "arn:aws:states:::aws-sdk:sfn:sendTaskSuccess",
"Next": "Success"
},
"Success": {
"Type": "Succeed"
},
"SendTaskFailure": {
"Type": "Task",
"Parameters": {
"TaskToken.$": "$.TaskToken",
"Error.$": "$.Failure.Error",
"Cause.$": "$.Failure.Cause"
},
"Resource": "arn:aws:states:::aws-sdk:sfn:sendTaskFailure",
"Next": "Fail"
},
"Fail": {
"Type": "Fail"
}
}
}
From the child function's definition, if I don't add the SendTaskSuccess
and SendTaskFailure
states, the state machine runs perfectly, but it doesn't notify the event bus that it's finished, and so the parent function never continues to the next state.
Is there any additional policies that I need to add to my AWS SAM template to enable the functionality I'm looking for?