Skip to content

Commit 479d003

Browse files
Merge pull request #222 from shota/master
DescribeExecution as option
2 parents cded38f + 83f55e2 commit 479d003

File tree

6 files changed

+164
-43
lines changed

6 files changed

+164
-43
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This is the Serverless Framework plugin for AWS Step Functions.
1717
- [Events](#events)
1818
- [API Gateway](#api-gateway)
1919
- [Simple HTTP endpoint](#simple-http-endpoint)
20+
- [Custom Step Functions Action](#custom-step-functions-action)
2021
- [HTTP Endpoint with custom IAM Role](#http-endpoint-with-custom-iam-role)
2122
- [Share API Gateway and API Resources](#share-api-gateway-and-api-resources)
2223
- [Enabling CORS](#enabling-cors)
@@ -375,6 +376,40 @@ stepFunctions:
375376
definition:
376377
```
377378

379+
#### Custom Step Functions Action
380+
381+
Step Functions have custom actions like DescribeExecution or StopExecution to fetch and control them. You can use custom actions like this:
382+
383+
```yml
384+
stepFunctions:
385+
stateMachines:
386+
start:
387+
events:
388+
- http:
389+
path: action/start
390+
method: POST
391+
definition:
392+
...
393+
status:
394+
events:
395+
- http:
396+
path: action/status
397+
method: POST
398+
action: DescribeExecution
399+
definition:
400+
...
401+
stop:
402+
events:
403+
- http:
404+
path: action/stop
405+
method: POST
406+
action: StopExecution
407+
definition:
408+
...
409+
```
410+
411+
Request template is not used when action is set because there're a bunch of actions. However if you want to use request template you can use [Customizing request body mapping templates](#customizing-request-body-mapping-templates).
412+
378413
#### HTTP Endpoint with custom IAM Role
379414

380415
The plugin would generate an IAM Role for you by default. However, if you wish to use an IAM role that you have provisioned separately, then you can override the IAM Role like this:

lib/deploy/events/apiGateway/apigateway-to-stepfunctions-assume-role.json

Lines changed: 0 additions & 34 deletions
This file was deleted.

lib/deploy/events/apiGateway/iamRole.js

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
const _ = require('lodash');
33
const BbPromise = require('bluebird');
4-
const path = require('path');
54

65
module.exports = {
76
compileHttpIamRole() {
@@ -14,15 +13,58 @@ module.exports = {
1413
return BbPromise.resolve();
1514
}
1615

17-
const iamRoleApiGatewayToStepFunctionsTemplate =
18-
JSON.stringify(this.serverless.utils.readFileSync(
19-
path.join(__dirname,
20-
'apigateway-to-stepfunctions-assume-role.json'))
21-
);
16+
const iamRoleApiGatewayToStepFunctionsAction = [
17+
'states:StartExecution',
18+
];
19+
20+
// generate IAM Role action by http.action parameter.
21+
this.pluginhttpValidated.events.forEach((event) => {
22+
if (_.has(event, 'http.action')) {
23+
const actionName = `states:${event.http.action}`;
24+
25+
if (iamRoleApiGatewayToStepFunctionsAction.indexOf(actionName) === -1) {
26+
iamRoleApiGatewayToStepFunctionsAction.push(actionName);
27+
}
28+
}
29+
});
30+
31+
const iamRoleApiGatewayToStepFunctions = {
32+
Type: 'AWS::IAM::Role',
33+
Properties: {
34+
AssumeRolePolicyDocument: {
35+
Version: '2012-10-17',
36+
Statement: [
37+
{
38+
Effect: 'Allow',
39+
Principal: {
40+
Service: 'apigateway.amazonaws.com',
41+
},
42+
Action: 'sts:AssumeRole',
43+
},
44+
],
45+
},
46+
Policies: [
47+
{
48+
PolicyName: 'apigatewaytostepfunctions',
49+
PolicyDocument: {
50+
Version: '2012-10-17',
51+
Statement: [
52+
{
53+
Effect: 'Allow',
54+
Action: iamRoleApiGatewayToStepFunctionsAction,
55+
Resource: '*',
56+
},
57+
],
58+
},
59+
},
60+
],
61+
},
62+
};
63+
2264

2365
const getApiToStepFunctionsIamRoleLogicalId = this.getApiToStepFunctionsIamRoleLogicalId();
2466
const newIamRoleStateMachineExecutionObject = {
25-
[getApiToStepFunctionsIamRoleLogicalId]: JSON.parse(iamRoleApiGatewayToStepFunctionsTemplate),
67+
[getApiToStepFunctionsIamRoleLogicalId]: iamRoleApiGatewayToStepFunctions,
2668
};
2769

2870
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,

lib/deploy/events/apiGateway/iamRole.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,56 @@ describe('#compileHttpIamRole()', () => {
120120
expect(resources).to.not.haveOwnProperty('ApigatewayToStepFunctionsRole');
121121
});
122122
});
123+
124+
it('Should add DescribeExecution action when it is assigned in config', () => {
125+
serverlessStepFunctions.pluginhttpValidated = {
126+
events: [
127+
{
128+
stateMachineName: 'first',
129+
http: {
130+
path: 'foo/bar1',
131+
method: 'post',
132+
},
133+
},
134+
{
135+
stateMachineName: 'first',
136+
http: {
137+
path: 'foo/bar2',
138+
method: 'post',
139+
action: 'DescribeExecution',
140+
},
141+
},
142+
],
143+
};
144+
145+
serverlessStepFunctions
146+
.compileHttpIamRole().then(() => {
147+
const properties = serverlessStepFunctions.serverless.service.provider
148+
.compiledCloudFormationTemplate.Resources.ApigatewayToStepFunctionsRole.Properties;
149+
expect(properties.Policies[0].PolicyDocument.Statement[0].Action)
150+
.to.deep.equal(['states:StartExecution', 'states:DescribeExecution']);
151+
});
152+
});
153+
154+
it('Should not add DescribeExecution action when it is not assigned in config', () => {
155+
serverlessStepFunctions.pluginhttpValidated = {
156+
events: [
157+
{
158+
stateMachineName: 'first',
159+
http: {
160+
path: 'foo/bar1',
161+
method: 'post',
162+
},
163+
},
164+
],
165+
};
166+
167+
serverlessStepFunctions
168+
.compileHttpIamRole().then(() => {
169+
const properties = serverlessStepFunctions.serverless.service.provider
170+
.compiledCloudFormationTemplate.Resources.ApigatewayToStepFunctionsRole.Properties;
171+
expect(properties.Policies[0].PolicyDocument.Statement[0].Action)
172+
.to.deep.equal(['states:StartExecution']);
173+
});
174+
});
123175
});

lib/deploy/events/apiGateway/methods.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,13 @@ module.exports = {
150150
],
151151
};
152152
const iamRole = _.get(http, 'iamRole', defaultIamRole);
153+
let integrationAction = ':states:action/StartExecution';
154+
let passthroughBehavior = 'NEVER';
155+
if (http && http.action) {
156+
integrationAction = `:states:action/${http.action}`;
157+
passthroughBehavior = 'WHEN_NO_TEMPLATES';
158+
}
159+
153160
const integration = {
154161
IntegrationHttpMethod: 'POST',
155162
Type: 'AWS',
@@ -162,11 +169,11 @@ module.exports = {
162169
{
163170
Ref: 'AWS::Region',
164171
},
165-
':states:action/StartExecution',
172+
integrationAction,
166173
],
167174
],
168175
},
169-
PassthroughBehavior: 'NEVER',
176+
PassthroughBehavior: passthroughBehavior,
170177
RequestTemplates: this.getIntegrationRequestTemplates(
171178
stateMachineName,
172179
stateMachineObj,
@@ -234,6 +241,12 @@ module.exports = {
234241
http.request.template
235242
);
236243
}
244+
245+
if (_.has(http, 'action')) {
246+
// no template if some action was defined.
247+
return {};
248+
}
249+
237250
// default template
238251
return defaultTemplate;
239252
},

lib/deploy/events/apiGateway/methods.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,19 @@ describe('#methods()', () => {
131131
.ResponseParameters['method.response.header.Access-Control-Allow-Origin'])
132132
.to.equal('\'*\'');
133133
});
134+
135+
it('should change passthroughBehavior and action when action is set',
136+
() => {
137+
expect(serverlessStepFunctions.getMethodIntegration('stateMachine', 'custom', {
138+
action: 'DescribeExecution',
139+
}).Properties.Integration.PassthroughBehavior)
140+
.to.equal('WHEN_NO_TEMPLATES');
141+
142+
expect(serverlessStepFunctions.getMethodIntegration('stateMachine', 'custom', {
143+
action: 'DescribeExecution',
144+
}).Properties.Integration.Uri['Fn::Join'][1][2])
145+
.to.equal(':states:action/DescribeExecution');
146+
});
134147
});
135148

136149
describe('#getIntegrationRequestTemplates()', () => {

0 commit comments

Comments
 (0)