I have noticed that SAM is producing a new layer each time we deploy, even though the contents of the layer should be bit-for-bit identical. Creating a new layer and deleting the old one takes time, so this slows down our deployments.
Consider this Makefile
:
build-KnexNodeModulesLayer:
mkdir -p "$(ARTIFACTS_DIR)/nodejs/"
npm install --prefix "$(ARTIFACTS_DIR)/nodejs/" pg@8.7.3 knex@1.0.1
# Flatten timestamps to avoid false change detection
find "$(ARTIFACTS_DIR)" | xargs touch -am -h -d 2019-02-11T05:09:12
If we then sam build
, and run find .aws-sam/build/KnexNodeModulesLayer/ -newermt "2019-02-12"
, we can see that all files, directories, and symlinks have the expected timestamp. However, running sam deploy
two times create two different versions of this layer.
I downloaded these layers, and found that all files and symlinks have the expected timestamp from our touch
command, but directories have the current timestamp:
❯ stat -c "%w %y %F %n" {a,b}/nodejs/node_modules/pg{,/LICENSE}
2022-03-15 12:28:10.681528449 -0400 2022-03-15 12:28:10.682330405 -0400 directory a/nodejs/node_modules/pg
2019-02-11 05:09:12.000000000 -0500 2019-02-11 05:09:12.000000000 -0500 regular file a/nodejs/node_modules/pg/LICENSE
2022-03-15 12:56:14.010637090 -0400 2022-03-15 12:56:14.011286674 -0400 directory b/nodejs/node_modules/pg
2019-02-11 05:09:12.000000000 -0500 2019-02-11 05:09:12.000000000 -0500 regular file b/nodejs/node_modules/pg/LICENSE
It seems like the process of creating the zip file is introducing this difference, and should be considered a bug.
Yes, the SHAs are different. This is because each time
sam build
creates the zip file, it introduces a different timestamp on the directories (current time, rather than the timestamp that the directory has on the filesystem).