I want to split my SAM application into multiple parts.
I want to create a API ( AWS::Serverless::Api ) in the root stack.
I am creating lambda functions in my child stacks, where I want to give the reference of the API from the root stack to the API Events.
Is this feasible? I didn't find any good examples for the accessing the API from the root stack into child stack?
I tried with the below template -
parenttemplateapi:
Type: AWS::Serverless::Application
Properties:
Location:
ApplicationId: arn:aws:serverlessrepo:us-east-1:account_id:applications/parent-template
SemanticVersion: 1.0.0
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python2.7
Events:
HelloWorld:
Type: Api
Properties:
Method: get
Path: /hello
RestApiId: !GetAtt parenttemplateapi.Outputs.ServerlessGW-restApiId
When I tried to deploy this template, I got below errors -
Error: Failed to create changeset for the stack: child-template, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Internal transform failure.
Any pointers/suggestions?
I was referring to below links -
https://aws.amazon.com/blogs/compute/announcing-nested-applications-for-aws-sam-and-the-aws-serverless-application-repository/
Can the API Gateway Id ( AWS::ApiGateway::RestApi) from the root stack used here?
https://dev.to/grahamcox82/building-a-larger-serverless-application-part-3-modular-monorepos-3mon
Can this be achieved using serverless framework?
The caveat here is that I do not use AWS SAM as I only use serverless.yml
ServerlessFramework files to declare my resources to deploy.
In my ROOT
API, I declare a series of outputs that my child lambdas depend on so that all my endpoints can have the same Rest API ID. This output declaration is nested under my resources
declaration in my serverless.yml
file as such:
resources:
Resources:
...
stuff here that you may need
...
# API Gateway Cross Stack Reference Exports!!!!!
# Outputs that other services will depend on!!!
Outputs:
ApiGatewayRestApiId:
Value:
Ref: ApiGatewayRestApi
Export:
Name: ${self:custom.stage}-ApiGatewayRestApiId
ApiGatewayRestApiRootResourceId:
Value:
Fn::GetAtt:
- ApiGatewayRestApi
- RootResourceId
Export:
Name: ${self:custom.stage}-ApiGatewayRestApiRootResourceId
Once you have this implemented you then need to import the reference to this parent API resource in your child lambdas within the provider
section of your serverless.yml
file.
# Cross-Stack Reference for sharing of API Gateway URI
# created with accounting-api
apiGateway:
restApiId: ${cf:ROOT_API_NAME_HERE-dev.ApiGatewayRestApiId}
#"Fn::ImportValue": ${self:custom.stage}-ApiGatewayRestApiId
restApiRootResourceId:
${cf:ROOT_API_NAME_HERE-dev.ApiGatewayRestApiRootResourceId}
#"Fn::ImportValue": ${self:custom.stage}-ApiGatewayRestApiRootResourceId
You must pay attention to the restApiId
that you need to import from the CloudFormation
stack from your parent API. You can review the outputs by going into the CloudFormation stack in your Parent API; click on Outputs and find your restApiId
values as needed.
There is also another way that allows you to import the values using Fn::ImportValue
which you can review with the example shown here:
https://github.com/serverless/examples/blob/master/aws-node-shared-gateway/users/serverless.yml
I have this method commented out in the code Ive pasted for you above for your reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With