aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.53k stars 1.17k forks source link

Bug: `sam local start-api` permits invalid API paths #7613

Open davidjb opened 1 month ago

davidjb commented 1 month ago

Description:

The local API implementation from SAM permits and works with API Path properties that are invalid and rejected by CloudFormation. For example:

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    ...
    Events:
      ApiEvent:
        Type: Api
        Properties:
          Path: /api/map/{z}/{x}/{y}.png
          # This also works locally but errors as well
          # Path: /api/map/{z}/{x}/{y}
          Method: get

When attempted to be deployed, this will error with:

Unable to create resource at path '/api/map/{z}/{x}/{y}.png': Resource's path part only allow a-zA-Z0-9._-: or a valid greedy path variable and curly braces at the beginning and the end. (Service: ApiGateway, Status Code: 400

Steps to reproduce:

  1. Install SAM
  2. Create template or add Events config to default template as per the above
  3. Run sam local start-api
  4. Make a HTTP request to http://localhost:3000/api/map/{z}/{x}/{y}.png and note that it succeeds.
  5. Try to run sam deploy.
  6. Observe that CloudFormation errors with the above error.

Observed result:

2024-10-29 12:33:25,102 | local start-api command is called
2024-10-29 12:33:25,189 | 2 resources found in the stack
2024-10-29 12:33:25,190 | Found Serverless function with name='MyFunction' and CodeUri='MyFunction'
2024-10-29 12:33:25,190 | --base-dir is not presented, adjusting uri MyFunction relative to /home/user/project/.aws-sam/local/template.yaml
2024-10-29 12:33:25,191 | watch resource /home/user/project/.aws-sam/local/template.yaml
2024-10-29 12:33:25,191 | Create Observer for resource /home/user/project/.aws-sam/local/template.yaml with recursive True
2024-10-29 12:33:25,192 | watch resource /home/user/project/.aws-sam/local/template.yaml's parent /home/user/project/.aws-sam/local
2024-10-29 12:33:25,193 | Create Observer for resource /home/user/project/.aws-sam/local with recursive False
2024-10-29 12:33:25,199 | Initializing the lambda functions containers.
2024-10-29 12:33:25,200 | Async execution started
2024-10-29 12:33:25,200 | Invoking function functools.partial(<function
InvokeContext._initialize_all_functions_containers.<locals>.initialize_function_container at 0x106ac5c60>, Function(function_id='MyFunction',
name='MyFunction', functionname='MyFunction', runtime='provided.al2023', memory=256, timeout=30, handler='bootstrap', imageuri=None,
packagetype='Zip', imageconfig=None, codeuri='/home/user/project/.aws-sam/local/MyFunction', environment={'Variables': {}}, rolearn=None,
layers=[], events={'ApiEvent': {'Type': 'Api', 'Properties': {'Path': '/api/map/{z}/{x}/{y}.png', 'Method': 'get',
'RestApiId': 'RanMapsAPI'}}}, metadata={'BuildMethod': 'go1.x', 'BuildProperties': {'TrimGoPath': True}, 'SamResourceId': 'MyFunction'},
inlinecode=None, codesign_config_arn=None, architectures=['arm64'], function_url_config=None, function_build_info=<FunctionBuildInfo.BuildableZip:
('BuildableZip', 'Regular ZIP function which can be build with SAM CLI')>, stack_path='', runtime_management_config=None, logging_config=None))
2024-10-29 12:33:25,202 | Waiting for async results
2024-10-29 12:33:25,205 | Loading AWS credentials from session with profile 'local'
2024-10-29 12:33:25,211 | Resolving code path. Cwd=/home/user/project/.aws-sam/local,
CodeUri=/home/user/project/.aws-sam/local/MyFunction
2024-10-29 12:33:25,212 | Resolved absolute path to code is /home/user/project/.aws-sam/local/MyFunction
2024-10-29 12:33:25,212 | Resolving code path. Cwd=/home/user/project/.aws-sam/local,
CodeUri=/home/user/project/.aws-sam/local/MyFunction
2024-10-29 12:33:25,212 | Resolved real code path to /home/user/project/.aws-sam/local/MyFunction
2024-10-29 12:33:25,277 | watch resource /home/user/project/.aws-sam/local/MyFunction
2024-10-29 12:33:25,277 | Create Observer for resource /home/user/project/.aws-sam/local/MyFunction with recursive True
2024-10-29 12:33:25,278 | watch resource /home/user/project/.aws-sam/local/MyFunction's parent /home/user/project/.aws-sam/local
2024-10-29 12:33:25,278 | Code /home/user/project/.aws-sam/local/MyFunction is not a zip/jar file
2024-10-29 12:33:29,536 | Local image is up-to-date
2024-10-29 12:33:29,555 | Checking free port on 127.0.0.1:5148
2024-10-29 12:33:29,565 | Using local image: public.ecr.aws/lambda/provided:al2023-rapid-arm64.

2024-10-29 12:33:29,566 | Mounting /home/user/project/.aws-sam/local/MyFunction as /var/task:ro,delegated, inside runtime container
2024-10-29 12:33:29,805 | Async execution completed
2024-10-29 12:33:29,806 | Containers Initialization is done.
2024-10-29 12:33:29,807 | Detected Inline Swagger definition
2024-10-29 12:33:29,808 | Parsing Swagger document using 2.0 specification
2024-10-29 12:33:29,811 | Found '0' authorizers in resource 'RanMapsAPI'
2024-10-29 12:33:29,812 | Lambda function integration not found in Swagger document at path='/api/map/{z}/{x}/{y}.png' method='get'
2024-10-29 12:33:29,813 | Found '0' APIs in resource 'RanMapsAPI'
2024-10-29 12:33:29,814 | Authorizer not found or disabled, returning early
2024-10-29 12:33:29,815 | Found '1' API Events in Serverless function with name 'MyFunction'
2024-10-29 12:33:29,816 | Removed duplicates from '1' Explicit APIs and '0' Implicit APIs to produce '1' APIs
2024-10-29 12:33:29,817 | 1 APIs found in the template
2024-10-29 12:33:29,828 | Mounting MyFunction at http://127.0.0.1:4000/api/map/{z}/{x}/{y}.png [GET, OPTIONS]
2024-10-29 12:33:29,830 | You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on
your functions, changes will be reflected instantly/automatically. If you used sam build before running local commands, you will need to re-run sam build
for the changes to be picked up. You only need to restart SAM CLI if you update your AWS SAM template
2024-10-29 12:33:29,832 | Localhost server is starting up. Multi-threading = True
2024-10-29 12:33:29,833 | Setting SIGTERM interrupt handler
2024-10-29 12:33:29 WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:4000
2024-10-29 12:33:29 Press CTRL+C to quit

Expected result:

SAM and CloudFormation to be aligned. SAM to error when supplied with invalid API paths and prevent local-api from starting up.

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

{
  "version": "1.126.0",
  "system": {
    "python": "3.13.0",
    "os": "Linux-6.4.16-linuxkit-aarch64-with-glibc2.35"
  },
  "additional_dependencies": {
    "docker_engine": "24.0.6",
    "aws_cdk": "Not available",
    "terraform": "Not available"
  },
  "available_beta_feature_env_vars": [
    "SAM_CLI_BETA_FEATURES",
    "SAM_CLI_BETA_BUILD_PERFORMANCE",
    "SAM_CLI_BETA_TERRAFORM_SUPPORT",
    "SAM_CLI_BETA_RUST_CARGO_LAMBDA"
  ]
}
hnnasit commented 3 weeks ago

Hi @davidjb, thanks for reporting the issue. I can re-produce the behavior, marking it as a bug.