Closed khlling closed 7 months ago
The sample uses the StartSyncExecution
action (as you can see both in the IAM role & request template) which is not available for Standard workflows (see docs).
If you want to use Standard workflows you'll have to modify the CDK above to use the StartExecution
action instead, which will make the call asynchronous. This API call returns only the execution Arn and start date (docs) so you'll also have to modify the API and/or the client to be able to fetch the result of the execution at a later time.
I haven't tested either with the sample above, but two options that come to mind are:
DescribeExecution
action (docs)@dreamorosi Thanks for your detailed comment. That really helped me understand the difference between Standard and Express workflows. Especially why there's a difference in execution.
In terms of converting from StartSyncExecution
to StartExecution
. I've made the following modifications:
"""
Create a new 'Execution' type that will be returned by our call
to the Step Functions workflow.
"""
type Execution {
status: String
executionArn: String
startDate: String
}
"""
Mutation that triggers the synchronous execution of our Step
Functions workflow.
"""
type Mutation {
executeMediaProcessingStateMachine(
input: String!
itemId: String!
): Execution @aws_api_key
}
const START_EXECUTION_REQUEST_TEMPLATE = (stateMachineArn: String) => {
return `
{
"version": "2018-05-29",
"method": "POST",
"resourcePath": "/",
"params": {
"headers": {
"content-type": "application/x-amz-json-1.0",
"x-amz-target":"AWSStepFunctions.StartExecution"
},
"body": {
"stateMachineArn": "${stateMachineArn}",
"input": "{ \\\"input\\\": \\\"$context.args.input\\\", \\\"itemId\\\": \\\"$context.args.itemId\\\"}"
}
}
}
`;
};
const RESPONSE_TEMPLATE = `
## Raise a GraphQL field error in case of a datasource invocation error
#if($ctx.error)
$util.error($ctx.error.message, $ctx.error.type)
#end
## if the response status code is not 200, then return an error. Else return the body **
#if($ctx.result.statusCode == 200)
## If response is 200, return the body.
$ctx.result.body
#else
## If response is not 200, append the response to error block.
$ctx.result.statusCode
#end
`;
// Create a service role for SFN to use
const serviceRole = new iam.Role(this, "Role", {
assumedBy: new iam.ServicePrincipal(
"states." + cdk.Stack.of(this).region + ".amazonaws.com"
),
});
/*
Defines the express SFN workflow resource using the state
machine definition as well as the service role defined above.
*/
const stateMachine = new sfn.StateMachine(this, "StateMachine", {
definition: transcribeStateMachineDefinition,
stateMachineType: sfn.StateMachineType.STANDARD,
role: serviceRole,
});
// Grant AppSync HTTP data source rights to execute the SFN workflow
stateMachine.grant(httpdatasource.grantPrincipal, "states:StartExecution");
// Creates an IAM role that can be assumed by the AWS AppSync service
const appsyncStepFunctionsRole = new iam.Role(
this,
"SyncStateMachineRole",
{
assumedBy: new iam.ServicePrincipal("appsync.amazonaws.com"),
}
);
// Allows the role we defined above to execute express SFN workflows
appsyncStepFunctionsRole.addToPolicy(
new iam.PolicyStatement({
resources: [stateMachine.stateMachineArn],
actions: ["states:StartExecution"],
})
);
/*
Adds a GraphQL resolver to our HTTP data source that defines how
GraphQL requests and fetches information from our SFN workflow.
*/
httpdatasource.createResolver("execute-state-machine", {
typeName: "Mutation",
fieldName: "executeMediaProcessingStateMachine",
requestMappingTemplate: appsync.MappingTemplate.fromString(
START_EXECUTION_REQUEST_TEMPLATE(stateMachine.stateMachineArn)
),
responseMappingTemplate:
appsync.MappingTemplate.fromString(RESPONSE_TEMPLATE),
});
}
}
However, I still can't get the step function to trigger. When I try and trigger it through the App Sync console I get an empty return object:
{
"data": {
"executeMediaProcessingStateMachine": {
"executionArn": null,
"status": null,
"startDate": null
}
}
}
Am I missing something?
I've figured it out my http datasource was pointing to https://sync-states." + cdk.Stack.of(this).region + ".amazonaws.com
// Adds the AWS Step Functions (SFN) service endpoint as a new HTTP data source to the GraphQL API
const httpdatasource = api.addHttpDataSource(
"ds",
"https://sync-states." + cdk.Stack.of(this).region + ".amazonaws.com",
{
name: "MediaProcessingSFN",
authorizationConfig: {
signingRegion: cdk.Stack.of(this).region,
signingServiceName: "states",
},
}
);
When it should have been https://states." + cdk.Stack.of(this).region + ".amazonaws.com
// Adds the AWS Step Functions (SFN) service endpoint as a new HTTP data source to the GraphQL API
const httpdatasource = api.addHttpDataSource(
"ds",
"https://states." + cdk.Stack.of(this).region + ".amazonaws.com",
{
name: "MediaProcessingSFN",
authorizationConfig: {
signingRegion: cdk.Stack.of(this).region,
signingServiceName: "states",
},
}
);
Before opening, please confirm:
JavaScript Framework
React
Amplify APIs
GraphQL API
Amplify Version
v6
Amplify Categories
api
Backend
Amplify CLI
Environment information
Describe the bug
My flow is as follows:
Note the step function is a STANDARD workflow, not an express workflow due to limited timeout time on the express workflow.
I initially had an express workflow but I switched to a standard workflow. I'm using amplify to define the App Sync Schema and custom/cdk to define the step function.
When I call the mutation nothing happens. The step function does not start. No errors visible. No error response from App Sync
Expected behavior
Calling the mutation triggers the start execution
Reproduction steps
I followed this setup guide for the flow initially:
https://aws.amazon.com/blogs/mobile/integrate-aws-step-functions-with-aws-amplify-using-amplify-custom-resources/
Works great as is. I customised it for my purpose and it was working fine. However, I was running into an issue with the initial implementation - the express workflow timeout being only 5 mins. The App sync schema was kept the same.
As a result, I changed express to standard workflow. I can manually execute the standard step function (from the console) and this works as expected.
Code Snippet
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response