-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
watch Option for SAM Build command #921
Comments
To me this only happens using Ruby once I've added a gem into the equation, with my functions having If I don't use gems at all, then I have live reloading; but once I need gems, everything only works by rebuilding inside a container. And since that takes about a minute, it makes SAM pretty much unusable for me. I can't build every time I make a small change, it just takes too long. |
Is there any progress on this? Having to build every time for the most minor of code changes is not ideal. |
I'd like to see a slightly different take on this proposal. Rather than having a continual build function through |
Hi @alxx, So what is your workaround for that? Or can you share your experience on that? Thank you, |
I don't like to compare but Chalice as this feature if I'm not mistaken ;) |
Assuming this is hard to build the watch option since this has been open for the better part of a year. It seems an easier option would be to use a docker volume to share your code rather than requiring a build, this way you do not have to have an actual watch. |
For a workaround, you're able to simply delete the ref: |
Lacking of a |
That doesn't work for me. Running in python3.8 now and it doesn't pick up the packages in |
If you're using a Node runtime you may want to consider using Webpack to build bundles for each function instead of I followed this very excellent write-up: https://dev.to/elthrasher/managing-multiple-functions-with-aws-sam-and-webpack-1581 The relevant config: webpack.config.jsmodule.exports = {
entry: {
functionA: path.join(__dirname, 'src/functionA.js'),
functionB: path.join(__dirname, 'src/functionB.js'),
},
output: {
libraryTarget: 'commonjs2',
path: `${__dirname}/build`,
filename: '[name].js',
},
mode: process.env.NODE_ENV === 'dev' ? 'development' : 'production',
target: "node", // Let webpack know to generate a Node.js bundle
} template.yaml PingFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: build/
Handler: functionA.lambdaHandler
Runtime: nodejs12.x
|
I just used nodemon for this. Going to put this here in case it would make anyone else's life easier:
Run this in the root folder in one terminal and run |
Hey guys, So, we created a small npm package based in nodemon (samwatch): https://www.npmjs.com/package/samwatch https://github.com/mxitgo/samwatch The way it works is, it copies your js/json files as you save them from the source folder to the corresponding .aws-sam/build folder (as long as the names are the same for your lambda and the code uri in template.yaml). That is useful to see your changes reflected on the fly if you are running sam local start-api, so you don't have to run sam build after every change. On the other hand, if the corresponding file copy is not within the .aws-sam/build folder already, the package will trigger a sam build (unless you use n parameter). The package has helped us get a hot reload feeling for our local lambda function development with sam. I hope anyone can find it useful. Thanks! |
My usage is also with ruby code so i am using the live reloading as follows currently without actually using sam build. Not sure though if this is recommend or bad practice so would like to get feedback on it. Let say i have the following folder structure with 2 functions:
instead of using sam build i just do: (i do this from the root directory lambda_example)
Same thing then for the other function
Now if you then issue sam local start-api and you make changes to the code then the live reloading stuff should be working without actually needing to build each time. Ofcourse this only probably works if you don't need to build native extensions for gems but esentially you only need to call the bundle install commands above if you change gem dependencies which should not happen that often. The samwatch thing is cool but does not work for ruby cause it only monitors js or json files it seems. So maybe add an extra option in your cli @eamarce to specify which files to watch? |
Now that warm containers has been delivered under #2383 . Is there anyway this can be prioritized? It would help make that dev experience so much better. |
Its such a painful process running sam build even for a small change such as a console.log(). Any good workaround? The solutions above (webpack and samwatch) force a folder structure which I am not willing to do. |
@anubhavmalik only thing is to modify the code in the build folder. |
such a pain... maybe instead of a "watch" option, which will still need to build on every change and slow down development, we could mount the source folder in the container? |
In the case of lambda container images it looks like a |
I've been actually doing this and I am curious if this will produce many local images as it builds again. Is it going to do that? Seems like that's what's happening to mine. |
I remember using a previous version of the SAM cli and being able to just run the I'm wondering why this behavior was changed? Now I'm honestly considering not using the SAM cli because this workflow is rather annoying. |
Maybe a simple solution to that: make a symbolic-link (ln -s) from the source code to the build folder? Something like:
|
@jhechtf That behavior still holds true the difference is when you use build, SAM CLI places the artifacts into another directory with an updated template. When running As a note, we do prioritize off of reactions. So more reactions do help us in deciding priority for outstanding feature requests from the community. |
@jfuss I've seen that mentioned before, about simply not using "sam build", but when I remove the |
@jhechtf Is the node modules within the CodeUri of the Function? If not, you need to install your dependencies into the CodeUri location. SAM CLI mounts the CodeUri into the container, which means all the code needs to be under that directory. This is what |
@jfuss the template that I am using is the nodejs14.x generated by the sam cli, which does not include any CodeUri properties. I'll try to add that in, but considering the code gets generated in the
|
@jhechtf Happy to help but let's spin this off into a different issue. This will distract from the original intent of this issue/request. |
Check it.
CommonLayer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: common-dependencies
Description: Common dependencies
ContentUri: layers/common/
CompatibleRuntimes:
- python3.8
RetentionPolicy: Retain
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: functions/consult/
Handler: app.lambda_handler
Runtime: python3.8
Layers:
- !Ref CommonLayer
$ cd layers/commons/
$ pip install -r ../상대경로/requirements.txt -t ./python
$ sam local start-api -t template.yaml --skip-pull-image |
SummaryI am 100% NOT a fan of this watch idea. Editing code and hitting refresh would still take a long time. Perhaps the solution to the problem is rethinking what is needed. Perhaps... can we have a
I do not know if this is a fair ask of the SAM team. Maybe I need the work y'all have done inside of SAM to be a smaller components to assemble. Maybe we have this already and I have not found a good way to do just that... for my needs? Context & Hack AttemptsFor both Ruby, Node, etc, we use the SAM build image as a Docker in Docker development image. A good example of this in practice for Ruby/Rails is here. https://lamby.custominktech.com/docs/quick_start. When doing this, we can assume the local "host" (docker dev image) has everything we need, system dependencies, dev code which can be edited, etc. All we need is a simple API Gateway => Lambda emulator. For Rails, we completely side step this issue by using the built-in Today I was coming back to an old Node zip function I wrote a few years ago and wanted to move it to our latest patterns which includes SAM dev containers, production package type image, etc and was super frustrated that SAM does not have a way to support start-api with container images. I tried a few hacks. First, I tried a little bit of @mims92 recommendation by leaning into the need to do if [ ! -d "./.aws-sam" ]; then
sam build \
--parameter-overrides "StageEnv=development"
mkdir ./.aws-sam/build/Lambda
pushd ./.aws-sam/build/Lambda
ln -s ../../../src src
popd
fi
sam local start-api \
--host '0.0.0.0' \
--port 3031 \
--container-host 'host.docker.internal' I then had the crazy idea maybe I could use the RIE (https://docs.aws.amazon.com/lambda/latest/dg/images-test.html) built into my image. So I tried adding this to my RUN curl -Lo /usr/local/bin/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie \
&& chmod +x /usr/local/bin/aws-lambda-rie docker-compose run \
--entrypoint "/usr/local/bin/aws-lambda-rie --log-level debug" \
-p 9001:3031 \
node-container-test For this hack I tried to see if I could have a development only version of my ( AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
DevLambda:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Events:
HttpApiProxy:
Type: HttpApi
Properties:
ApiId: !Ref DevHttpApi
Runtime: nodejs14.x
Handler: src/index.handler
MemorySize: 512
Timeout: 30
DevHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
StageName: development sam local start-api \
--template 'template-dev.yaml' \
--container-host 'host.docker.internal' \
--docker-volume-basedir $DIDPWD \
--host '0.0.0.0' \
--port 3031 Where 💥💣💥 SAM HAS ANOTHER BUG THAT PREVENTS THIS. SEE HERE: #2837 But even if that did work, it would not be a good workaround for a container function that might have done a system dependency via yum install on both the production and development Docker files. Wrapping UpI GET IT! I get why this is hard. The Is there a way to use SAM's API Gateway => Lambda integration in some way to make local development work? |
Using @sbhvt's comment here #921 (comment) I was able to change my last hack above the 💥💣💥 in the following ways. First in my volumes:
- ${PWD}:${PWD}
working_dir: $PWD sam local start-api \
--template 'template-dev.yaml' \
--container-host 'host.docker.internal' \
--host '0.0.0.0' \
--port 3031 But this only works on Mac! I can not get it to work with GitHub Codespaces yet. I tried following this advice (https://dev.to/natterstefan/docker-tip-how-to-get-host-s-ip-address-inside-a-docker-container-5anh) and used So I'm blocked even on the hacks of hacks :( |
GOT IT TO WORK ON CODESPACES. Just needed to clear out Docker images and start from scratch. I'll be using extra_hosts:
- host.docker.internal:172.17.0.1 Which allows the bin/server wrapper to do the following, the key here is was adding sam local start-api \
--template 'template-dev.yaml' \
--container-host 'host.docker.internal' \
--container-host-interface '0.0.0.0' \
--host '0.0.0.0' \
--port 3031 AGAIN! This is hacks on top of hacks. IMO we do not need a watch command but better tooling to expose a simple API Gateway => Lambda server option that works with both Docker in Docker and Lambda Containers where it can be assumed that the Docker dev env has everything setup (built) where |
Hi! Works with PackageType: Image? Thks! |
Is there a workaround for projects created with |
Just having a sensible way to have a mounted volume inside the docker container would be awesome for my use case |
AWS, What does it take to solve that significant UX problem? Thanks to everyone who contributed with their solution; I'll re-iterate on what worked for me for Python project
|
This appears to be a JavaScript example But Python would need to be handled also |
Nope, this works in python, it watches the files with the .py extension - After playing with it for some time, I've added a delay to avoid re-building too quickly.
|
almost 4 years of this issue. Any news? |
Here's the command I ended up with for now:
Requires It runs nodemon and |
+1 for this feature |
I've only been experiencing this same issue for a bit so im only vaguely familiar but id like to a propose another solution that the sam team at AWS may be able to implement more easily than creating hot reload for the .aws-sam built folder: Context: Article: https://aws.amazon.com/blogs/compute/working-with-aws-lambda-and-lambda-layers-in-aws-sam/ When using the nodejs folder as described in the article and the docs, as long as you have generated the node modules manually using npm i, it should work just fine to run your code locally and have hot reloading without using sam build. The issue with this method is that when you need to move beyond local environments to testing or production, most pipelines will utilize sam build. When sam build is run, it will generate a nodejs folder inside your nodejs folder and not generate the dependencies correctly as it would if you didnt have the nodejs folder created (discussed in previous comments). So what im saying is maybe the sam developers would have an easier time fixing the current issue of duplicate nodejs folders which causes the dependency generation to not work, rather than trying to fix the issue of hot reload not working for the 'sam build' built .aws-sam folder. |
Describe your idea/feature/enhancement
When using
sam build
to build functions that will later be invoked throughsam local [invoke|start-lambda|start-api]
, you need to runsam build
before each invoke. The reason for this requirement is because the build command places artifacts (code + dependencies + updated template) into a build folder. Thesam local [invoke|start-lambda|start-api]
use these built templates (this has updated locations to the built function code) by default but there is no way to update the built code without runningsam build
again.Proposal
For the initial implementation of
sam build
, the--watch
option was out of scope. The proposal is to add support for this option to all customers to enable building when source code changes.An alternative could be to make the
sam local
suite of commands build the function during invoke. The main concern with this is the speed at which you can now invoke (other build enhancements might be a requirement for this, speed, incremental builds, etc).Workaround
All of the
sam local
command allow 'reloading' of the function code. This means for a given template, if you update the contents of a functions Code/CodeUri, SAM CLI will mount this updated content. So the current option for making interactions easier is to have two terminal windows open, one that builds and one that you local invoke with.The text was updated successfully, but these errors were encountered: