aws-sam-cli
aws-sam-cli copied to clipboard
`sam local start-api` does not produce any API's with nested stacks
Description:
We are currently building our parent stack with nested stacks, each will have their own endpoints from our main API which is defined in the parent stack using a Swagger file and referenced here and discussed here.
Note: we are using AWS::Serverless::API
as we need some of the security features for future integrations.
If I was to deploy this to our development and production environment it builds as expected.
However, when our developer's attempt to run the API Gateway locally, they get the following message: Error: Template does not have any APIs connected to Lambda functions
. If we define Events in the nested stack, multiple API's are built upon deployment.
Steps to reproduce:
template.yml - the parent stack
Resources:
# Each Lambda function is defined by properties:
# https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
ClientFacingLambdaAPIGateway:
Type: AWS::Serverless::Api
Properties:
Name: !Sub "Client Facing Lambda API Gateway - ${STAGE}"
Cors:
AllowOrigin: "'*'"
AllowHeaders: "'*'"
StageName: !Sub ${STAGE}
TracingEnabled: true
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: ./resources/api/api.yaml
# Further nested stacks defined before
origoHub:
Type: AWS::Serverless::Application
Properties:
Location: ./resources/applications/origo-hub-functions.yaml
resources/applications/origo-hub-functions.yaml
Resources:
# further resources defined before this
origoSwitch:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/switch.switchInstruction
FunctionName: !Sub "${STAGE}-origo-hub-switch"
Timeout: 120
Policies:
- LambdaInvokePolicy:
FunctionName:
!Sub "${STAGE}-origo-hub-switch"
origoSwitchPermisssion:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt switch.Arn
Principal: apigateway.amazonaws.com
Outputs:
origoSwitchFunction:
Description: "Switch Function ARN"
Value: !GetAtt origoSwitch.Arn
resources/api/api.yaml
swagger: '2.0'
info:
version: '1.0'
title:
Ref: AWS::StackName
paths:
/origohub/switch:
post:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
Fn::Sub:
- >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${origoSwitchFunction}/invocations
- origoSwitchFunction:
Fn::GetAtt:
- origohub
- Outputs.origoSwitchFunction
responses:
'200':
description: 'Success'
# More resources defined after.
Observed result:
2021-09-27 14:43:19,501 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2021-09-27 14:43:19,502 | Using config file: samconfig.toml, config environment: default
2021-09-27 14:43:19,502 | Expand command line arguments to:
2021-09-27 14:43:19,502 | --template_file=/Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/template.yaml --host=0.0.0.0 --port=3000 --static_dir=public --layer_cache_basedir=/Users/marcus.rowland/.aws-sam/layers-pkg --container_host=localhost --container_host_interface=127.0.0.1
2021-09-27 14:43:19,613 | local start-api command is called
2021-09-27 14:43:19,634 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'CRYPTO': 'true', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': '', 'WebEndpoint': ''}
2021-09-27 14:43:19,664 | Unable to resolve property DefinitionBody: OrderedDict([('Fn::Transform', OrderedDict([('Name', 'AWS::Include'), ('Parameters', OrderedDict([('Location', '../../resources/api/api.yaml')]))]))]). Leaving as is.
2021-09-27 14:43:19,664 | 3 stacks found in the template
2021-09-27 14:43:19,729 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': ''}
2021-09-27 14:43:19,752 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,752 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,753 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,753 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,753 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,753 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,753 | 6 stacks found in the template
2021-09-27 14:43:19,773 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'ClarityWebPrefix': 'https://dev.'}
2021-09-27 14:43:19,796 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:19,796 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:19,796 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,797 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:19,797 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:19,797 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,797 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,797 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,797 | 7 stacks found in the template
2021-09-27 14:43:19,797 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'CRYPTO': 'true', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': '', 'WebEndpoint': ''}
2021-09-27 14:43:19,817 | Unable to resolve property DefinitionBody: OrderedDict([('Fn::Transform', OrderedDict([('Name', 'AWS::Include'), ('Parameters', OrderedDict([('Location', '../../resources/api/api.yaml')]))]))]). Leaving as is.
2021-09-27 14:43:19,817 | 3 resources found in the stack
2021-09-27 14:43:19,817 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': ''}
2021-09-27 14:43:19,838 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,838 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,839 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,839 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,839 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,839 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,839 | 6 resources found in the stack morningstar
2021-09-27 14:43:19,839 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'ClarityWebPrefix': 'https://dev.'}
2021-09-27 14:43:19,861 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:19,861 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:19,861 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,862 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:19,862 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:19,862 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,862 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,862 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,862 | 7 resources found in the stack origohub
2021-09-27 14:43:19,862 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'CRYPTO': 'true', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': '', 'WebEndpoint': ''}
2021-09-27 14:43:19,881 | Unable to resolve property DefinitionBody: OrderedDict([('Fn::Transform', OrderedDict([('Name', 'AWS::Include'), ('Parameters', OrderedDict([('Location', '../../resources/api/api.yaml')]))]))]). Leaving as is.
2021-09-27 14:43:19,882 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': ''}
2021-09-27 14:43:19,903 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,903 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,904 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,904 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,904 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,904 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,904 | Found Serverless function with name='buyListFundPerformance' and CodeUri='buyListFundPerformance'
2021-09-27 14:43:19,904 | --base-dir is not presented, adjusting uri buyListFundPerformance relative to /Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/morningstar/template.yaml
2021-09-27 14:43:19,904 | Found Serverless function with name='fundPerformanceGraph' and CodeUri='fundPerformanceGraph'
2021-09-27 14:43:19,904 | --base-dir is not presented, adjusting uri fundPerformanceGraph relative to /Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/morningstar/template.yaml
2021-09-27 14:43:19,904 | Found Serverless function with name='fundInfoTooltip' and CodeUri='fundInfoTooltip'
2021-09-27 14:43:19,904 | --base-dir is not presented, adjusting uri fundInfoTooltip relative to /Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/morningstar/template.yaml
2021-09-27 14:43:19,904 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'ClarityWebPrefix': 'https://dev.'}
2021-09-27 14:43:19,926 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:19,926 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:19,926 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,927 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:19,927 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:19,927 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,927 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,927 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:19,927 | Found Serverless function with name='receiveAlert' and CodeUri='receiveAlert'
2021-09-27 14:43:19,927 | --base-dir is not presented, adjusting uri receiveAlert relative to /Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/origohub/template.yaml
2021-09-27 14:43:19,928 | Found Serverless function with name='processDocument' and CodeUri='processDocument'
2021-09-27 14:43:19,928 | --base-dir is not presented, adjusting uri processDocument relative to /Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/origohub/template.yaml
2021-09-27 14:43:19,928 | Found Serverless function with name='origoSwitch' and CodeUri='origoSwitch'
2021-09-27 14:43:19,928 | --base-dir is not presented, adjusting uri origoSwitch relative to /Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/origohub/template.yaml
2021-09-27 14:43:19,933 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'CRYPTO': 'true', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': '', 'WebEndpoint': ''}
2021-09-27 14:43:19,953 | Unable to resolve property DefinitionBody: OrderedDict([('Fn::Transform', OrderedDict([('Name', 'AWS::Include'), ('Parameters', OrderedDict([('Location', '../../resources/api/api.yaml')]))]))]). Leaving as is.
2021-09-27 14:43:19,953 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'CRYPTO': 'true', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': '', 'WebEndpoint': ''}
2021-09-27 14:43:19,972 | Unable to resolve property DefinitionBody: OrderedDict([('Fn::Transform', OrderedDict([('Name', 'AWS::Include'), ('Parameters', OrderedDict([('Location', '../../resources/api/api.yaml')]))]))]). Leaving as is.
2021-09-27 14:43:19,972 | Successfully parsed location from AWS::Include transform: ../../resources/api/api.yaml
2021-09-27 14:43:19,972 | Trying to download Swagger from ../../resources/api/api.yaml
2021-09-27 14:43:19,972 | Reading Swagger document from local file at /Users/marcus.rowland/Projects/clarity-clientaccessible-lambda/.aws-sam/build/../../resources/api/api.yaml
2021-09-27 14:43:19,994 | Resolved Sub intrinsic function: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${origoSwitchFunction}/invocations
2021-09-27 14:43:19,994 | Extracted Function ARN: ${origoSwitchFunction}
2021-09-27 14:43:19,994 | No Lambda function ARN defined for integration containing ARN ${origoSwitchFunction}
2021-09-27 14:43:19,994 | Lambda function integration not found in Swagger document at path='/origohub/switch' method='post'
2021-09-27 14:43:19,994 | Resolved Sub intrinsic function: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${receiveAlertFunction}/invocations
2021-09-27 14:43:19,994 | Extracted Function ARN: ${receiveAlertFunction}
2021-09-27 14:43:19,994 | No Lambda function ARN defined for integration containing ARN ${receiveAlertFunction}
2021-09-27 14:43:19,994 | Lambda function integration not found in Swagger document at path='/origohub/alert' method='post'
2021-09-27 14:43:19,994 | Resolved Sub intrinsic function: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${buyListFundPerformanceFunction}/invocations
2021-09-27 14:43:19,994 | Extracted Function ARN: ${buyListFundPerformanceFunction}
2021-09-27 14:43:19,994 | No Lambda function ARN defined for integration containing ARN ${buyListFundPerformanceFunction}
2021-09-27 14:43:19,994 | Lambda function integration not found in Swagger document at path='/morningstar/buylistfundperfomance' method='get'
2021-09-27 14:43:19,994 | Lambda function integration not found in Swagger document at path='/morningstar/buylistfundperfomance' method='options'
2021-09-27 14:43:19,994 | Resolved Sub intrinsic function: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${fundInfoTooltipFunction}/invocations
2021-09-27 14:43:19,994 | Extracted Function ARN: ${fundInfoTooltipFunction}
2021-09-27 14:43:19,994 | No Lambda function ARN defined for integration containing ARN ${fundInfoTooltipFunction}
2021-09-27 14:43:19,994 | Lambda function integration not found in Swagger document at path='/morningstar/fundinfotooltipdata' method='get'
2021-09-27 14:43:19,995 | Lambda function integration not found in Swagger document at path='/morningstar/fundinfotooltipdata' method='options'
2021-09-27 14:43:19,995 | Resolved Sub intrinsic function: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${fundPerformanceGraphFunction}/invocations
2021-09-27 14:43:19,995 | Extracted Function ARN: ${fundPerformanceGraphFunction}
2021-09-27 14:43:19,995 | No Lambda function ARN defined for integration containing ARN ${fundPerformanceGraphFunction}
2021-09-27 14:43:19,995 | Lambda function integration not found in Swagger document at path='/morningstar/fundperformancegraphdata' method='get'
2021-09-27 14:43:19,995 | Lambda function integration not found in Swagger document at path='/morningstar/fundperformancegraphdata' method='options'
2021-09-27 14:43:19,995 | Found '0' APIs in resource 'ClientFacingLambdaAPIGateway'
2021-09-27 14:43:19,995 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'IntranetWebPrefix': 'https://dev-intr.', 'ClarityWebPrefix': 'https://dev.', 'DBUSER': '', 'DBCLIENT': '', 'DBPASSWORD': '', 'DBDATABASE': '', 'DBHOST': '', 'DBPORT': ''}
2021-09-27 14:43:20,016 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,016 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,017 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,017 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['buyListFundPerformance', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,017 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundPerformanceGraph', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,017 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['fundInfoTooltip', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,017 | Found '0' API Events in Serverless function with name 'buyListFundPerformance'
2021-09-27 14:43:20,017 | Found '0' API Events in Serverless function with name 'fundPerformanceGraph'
2021-09-27 14:43:20,017 | Found '0' API Events in Serverless function with name 'fundInfoTooltip'
2021-09-27 14:43:20,017 | Collected default values for parameters: {'DEBUG': 'false', 'STAGE': 'dev', 'ClarityWebPrefix': 'https://dev.'}
2021-09-27 14:43:20,040 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:20,040 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:20,040 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,040 | Unable to resolve property queueName: OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])]). Leaving as is.
2021-09-27 14:43:20,040 | Unable to resolve property Resource: {'Fn::Sub': ['arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:${queueName}', {'queueName': OrderedDict([('Fn::GetAtt', ['OrigoAWSSQSQueue', 'QueueName'])])}]}. Leaving as is.
2021-09-27 14:43:20,041 | Unable to resolve property FunctionName: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,041 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['origoSwitch', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,041 | Unable to resolve property Value: OrderedDict([('Fn::GetAtt', ['receiveAlert', 'Arn'])]). Leaving as is.
2021-09-27 14:43:20,041 | Found '0' API Events in Serverless function with name 'receiveAlert'
2021-09-27 14:43:20,041 | Found '0' API Events in Serverless function with name 'processDocument'
2021-09-27 14:43:20,041 | Found '0' API Events in Serverless function with name 'origoSwitch'
2021-09-27 14:43:20,041 | Removed duplicates from '0' Explicit APIs and '0' Implicit APIs to produce '0' APIs
2021-09-27 14:43:20,041 | 0 APIs found in the template
2021-09-27 14:43:20,046 | Sending Telemetry: {'metrics': [{'commandRun': {'requestId': '5692639e-efb6-4d2e-a7a0-e47bdfee37db', 'installationId': '0abac36d-28de-45ba-a90c-d56e9a011c21', 'sessionId': '7c1c8e19-c987-41b2-80e0-af79ff1c9acf', 'executionEnvironment': 'CLI', 'ci': False, 'pyversion': '3.8.12', 'samcliVersion': '1.31.0', 'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'commandName': 'sam local start-api', 'duration': 544, 'exitReason': 'NoApisDefined', 'exitCode': 1}}]}
2021-09-27 14:43:20,735 | HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)
Error: Template does not have any APIs connected to Lambda functions
Expected result:
When I run sam build
followed by sam local start-api --host 0.0.0.0
I expect the API's that I have defined in my api.yaml file to be available locally.
Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
- OS: macOS Big Sur 11.6
-
sam --version
: 1.31.0 - AWS region: eu-west-1.
Add --debug flag to command you are running
Hi @marcusr21, Thanks for the feedback! SAM CLI local commands currently do not support nested stacks. We will look into adding this support.
Any update on this?
sorry @utsav-enact .. this feature is not added yet.
Our team is running into the same issue with sam local start-lambda
in a multi-stack application. Are there any suggested workarounds?
Same issue here: working with nested stacks on CDK. It seems to me that the only solution is to have a local stack with all the required resources defined inside.
My solution is to run the stacks on different ports. Like so:
npm i -D concurrently
npx concurrently \
"sam local start-api -t ./cdk.out/foo.template.json -p 3000" \
"sam local start-api -t ./cdk.out/bar.template.json -p 3001"
Are there any plans, or on the roadmap to support this functionality?
Coming from #5164
Thanks for your response @hawflau a terminal session for each template is somewhat undesirable. At the very least it changes the ports such that our automated local testing has a mess of ports.
This isn't just a case of wanting multiple APIs. We would probably be satisfied with a single API however we have reached the limits of the size of single cloudformation document when it comes to "Template body size in a request"
We can't have multiple nested stacks use the same API We can't have a completely different stack use the same API
It leaves us wondering how anyone is able to use SAM with a large API, supporting local development.
It is also strange to have the SAM documentation suggest moving to nested stacks for size issues despite limited support.
This issue is over 1.5 years old now, do you think we could get it prioritized?
@BenPela Got it. I'll bring that up to the Team and see if we can prioritize this feature request.
As you mentioned you are trying to run automated local tests, can you help me understand how the tests are structured and run? Are these tests unit tests or integration tests?
I'd imagine you would spin up the local API service, then the tests invoke the API and assert if the outcomes produced by the Lambda Functions are as expected. If that's the case, I wonder if testing in cloud is more reliable. Reason is that sam local start-api
is an emulation of API Gateway after all, and we don't guarantee the local API behaves 100% the same as API Gateway.
We understand that customers wish sam local start-api
to become more powerful. But I'd also like to understand more if sam local *
is the answer to most use cases.
@hawflau thanks for your great response.
We do understand that API Gateway will not behave exactly as the local implementation and that's reasonable. For this reason, our integration tests are also run in the cloud to cover these cases.
Let's say one has an api with a few features.
api.example.com/authentication
api.example.com/feature1
There are 2 ways we conduct testing/developing locally. Using an integration test, or using a tool like postman/insomnia. Due to the size of our project, deploying takes multiple minutes so having developers each deploy a their own instance of our API would slow us down quite a bit.
When locally developing/testing feature1, it may be a requirement to use /auths if my feature requires authentication. Our api is specified by an openapi specification that can be imported. Changing the ports means all of the base paths are incorrect.
It is certainly possible to change the base paths in our testing tools and integration tests to accommodate but that is quite a work around and adds a lot of confusion for local development.
Hey, @lmiguelmh, @marcusr21, and @BenPela!
I wanted to share an experience we had with CDK nested stacks. Initially, we encountered an issue when referencing API Gateway within nested stacks. It seemed like something was going wrong, and running the Sam local start API command became nearly impossible. Surprisingly, though, the same structure worked perfectly fine when deployed in the cloud.
To overcome this challenge, we made some changes to the stack configuration to enable SAM local commands. We decided to define the API Gateway(RestApi) in the main (parent) stack and pass its restApiId and restApiRootResourceId as props to the nested (child) stacks. This allowed us to integrate the API with Lambda functions in the nested stacks. This approach also facilitates multiple nested stacks to utilize the same API as well. The best part was that we were able to successfully test the sam local commands with these modifications.
This CDK document helped us in our journey.
We believe this same approach should be possible when defining stacks through SAM
Having a good setup for AWS GW with multiple routes and lambda functions is pretty much an ongoing quest. So I was thrilled to came across this repo as an example https://github.com/aws-samples/sam-accelerate-nested-stacks-demo
It has good separation, with some tweaks it could be a great start template for any team that wants to go full lambda and api gateway. When deployed to one of my accounts it all went pretty smoothly.
Then of course I wanted to test is locally to test how we could incorporate this into our development cycles.
sam local start-api
fails due to the openapi document that is imported in one of the template, pretty much the same as the examples given in this issue
When running the mentioned command with the debug flag you can see that it fails to parse the openapi.yaml file.
2023-07-30 11:35:01,449 | Unable to resolve property DefinitionBody: OrderedDict([('Fn::Transform', OrderedDict([('Name', 'AWS::Include'), ('Parameters', OrderedDict([('Location', '../../../api/definition/openapi.yaml')]))]))]). Leaving as is.
It would be great if the repo mentioned above could be the basis for resolving this issue and create an easier adoption to the GW / Lambda setup
EDIT:
To expand on what I have written above, I also tried to paste the openapi.yaml contents directly into the DefinitionBody
OrderApi:
Type: AWS::Serverless::Api
Properties:
StageName: Dev
EndpointConfiguration:
Type: REGIONAL
MethodSettings:
- HttpMethod: "*"
# LoggingLevel: INFO
ResourcePath: "/*"
# MetricsEnabled: true
Cors:
AllowMethods: "'POST, GET, DELETE'"
AllowHeaders: "'X-Forwarded-For'"
AllowOrigin: "'*'"
MaxAge: "'600'"
# DefinitionUri: definition/openapi.yaml
DefinitionBody:
openapi: 3.0.1
info:
title: qmica-api
version: 1.0.0
servers:
- url: /Dev
paths:
/orders:
get:
x-amazon-apigateway-integration:
credentials:
Fn::GetAtt:
- ApiGwExecutionRole
- Arn
type: aws_proxy
httpMethod: POST
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetOrders}/invocations
passthroughBehavior: when_no_match
/orders/{orderId+}:
get:
x-amazon-apigateway-integration:
credentials:
Fn::GetAtt:
- ApiGwExecutionRole
- Arn
type: "aws_proxy"
httpMethod: POST
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetSingleOrder}/invocations
passthroughBehavior: "when_no_match"
components: {}
This will result in Error: Template does not have any APIs connected to Lambda functions
do we have any updates on that issue?
Also would love this to work, running into the same issue
We are running into the same issue. Our nested stack cannot mount any of our functions. Our lambdas are divided into separate stacks by their category. Gateway is in another stack. Attempting to run sam local start-api
simply won't work.
It's been more than 2 years since this issue has been opened. I don't see any comment from AWS team even providing an action plan for it. If this is not planned to be fixed, why is it allowed to be open?
The only solution we ever found, and still use was to use start-lambda
and write a small express server that recursively parses nested stacks for lambda functions, hosts them and uses the AWS SDK to call them.
Quite a workaround and I'm sure it misses a lot in functionality.
It would be nice to know if this is somewhere on the road map for the SAM team.
CDK team, thank you for your work.
Any updates? I have a similar workflow as mentioned previously by @BenPela . I leverage nested stacks to circumvent the 1MB limit.
Is there any updates on this as we are facing the same issue.
@Shra1kumarLP , we had already tried passing restapi id as that was the very first approach of our configuration but that does not work. It lands in error "RestApiId must be a valid reference to an 'AWS::Serverless::Api' resource in same template." when the serverless function tries to hook up with the api gateway id
Pretty bad that this was never addressed over the years, I'm having cross-stack references issue with HTTP API and AWS CDK, with the Lambda stack referenced by the API Gateway v2 stack in Launcher.ts.
sam local start-api -t ./cdk.out/APIGWStack.template.json
Mounting None at http://127.0.0.1:3000/orders [DELETE, GET, POST, PUT,
OPTIONS]
Exception on /orders [GET]
Traceback (most recent call last):
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/flask/app.py", line 1473, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/flask/app.py", line 882, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/flask/app.py", line 880, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/flask/app.py", line 865, in dispatch_request
return
self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) #
type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/samcli/local/apigw/local_apigw_service.py", line 725, in
_request_handler
lambda_response = self._invoke_lambda_function(route.function_name,
route_lambda_event)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/samcli/local/apigw/local_apigw_service.py", line 618, in
_invoke_lambda_function
self.lambda_runner.invoke(lambda_function_name, event_str,
stdout=stdout_writer, stderr=self.stderr)
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/samcli/commands/local/lib/local_lambda.py", line 118, in invoke
function = self.provider.get(function_identifier)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/usr/local/Cellar/aws-sam-cli/1.118.0/libexec/lib/python3.12/site-pack
ages/samcli/lib/providers/sam_function_provider.py", line 121, in get
raise ValueError("Function name is required")
ValueError: Function name is required
Looks like it can't find the function identifier/function name. CDK watch works fine, but it's slow - takes like 15 seconds to hot swap with the nodejsfunction esbuild construct.