diff --git a/lib/deploy/stepFunctions/compileIamRole.js b/lib/deploy/stepFunctions/compileIamRole.js index 8772a20..3ea6a75 100644 --- a/lib/deploy/stepFunctions/compileIamRole.js +++ b/lib/deploy/stepFunctions/compileIamRole.js @@ -632,6 +632,24 @@ function getEventBridgeSchedulerPermissions(state) { ]; } +// Because the S3 Bucket parameter can be either a literal name or a reference to an existing S3 bucket we need to resolve +function resolveS3BucketReference(bucket, resource) { + if (isIntrinsic(bucket)) { + return { + 'Fn::Sub': [ + resource, + { bucket }, + ], + }; + } + + return resource.replaceAll('${bucket}', bucket); +} + +function resolveS3BucketReferences(bucket, resources) { + return resources.map((resource) => resolveS3BucketReference(bucket, resource)); +} + function getS3ObjectPermissions(action, state) { const bucket = state.Parameters.Bucket || '*'; const key = state.Parameters.Key || '*'; @@ -642,27 +660,27 @@ function getS3ObjectPermissions(action, state) { return [ { action: 's3:Get*', - resource: [ - `arn:aws:s3:::${bucket}`, - `arn:aws:s3:::${bucket}/*`, - ], + resource: resolveS3BucketReferences(bucket, [ + `arn:aws:s3:::\${bucket}`, + `arn:aws:s3:::\${bucket}/*`, + ]), }, { action: 's3:List*', - resource: [ - `arn:aws:s3:::${bucket}`, - `arn:aws:s3:::${bucket}/*`, - ], + resource: resolveS3BucketReferences(bucket, [ + `arn:aws:s3:::\${bucket}`, + `arn:aws:s3:::\${bucket}/*`, + ]), }, ]; } if (prefix) { - arn = `arn:aws:s3:::${bucket}/${prefix}/${key}`; + arn = resolveS3BucketReference(bucket, `arn:aws:s3:::\${bucket}/${prefix}/${key}`); } else if (bucket === '*' && key === '*') { arn = '*'; } else { - arn = `arn:aws:s3:::${bucket}/${key}`; + arn = resolveS3BucketReference(bucket, `arn:aws:s3:::\${bucket}/${key}`); } return [{