fix(iam): resolve local Lambda Ref to static ARN (#470)#746
Merged
Conversation
commit: |
…PolicyDocument
When a task state uses `Resource: !Ref localFunction`, two bugs occur:
1. The IAM role's policy resource contains `{ Ref: ParseCSVLambdaFunction }`.
CloudFormation resolves a Lambda function Ref to the function *name*
(e.g. `my-service-dev-parseCSV`), not its ARN — IAM rejects this with
MalformedPolicyDocument.
2. The state machine definition also receives the function name string as
its Resource. Step Functions rejects this with InvalidDefinition.
In both cases the Ref also introduces a CloudFormation resource dependency
that can cause the circular dependency error reported in #470 when the
referenced Lambda has an env var pointing back at the state machine.
Fix: add `resolveLambdaFunctionName` to `lib/utils/aws.js`. When a Ref
points to a local function whose deployed name is known at compile time
(via `serverless.service.functions[key].name`), callers emit a static
`Fn::Sub` ARN string instead of the Ref. Two call sites are fixed:
- `iamStrategies/lambda.js` — IAM policy resource for both the direct
lambda ARN path (getFallbackPermissions) and the lambda:invoke SDK
integration path (getPermissions)
- `compileStateMachines.js` — definition string Fn::Sub params: local
Lambda Refs are inlined as static ARNs directly in the definition
string, eliminating both the CF dependency and the name-not-ARN error
Adds a `circular-dependency` integration fixture reproducing #470.
LocalStack confirms: without the fix the IAM role fails with
MalformedPolicyDocument and the state machine fails with InvalidDefinition;
with the fix the full stack deploys cleanly.
Closes #470
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
d954524 to
389288b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two bugs triggered when a task state uses
Resource: !Ref localFunction:{ Ref: ParseCSVLambdaFunction }, which CloudFormation resolves to the function name (e.g.my-service-dev-parseCSV), not its ARN. IAM rejects non-ARN resources.Resource. Step Functions rejects anything that isn't an ARN.Both bugs also introduce a CloudFormation resource dependency (
StateMachineRole → Lambda) that causes the circular dependency error reported in #470 when the Lambda has an env var referencing the state machine ARN.Fix
Adds
resolveLambdaFunctionNametolib/utils/aws.js. When aRefpoints to a local function whose deployed name is known at compile time (viaserverless.service.functions[key].name), a staticFn::SubARN is emitted instead — no CloudFormation resource reference, no dependency, no cycle.Two call sites fixed:
iamStrategies/lambda.jsgetFallbackPermissions(direct!Refresource) andgetPermissions(FunctionName: !RefSDK integration)compileStateMachines.jsFn::Subparams — local Lambda Refs are inlined as static ARNs directly in the definition stringIntegration test
Adds a
circular-dependencyfixture reproducing the exact scenario from #470. LocalStack validates both bugs:CircularMachineRolefails withMalformedPolicyDocument, thenCircularMachinefails withInvalidDefinitionTest plan
npm test— 534 passingnpx osls circular-dependency:deploy --stage testdeploys successfully against LocalStackCloses #470
🤖 Generated with Claude Code