Reputation: 621
I am using the Serverless Framework to create a lambda function and would like to be able to cross-reference its Arn and name in other parts of serverless.yml.
I'm surprised how difficult I'm finding this as !GetAtt and !Ref do not seem to work as I would expect if the lambda was created via vanilla CloudFormation. (AWS::Lambda::Function returns Ref and Fn::GetAtt which would make this easy!)
I have found a few posts, that allude to solutions, but nothing that states in plain English how to achieve this.
...
functions:
- ${file(functions/sendEmail.yml)}
...
sendEmail:
handler: lambda-functions/send-email.handler
...
In another part of the template I have attempted:
...
LambdaFunctionArn: !GetAtt sendEmail.Arn
but, when I deploy, I get:
Error: The CloudFormation template is invalid: Template error: instance of Fn::GetAtt references undefined resource sendEmail
I notice that the final CloudFormation template has converted sendEmail to sendEmailLambdaFunction, so I then tried:
LambdaFunctionArn: !GetAtt sendEmailLambdaFunction.Arn
but received a similar error.
I also would like to be able to reference the name, but sadly
!Ref sendEmail
causes the error:
Error: The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [sendEmail] in the Resources block of the template
Any assistance with regards to precise changes I need to make, in order to achieve grabbing the lambda's Arn and name, would be greatly appreciated!
Thanks in advance! I
Upvotes: 3
Views: 12420
Reputation: 621
Ok, with thanks to Dinush for putting me on track, I achieved a functional solution as follows:
custom:
...
myEnvironment:
assetPreName: ${self:service.name}-${self:provider.stage}
arnRegionAndAccount: ${self:provider.region}:#{AWS::AccountId}
...
myContact:
...
lambdaFuncName: ${self:custom.myEnvironment.assetPreName}-sendEmail
lambdaFuncArn: arn:aws:lambda:${self:custom.myEnvironment.arnRegionAndAccount}:function:${self:custom.myContact.lambdaFuncName}
Note: The notation:
#{AWS::AccountId}
requires the plugin: serverless-pseudo-parameters.
sendEmail:
...
name: ${self:custom.myContact.lambdaFuncName}
...
LambdaFunctionArn: ${self:custom.myContact.lambdaFuncArn}
I still think it's a shame that I couldn't simply use Ref and Fn::GetAtt (as I would be able to if the lambda was created via a vanilla CloudFormation, AWS::Lambda::Function, resource), but this works for now.
Hope this helps someone else. Thanks again, Dinush for setting me on this course!
Upvotes: 6
Reputation: 406
I am not sure of the best practice, but the below works for me.
Provide functionName in the serverless function and when you want the arn, you can form it.
test.yaml
TestFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
FunctionName: myFunction
When referencing,
LambdaArn: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:myFunction
Upvotes: 11