Capturing the discussion from a separate thread as a feature request for a .sam folder in project level to encapsulate SAM CLI's metadata such as build artifacts, packaged template etc. Similar to .samrc, we need to design this to make sure we keep the semantics and usage of this folder clear.
[Need Help/Owner 👋]: As next step, create a design document following the design document template (/designs/_template.md) and send a pull request for discussion before implementing.
FAQs
Can it exist in multiple places (project root & user home)?
No, just project root. .sam folder will contain build artifacts and it's project specific; moving to user home brings unwanted side effects (disk space and logic complexity).
Q: Can other tools consume the contents of this folder?
.sam folder contains read-only build artifacts so any tool built to work with sam can read from that.
Q: How does sam cli operate in absence of this folder?
We should create it in the absence of it - That provides a Just Works(tm) experience. Here's a sample scenario for this:
No explicit sam build from the user
UX
This is the ideal scenario assuming .sam folder contains artifacts, packaged-template and other commands are aware of .sam and .samrc:
- Initialize boilerplate:
sam init --name my-project && cd my-project
- Deploy:
sam deploy
SAM application will be deployed seamless and the entire process logged. One could introduce sam local before sam deploy and sam build will run seamlessly if .sam folder is absent.
Power users can then modify the convention and opinions if they wanted to.
Logic
sam deploy checks .sam absence and run sam build for the runtime chosen in template.yaml
sam deploy then run sam package
sam package creates a S3 bucket based on project name (.samrc) if one doesn't exist
sam deploy ultimately deploys the application
.samrc is instrumental in allowing the user to add his/her opinions to change this flow (e.g. custom build, custom stack name, custom s3 bucket name)
Pros
- Seamless experience and just works without having to know
built-template.yaml, packaged-template.yaml, etc.
- New users don't have to learn upfront how Lambda packaging works and embed
sam local within their package managers
npm run build -> sam build
npm run deploy -> sam deploy
make build -> sam build
make deploy -> sam deploy
- Power users can rely on
.sam and build wrappers/tools until sam package/deploy changes its logic
Cons
- This can only happen post-MVP as
sam local, sam package, and sam deploy would need to check for .sam
Q: How do CI/CD systems use this folder to extra artifacts etc.
Extra artifacts is a responsibility of the CI system and SAM only takes into account the application artifact so CloudFormation can deploy it afterwards - But perhaps I didn't understand the question.
[Future] Here's an example using CodeBuild where CodePipeline would pass that as an Input Artifact to CloudFormation:
phases:
install:
commands:
- echo "[Security phase]"
- pipenv check # run some CVE checks on deps
pre_build:
commands:
- echo "[Pre-Build phase] Nothing to be done as SAM build now handles that for me ;)"
build:
commands:
- echo "[Build phase] Starting SAM build `date` in `pwd`"
- sam build
- echo "[Build phase] SAM build completed on `date`"
post_build:
commands:
- echo "[Post-build] Uploading artifacts to S3 `date`"
- sam package
artifacts:
files:
- .sam/template-packaged.yaml
discard-paths: yes
[Post-MVP] Here's the same example but without changing sam package/deploy yet:
phases:
install:
commands:
- echo "[Security phase]"
- pipenv check # run some CVE checks on deps
- aws s3api head-bucket --bucket $BUILD_OUTPUT_BUCKET || aws s3 mb s3://$BUILD_OUTPUT_BUCKET
pre_build:
commands:
- echo "[Pre-Build phase] Nothing to be done as SAM build now handles that for me ;)"
build:
commands:
- echo "[Build phase] Starting SAM build `date` in `pwd`"
- sam build
- echo "[Build phase] SAM build completed on `date`"
post_build:
commands:
- echo "[Post-build] Uploading artifacts to S3 `date`"
- echo "Runs sed/awk/whatever needed to replace CodeUri in template.yaml to .sam/functionLogicalName/"
- sam package --template-file template.yaml --s3-bucket $BUILD_OUTPUT_BUCKET --output-template-file .sam/template-packaged.yaml
artifacts:
files:
- .sam/template-packaged.yaml
discard-paths: yes
By supporting .sam folder and only storing artifacts this can set the path for a fast follow up on sam package and sam deploy afterwards.
Capturing the discussion from a separate thread as a feature request for a
.samfolder in project level to encapsulate SAM CLI's metadata such as build artifacts, packaged template etc. Similar to.samrc, we need to design this to make sure we keep the semantics and usage of this folder clear.[Need Help/Owner 👋]: As next step, create a design document following the design document template (
/designs/_template.md) and send a pull request for discussion before implementing.FAQs
Can it exist in multiple places (project root & user home)?
No, just project root.
.samfolder will contain build artifacts and it's project specific; moving to user home brings unwanted side effects (disk space and logic complexity).Q: Can other tools consume the contents of this folder?
.samfolder contains read-only build artifacts so any tool built to work with sam can read from that.Q: How does sam cli operate in absence of this folder?
We should create it in the absence of it - That provides a
Just Works(tm)experience. Here's a sample scenario for this:No explicit sam build from the user
UX
This is the ideal scenario assuming
.samfolder contains artifacts, packaged-template and other commands are aware of.samand.samrc:sam init --name my-project && cd my-projectsam deploySAM application will be deployed seamless and the entire process logged. One could introduce
sam localbeforesam deployandsam buildwill run seamlessly if.samfolder is absent.Power users can then modify the convention and opinions if they wanted to.
Logic
sam deploychecks.samabsence and runsam buildfor the runtime chosen intemplate.yamlsam deploythen runsam packagesam packagecreates a S3 bucket based on project name (.samrc) if one doesn't existsam deployultimately deploys the application.samrcis instrumental in allowing the user to add his/her opinions to change this flow (e.g. custom build, custom stack name, custom s3 bucket name)Pros
built-template.yaml,packaged-template.yaml, etc.sam localwithin their package managersnpm run build -> sam buildnpm run deploy -> sam deploymake build -> sam buildmake deploy -> sam deploy.samand build wrappers/tools untilsam package/deploychanges its logicCons
sam local,sam package, andsam deploywould need to check for.samQ: How do CI/CD systems use this folder to extra artifacts etc.
Extra artifacts is a responsibility of the CI system and SAM only takes into account the application artifact so CloudFormation can deploy it afterwards - But perhaps I didn't understand the question.
[Future] Here's an example using CodeBuild where CodePipeline would pass that as an Input Artifact to CloudFormation:
[Post-MVP] Here's the same example but without changing
sam package/deployyet:By supporting
.samfolder and only storingartifactsthis can set the path for a fast follow up onsam packageandsam deployafterwards.