Skip to content

Commit cef3c2e

Browse files
authored
Merge pull request #208 from horike37/feature/support_existing_IAM
feat: support iamRole override for HTTP events
2 parents acc2cd0 + c6c7fcf commit cef3c2e

File tree

4 files changed

+123
-17
lines changed

4 files changed

+123
-17
lines changed

README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,6 @@ stepFunctions:
315315
definition:
316316
```
317317

318-
#### HTTP Endpoint with Extended Options
319-
320318
Here You can define an POST endpoint for the path posts/create.
321319

322320
```yml
@@ -330,6 +328,22 @@ stepFunctions:
330328
definition:
331329
```
332330

331+
#### HTTP Endpoint with custom IAM Role
332+
333+
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:
334+
335+
```yml
336+
stepFunctions:
337+
stateMachines:
338+
hello:
339+
events:
340+
- http:
341+
path: posts/create
342+
method: POST
343+
iamRole: arn:aws:iam::<accountId>:role/<roleName>
344+
definition:
345+
```
346+
333347
#### Share API Gateway and API Resources
334348

335349
You can [share the same API Gateway](https://serverless.com/framework/docs/providers/aws/events/apigateway/#share-api-gateway-and-api-resources) between multiple projects by referencing its REST API ID and Root Resource ID in serverless.yml as follows:

lib/deploy/events/apiGateway/iamRole.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ const path = require('path');
55

66
module.exports = {
77
compileHttpIamRole() {
8+
const needDefaultIamRole = this.pluginhttpValidated.events.some((event) =>
9+
// a http event that doesn't specify its own iamRole would need us to
10+
// generate a default IAM role
11+
_.has(event, 'http') && !_.has(event, 'http.iamRole'));
12+
13+
if (!needDefaultIamRole) {
14+
return BbPromise.resolve();
15+
}
16+
817
const iamRoleApiGatewayToStepFunctionsTemplate =
918
JSON.stringify(this.serverless.utils.readFileSync(
1019
path.join(__dirname,

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

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,93 @@ describe('#compileHttpIamRole()', () => {
3131
serverlessStepFunctions = new ServerlessStepFunctions(serverless);
3232
});
3333

34-
it('should create a IAM Role resource', () => serverlessStepFunctions
35-
.compileHttpIamRole().then(() => {
36-
expect(
37-
serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate
38-
.Resources.ApigatewayToStepFunctionsRole.Type
39-
).to.equal('AWS::IAM::Role');
40-
})
41-
);
34+
it('should create an IAM Role resource when there are no iamRole overrides', () => {
35+
serverlessStepFunctions.pluginhttpValidated = {
36+
events: [
37+
{
38+
stateMachineName: 'first',
39+
http: {
40+
path: 'foo/bar1',
41+
method: 'post',
42+
},
43+
},
44+
{
45+
stateMachineName: 'first',
46+
http: {
47+
path: 'foo/bar2',
48+
method: 'post',
49+
private: true,
50+
},
51+
},
52+
],
53+
};
54+
55+
serverlessStepFunctions
56+
.compileHttpIamRole().then(() => {
57+
expect(
58+
serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate
59+
.Resources.ApigatewayToStepFunctionsRole.Type
60+
).to.equal('AWS::IAM::Role');
61+
});
62+
});
63+
64+
it('should create an IAM Role resource when at least one event has no iamRole override', () => {
65+
serverlessStepFunctions.pluginhttpValidated = {
66+
events: [
67+
{
68+
stateMachineName: 'first',
69+
http: {
70+
path: 'foo/bar1',
71+
method: 'post',
72+
},
73+
},
74+
{
75+
stateMachineName: 'first',
76+
http: {
77+
path: 'foo/bar2',
78+
method: 'post',
79+
iamRole: 'arn:aws:iam::12345567890:role/test',
80+
},
81+
},
82+
],
83+
};
84+
85+
serverlessStepFunctions
86+
.compileHttpIamRole().then(() => {
87+
expect(
88+
serverlessStepFunctions.serverless.service.provider.compiledCloudFormationTemplate
89+
.Resources.ApigatewayToStepFunctionsRole.Type
90+
).to.equal('AWS::IAM::Role');
91+
});
92+
});
93+
94+
it('should not create an IAM Role resource when all events have iamRole override', () => {
95+
serverlessStepFunctions.pluginhttpValidated = {
96+
events: [
97+
{
98+
stateMachineName: 'first',
99+
http: {
100+
path: 'foo/bar1',
101+
method: 'post',
102+
iamRole: 'arn:aws:iam::12345567890:role/test1',
103+
},
104+
},
105+
{
106+
stateMachineName: 'first',
107+
http: {
108+
path: 'foo/bar2',
109+
method: 'post',
110+
iamRole: 'arn:aws:iam::12345567890:role/test2',
111+
},
112+
},
113+
],
114+
};
115+
116+
serverlessStepFunctions
117+
.compileHttpIamRole().then(() => {
118+
const resources = serverlessStepFunctions.serverless.service.provider
119+
.compiledCloudFormationTemplate.Resources;
120+
expect(resources).to.not.haveOwnProperty('ApigatewayToStepFunctionsRole');
121+
});
122+
});
42123
});

lib/deploy/events/apiGateway/methods.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,18 @@ module.exports = {
142142
},
143143

144144
getMethodIntegration(stateMachineName, stateMachineObj, http) {
145-
const apiToStepFunctionsIamRoleLogicalId = this.getApiToStepFunctionsIamRoleLogicalId();
145+
const defaultIamRoleLogicalId = this.getApiToStepFunctionsIamRoleLogicalId();
146+
const defaultIamRole = {
147+
'Fn::GetAtt': [
148+
`${defaultIamRoleLogicalId}`,
149+
'Arn',
150+
],
151+
};
152+
const iamRole = _.get(http, 'iamRole', defaultIamRole);
146153
const integration = {
147154
IntegrationHttpMethod: 'POST',
148155
Type: 'AWS',
149-
Credentials: {
150-
'Fn::GetAtt': [
151-
`${apiToStepFunctionsIamRoleLogicalId}`,
152-
'Arn',
153-
],
154-
},
156+
Credentials: iamRole,
155157
Uri: {
156158
'Fn::Join': [
157159
'',

0 commit comments

Comments
 (0)