I want to be able to reference outputs or function-level information (ARN or name) that is in one app/service, in another app/service using Serverless Framework. I am specifically interested in referencing a function's ARN, and if it changes for any reason, I am able to have a decoupled reference in the other service/app.
For example, I have this serverless.yml in App A:
org: myOrg
app: appA
service: serviceA
...
myFunction:
handler: src/index.handler
name: ${self:app}-${self:service}-myFunction-${sls:stage}
events:
- httpApi:
method: 'POST'
path: /my-path
I want to be able to use the ARN of myFunction in appA and serviceA, in appB and serviceB. Something like this:
org: myOrg
app: appB
service: serviceB
...
custom:
myFunctionArn: ${app:A-service:A-myFunctionArn} # <- here I want to be able to reference the ARN of the other deployed service
CodePudding user response:
You can achieve this by using serverless's outputs and then reference that in the other Serverless App or Service.
Using your example, in appA, serviceA, do this:
org: myOrg
app: appA
service: serviceA
...
myFunction:
handler: src/index.handler
name: ${self:app}-${self:service}-myFunction-${sls:stage}
events:
- httpApi:
method: 'POST'
path: /my-path
outputs:
myFunctionArn:
'Fn::GetAtt': [MyFunctionLambdaFunction, Arn]
Note, you have to use CloudFormation's generated resource names (see this great StackOverflow answer here). CloudFormation always outputs lambda function names as {titleCasedFunctionName}LambdaFunction
, so myFunction
becomes MyFunctionLambdaFunction
Then, in appB, serviceB, you can reference the output by following ${output:appname:stagename:regionname:my-service.var-key}
mentioned in the Serverless docs linked above. This makes your appB, serviceB serverless.yml as:
org: myOrg
app: appB
service: serviceB
...
custom:
myFunctionArn: ${output:appA:${self:provider.stage}:${self:provider.region}:serviceA.myFunctionArn}
I added variables for stage and region assuming this is a multi-stage deployment, and assuming that it is in the same region. If it is in a different region, then change ${self:provider.region}
to the region of appA/serviceA.