aws / aws/aws-sam-cli

Code changes reflected inconsistently when using sam local

Open
#3,721 4 comments 0 reactions 0 assignees View on GitHub
maintainer/need-followup type/feature
Dominant language
Python
Stars
6.7k
Forks
1.2k
Avg merge
1d 10h
Merged PRs (30d)
52

Description

### Description:

When using `sam local start-api`, code changes are sometimes reflected immediately after saving a file and other times require a `sam build`.

### Steps to reproduce:

1. Create a new Python SAM application using the HelloWorld template
2. Run `sam local start-api --port 8080`.
3. Run `curl http://localhost:8080/hello`. Note the return value `{"message": "hello world"}`. Also note the mounted code path is in the application root:`Mounting /home/ec2-user/environment/sam-app/hello_world`, as logged where the server is running.
4. Make a code change to `app.py` by changing the response message to `"hello world!!!"`
5. Run `curl http://localhost:8080/hello`. Note the return value matches the code change, `{"message": "hello world!!!"}`
6. Ctrl-C the `sam local start-api` command.
7. Run `sam build`
8. Run `sam local start-api --port 8080`
9. Run `curl http://localhost:8080/hello`. Note the expected return value: `{"message": "hello world!!!"}`. Also note the mounted code path is in the `.aws-sam` directory: `Mounting /home/ec2-user/environment/sam-app/.aws-sam/build/HelloWorldFunction`, as logged where the server is running.
10. Make a code change to `app.py` by changing the response message to `HELLO WORLD`. Save the file.
11. Run `curl http://localhost:8080/hello`. Note the return value does *not* match the code change and returns the previous built version with `{"message": "hello world!!!"}`
12. Kill the server, `rm -rf .aws-sam` and note that the first behavior (step 2) works again.

### Observed result:

**Without the .aws-sam directory**

```admin:~/environment/sam-app $ sam local start-api --port 8080 --debug
2022-03-09 21:59:01,441 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2022-03-09 21:59:01,441 | Using config file: samconfig.toml, config environment: default
2022-03-09 21:59:01,441 | Expand command line arguments to:
2022-03-09 21:59:01,441 | --template_file=/home/ec2-user/environment/sam-app/template.yaml --port=8080 --host=127.0.0.1 --static_dir=public --layer_cache_basedir=/home/ec2-user/.aws-sam/layers-pkg --container_host=localhost --container_host_interface=127.0.0.1
2022-03-09 21:59:01,513 | local start-api command is called
2022-03-09 21:59:01,520 | No Parameters detected in the template
2022-03-09 21:59:01,535 | There is no customer defined id or cdk path defined for resource HelloWorldFunction, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,535 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,536 | 2 stacks found in the template
2022-03-09 21:59:01,536 | No Parameters detected in the template
2022-03-09 21:59:01,548 | There is no customer defined id or cdk path defined for resource HelloWorldFunction, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,549 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,549 | 2 resources found in the stack
2022-03-09 21:59:01,549 | No Parameters detected in the template
2022-03-09 21:59:01,561 | There is no customer defined id or cdk path defined for resource HelloWorldFunction, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,561 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,562 | Found Serverless function with name='HelloWorldFunction' and CodeUri='hello_world/'
2022-03-09 21:59:01,562 | --base-dir is not presented, adjusting uri hello_world/ relative to /home/ec2-user/environment/sam-app/template.yaml
2022-03-09 21:59:01,566 | No Parameters detected in the template
2022-03-09 21:59:01,578 | There is no customer defined id or cdk path defined for resource HelloWorldFunction, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,578 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,579 | No Parameters detected in the template
2022-03-09 21:59:01,591 | There is no customer defined id or cdk path defined for resource HelloWorldFunction, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,591 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:59:01,592 | Found '1' API Events in Serverless function with name 'HelloWorldFunction'
2022-03-09 21:59:01,592 | Detected Inline Swagger definition
2022-03-09 21:59:01,592 | Lambda function integration not found in Swagger document at path='/hello' method='get'
2022-03-09 21:59:01,592 | Found '0' APIs in resource 'ServerlessRestApi'
2022-03-09 21:59:01,592 | Removed duplicates from '0' Explicit APIs and '1' Implicit APIs to produce '1' APIs
2022-03-09 21:59:01,592 | 1 APIs found in the template
2022-03-09 21:59:01,597 | Mounting HelloWorldFunction at http://127.0.0.1:8080/hello [GET]
2022-03-09 21:59:01,597 | 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. You only need to restart SAM CLI if you update your AWS SAM template
2022-03-09 21:59:01,597 | Localhost server is starting up. Multi-threading = True
2022-03-09 21:59:01 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
2022-03-09 21:59:05,233 | Constructed String representation of Event to invoke Lambda. Event: {"body": null, "headers": {"Accept": "*/*", "Host": "localhost:8080", "User-Agent": "curl/7.79.1", "X-Forwarded-Port": "8080", "X-Forwarded-Proto": "http"}, "httpMethod": "GET", "isBase64Encoded": false, "multiValueHeaders": {"Accept": ["*/*"], "Host": ["localhost:8080"], "User-Agent": ["curl/7.79.1"], "X-Forwarded-Port": ["8080"], "X-Forwarded-Proto": ["http"]}, "multiValueQueryStringParameters": null, "path": "/hello", "pathParameters": null, "queryStringParameters": null, "requestContext": {"accountId": "123456789012", "apiId": "1234567890", "domainName": "localhost:8080", "extendedRequestId": null, "httpMethod": "GET", "identity": {"accountId": null, "apiKey": null, "caller": null, "cognitoAuthenticationProvider": null, "cognitoAuthenticationType": null, "cognitoIdentityPoolId": null, "sourceIp": "127.0.0.1", "user": null, "userAgent": "Custom User Agent String", "userArn": null}, "path": "/hello", "protocol": "HTTP/1.1", "requestId": "960f886e-5290-4dab-b2e1-100713a3ce1b", "requestTime": "09/Mar/2022:21:59:01 +0000", "requestTimeEpoch": 1646863141, "resourceId": "123456", "resourcePath": "/hello", "stage": "Prod"}, "resource": "/hello", "stageVariables": null, "version": "1.0"}
2022-03-09 21:59:05,233 | Found one Lambda function with name 'HelloWorldFunction'
2022-03-09 21:59:05,234 | Invoking app.lambda_handler (python3.7)
2022-03-09 21:59:05,234 | No environment variables found for function 'HelloWorldFunction'
2022-03-09 21:59:05,234 | Environment variables overrides data is standard format
2022-03-09 21:59:05,234 | Loading AWS credentials from session with profile 'None'
2022-03-09 21:59:05,247 | Resolving code path. Cwd=/home/ec2-user/environment/sam-app, CodeUri=/home/ec2-user/environment/sam-app/hello_world
2022-03-09 21:59:05,247 | Resolved absolute path to code is /home/ec2-user/environment/sam-app/hello_world
2022-03-09 21:59:05,247 | Code /home/ec2-user/environment/sam-app/hello_world is not a zip/jar file
2022-03-09 21:59:05,272 | Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.7:rapid-1.40.1-x86_64.

2022-03-09 21:59:05,273 | Mounting /home/ec2-user/environment/sam-app/hello_world as /var/task:ro,delegated inside runtime container
2022-03-09 21:59:06,001 | Starting a timer for 3 seconds for function 'HelloWorldFunction'
END RequestId: 1d6476a7-580a-4da4-9842-8195db09b873
REPORT RequestId: 1d6476a7-580a-4da4-9842-8195db09b873 Init Duration: 0.26 ms Duration: 90.01 ms Billed Duration: 91 ms Memory Size: 128 MB Max Memory Used: 128 MB
2022-03-09 21:59:06,346 | Cleaning all decompressed code dirs
2022-03-09 21:59:06,347 | Unable to find Click Context for getting session_id.
2022-03-09 21:59:06,347 | No Content-Type given. Defaulting to 'application/json'.
2022-03-09 21:59:06 127.0.0.1 - - [09/Mar/2022 21:59:06] "GET /hello HTTP/1.1" 200 -
```

**With the .aws-sam directory present**

```admin:~/environment/sam-app $ sam local start-api --port 8080 --debug
2022-03-09 21:56:59,144 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2022-03-09 21:56:59,145 | Using config file: samconfig.toml, config environment: default
2022-03-09 21:56:59,145 | Expand command line arguments to:
2022-03-09 21:56:59,145 | --template_file=/home/ec2-user/environment/sam-app/.aws-sam/build/template.yaml --port=8080 --host=127.0.0.1 --static_dir=public --layer_cache_basedir=/home/ec2-user/.aws-sam/layers-pkg --container_host=localhost --container_host_interface=127.0.0.1
2022-03-09 21:56:59,219 | local start-api command is called
2022-03-09 21:56:59,225 | No Parameters detected in the template
2022-03-09 21:56:59,241 | Sam customer defined id is more priority than other IDs. Customer defined id for resource HelloWorldFunction is HelloWorldFunction
2022-03-09 21:56:59,241 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:56:59,243 | 2 stacks found in the template
2022-03-09 21:56:59,243 | No Parameters detected in the template
2022-03-09 21:56:59,264 | Sam customer defined id is more priority than other IDs. Customer defined id for resource HelloWorldFunction is HelloWorldFunction
2022-03-09 21:56:59,264 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:56:59,265 | 2 resources found in the stack
2022-03-09 21:56:59,265 | No Parameters detected in the template
2022-03-09 21:56:59,278 | Sam customer defined id is more priority than other IDs. Customer defined id for resource HelloWorldFunction is HelloWorldFunction
2022-03-09 21:56:59,278 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:56:59,279 | Found Serverless function with name='HelloWorldFunction' and CodeUri='HelloWorldFunction'
2022-03-09 21:56:59,279 | --base-dir is not presented, adjusting uri HelloWorldFunction relative to /home/ec2-user/environment/sam-app/.aws-sam/build/template.yaml
2022-03-09 21:56:59,282 | No Parameters detected in the template
2022-03-09 21:56:59,296 | Sam customer defined id is more priority than other IDs. Customer defined id for resource HelloWorldFunction is HelloWorldFunction
2022-03-09 21:56:59,296 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:56:59,297 | No Parameters detected in the template
2022-03-09 21:56:59,310 | Sam customer defined id is more priority than other IDs. Customer defined id for resource HelloWorldFunction is HelloWorldFunction
2022-03-09 21:56:59,310 | There is no customer defined id or cdk path defined for resource ServerlessRestApi, so we will use the resource logical id as the resource id
2022-03-09 21:56:59,311 | Found '1' API Events in Serverless function with name 'HelloWorldFunction'
2022-03-09 21:56:59,311 | Detected Inline Swagger definition
2022-03-09 21:56:59,311 | Lambda function integration not found in Swagger document at path='/hello' method='get'
2022-03-09 21:56:59,311 | Found '0' APIs in resource 'ServerlessRestApi'
2022-03-09 21:56:59,311 | Removed duplicates from '0' Explicit APIs and '1' Implicit APIs to produce '1' APIs
2022-03-09 21:56:59,311 | 1 APIs found in the template
2022-03-09 21:56:59,316 | Mounting HelloWorldFunction at http://127.0.0.1:8080/hello [GET]
2022-03-09 21:56:59,316 | 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. You only need to restart SAM CLI if you update your AWS SAM template
2022-03-09 21:56:59,316 | Localhost server is starting up. Multi-threading = True
2022-03-09 21:56:59 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
2022-03-09 21:57:06,905 | Constructed String representation of Event to invoke Lambda. Event: {"body": null, "headers": {"Accept": "*/*", "Host": "localhost:8080", "User-Agent": "curl/7.79.1", "X-Forwarded-Port": "8080", "X-Forwarded-Proto": "http"}, "httpMethod": "GET", "isBase64Encoded": false, "multiValueHeaders": {"Accept": ["*/*"], "Host": ["localhost:8080"], "User-Agent": ["curl/7.79.1"], "X-Forwarded-Port": ["8080"], "X-Forwarded-Proto": ["http"]}, "multiValueQueryStringParameters": null, "path": "/hello", "pathParameters": null, "queryStringParameters": null, "requestContext": {"accountId": "123456789012", "apiId": "1234567890", "domainName": "localhost:8080", "extendedRequestId": null, "httpMethod": "GET", "identity": {"accountId": null, "apiKey": null, "caller": null, "cognitoAuthenticationProvider": null, "cognitoAuthenticationType": null, "cognitoIdentityPoolId": null, "sourceIp": "127.0.0.1", "user": null, "userAgent": "Custom User Agent String", "userArn": null}, "path": "/hello", "protocol": "HTTP/1.1", "requestId": "875a62b7-f77a-430d-9d4c-afbb7dc31b22", "requestTime": "09/Mar/2022:21:56:59 +0000", "requestTimeEpoch": 1646863019, "resourceId": "123456", "resourcePath": "/hello", "stage": "Prod"}, "resource": "/hello", "stageVariables": null, "version": "1.0"}
2022-03-09 21:57:06,905 | Found one Lambda function with name 'HelloWorldFunction'
2022-03-09 21:57:06,905 | Invoking app.lambda_handler (python3.7)
2022-03-09 21:57:06,905 | No environment variables found for function 'HelloWorldFunction'
2022-03-09 21:57:06,905 | Environment variables overrides data is standard format
2022-03-09 21:57:06,905 | Loading AWS credentials from session with profile 'None'
2022-03-09 21:57:06,917 | Resolving code path. Cwd=/home/ec2-user/environment/sam-app/.aws-sam/build, CodeUri=/home/ec2-user/environment/sam-app/.aws-sam/build/HelloWorldFunction
2022-03-09 21:57:06,917 | Resolved absolute path to code is /home/ec2-user/environment/sam-app/.aws-sam/build/HelloWorldFunction
2022-03-09 21:57:06,917 | Code /home/ec2-user/environment/sam-app/.aws-sam/build/HelloWorldFunction is not a zip/jar file
2022-03-09 21:57:06,931 | Skip pulling image and use local one: public.ecr.aws/sam/emulation-python3.7:rapid-1.40.1-x86_64.

2022-03-09 21:57:06,931 | Mounting /home/ec2-user/environment/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
2022-03-09 21:57:07,613 | Starting a timer for 3 seconds for function 'HelloWorldFunction'
END RequestId: 0d6b34b8-a32a-4187-903c-fadabc8345f2
REPORT RequestId: 0d6b34b8-a32a-4187-903c-fadabc8345f2 Init Duration: 0.85 ms Duration: 90.03 ms Billed Duration: 91 ms Memory Size: 128 MB Max Memory Used: 128 MB
2022-03-09 21:57:07,979 | Cleaning all decompressed code dirs
2022-03-09 21:57:07,979 | Unable to find Click Context for getting session_id.
2022-03-09 21:57:07,980 | No Content-Type given. Defaulting to 'application/json'.
2022-03-09 21:57:07 127.0.0.1 - - [09/Mar/2022 21:57:07] "GET /hello HTTP/1.1" 200 -
```

### Expected result:

I expect this to be consistent. IMO the original code should be preferred. As it stands now this is not intuitive and requires developers to 1) know and 2) work with this behavior. Needing to either `rm -rf .aws-sam` or `sam build` during development is cumbersome.

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

1. OS: AL2
13. `sam --version`: `SAM CLI, version 1.40.1`
14. AWS region: us-west-2

Contributor guide

Open the contributing guide

Research direction

Reproduce the behavior with `sam local start-api`, `sam build`, and the HelloWorld template using `hello_world/app.py`, comparing mounts from the source tree and `.aws-sam/build`. Start at the `sam local start-api` command entry point and trace template and code-path selection. Done means source edits are reflected consistently after restarting with an existing `.aws-sam` directory, with regression coverage for both paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, docker, python
Domain
cli, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.