Skip to content

Commit fd5fc08

Browse files
committed
feat: add support for having a task be based on an object in S3 using AWS SDK service integration
1 parent 898752e commit fd5fc08

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/deploy/stepFunctions/compileIamRole.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,15 @@ function getEventBridgePermissions(state) {
372372
];
373373
}
374374

375+
function getS3GetObjectPermissions(state) {
376+
return [{
377+
action: 's3:GetObject',
378+
resource: [
379+
`arn:aws:s3:::${state.Parameters.Bucket}/${state.Parameters.Key}`,
380+
],
381+
}];
382+
}
383+
375384
// if there are multiple permissions with the same action, then collapsed them into one
376385
// permission instead, and collect the resources into an array
377386
function consolidatePermissionsByAction(permissions) {
@@ -470,6 +479,9 @@ function getIamPermissions(taskStates) {
470479
case 'arn:aws:states:::events:putEvents.waitForTaskToken':
471480
return getEventBridgePermissions(state);
472481

482+
case 'arn:aws:states:::aws-sdk:s3:getObject':
483+
return getS3GetObjectPermissions(state);
484+
473485
default:
474486
if (isIntrinsic(state.Resource) || !!state.Resource.match(/arn:aws(-[a-z]+)*:lambda/)) {
475487
const trimmedArn = trimAliasFromLambdaArn(state.Resource);

lib/deploy/stepFunctions/compileIamRole.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,47 @@ describe('#compileIamRole', () => {
10461046
expectDenyAllPolicy(policy);
10471047
});
10481048

1049+
it('should give s3:GetObject permission for only objects referenced by state machine', () => {
1050+
const hello = 'hello.txt';
1051+
const world = 'world.txt';
1052+
const testBucket = 'test-bucket';
1053+
1054+
const genStateMachine = (id, bucket, key) => ({
1055+
id,
1056+
definition: {
1057+
StartAt: 'A',
1058+
States: {
1059+
A: {
1060+
Type: 'Task',
1061+
Resource: 'arn:aws:states:::aws-sdk:s3:getObject',
1062+
Parameters: {
1063+
Bucket: bucket,
1064+
Key: key,
1065+
},
1066+
End: true,
1067+
},
1068+
},
1069+
},
1070+
});
1071+
1072+
serverless.service.stepFunctions = {
1073+
stateMachines: {
1074+
myStateMachine1: genStateMachine('StateMachine1', testBucket, hello),
1075+
myStateMachine2: genStateMachine('StateMachine2', testBucket, world),
1076+
},
1077+
};
1078+
1079+
serverlessStepFunctions.compileIamRole();
1080+
const resources = serverlessStepFunctions.serverless.service
1081+
.provider.compiledCloudFormationTemplate.Resources;
1082+
const policy1 = resources.StateMachine1Role.Properties.Policies[0];
1083+
const policy2 = resources.StateMachine2Role.Properties.Policies[0];
1084+
expect(policy1.PolicyDocument.Statement[0].Resource)
1085+
.to.be.deep.equal([`arn:aws:s3:::${testBucket}/${hello}`]);
1086+
expect(policy2.PolicyDocument.Statement[0].Resource)
1087+
.to.be.deep.equal([`arn:aws:s3:::${testBucket}/${world}`]);
1088+
});
1089+
10491090
it('should not generate any permissions for Task states not yet supported', () => {
10501091
const genStateMachine = id => ({
10511092
id,

0 commit comments

Comments
 (0)