According to my experience, if you want to create an AWS Lambda without interactive mode, 15 templates below don't exists for each runtime, for example,
Data processing
template only exists fordotnet
andnodejs
.
Notice that third template name isHello World Example with Powertools for AWS Lambda
in below output, but if you want to create a project with python runtime and third template in the belowsam init
output, you have to usehello-world-powertools-python
as a template name. But it is not mentioned in help. So, i just usedsam init
in interactive mode and output of this command showed me template name.sam init --name my-data-processing-app --runtime python3.9 --dependency-manager pip --app-template hello-world-powertools-python
$ sam init
You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Data processing
3 - Hello World Example with Powertools for AWS Lambda
4 - Multi-step workflow
5 - Scheduled task
6 - Standalone function
7 - Serverless API
8 - Infrastructure event management
9 - Lambda Response Streaming
10 - Serverless Connector Hello World Example
11 - Multi-step workflow with Connectors
12 - Full Stack
13 - Lambda EFS example
14 - DynamoDB Example
15 - Machine Learning
Template: 1
Use the most popular runtime and package type? (Python and zip) [y/N]:
$ sam init --help
Usage: sam init [OPTIONS]
Description:
Initialize a serverless application with an AWS SAM template, source code and
structure for serverless abstractions which connect to event source(s) such as APIs,
S3 Buckets or DynamoDB Tables. This application includes everything one needs to
get started with serverless and eventually grow into a production scale application.
To explore initializing with your own template and/or using a custom location,
please take a look at our official documentation.
This command may not require access to AWS credentials.
Examples:
Interactive Mode:
$ sam init
Customized Interactive Mode:
$ sam init --name sam-app --runtime nodejs18.x --architecture arm64
$ sam init --name sam-app --runtime nodejs18.x --dependency-manager npm --app-template hello-world
$ sam init --name sam-app --package-type image --architecture arm64
Direct Initialization:
$ sam init --location gh:aws-samples/cookiecutter-aws-sam-python
$ sam init --location git+ssh://git@github.com/aws-samples/cookiecutter-aws-sam-python.git
$ sam init --location /path/to/template.zip
$ sam init --location /path/to/template/directory
$ sam init --location https://example.com/path/to/template.zip
Application Options:
-n, --name TEXT Name of AWS SAM Application.
--architecture ARCHITECTURE Architectures for Lambda functions.
Architectures: ['arm64', 'x86_64']
--runtime RUNTIME Lambda runtime for application.
Runtimes: dotnet6, go1.x, java17, java11, java8.al2, java8, nodejs18.x, nodejs16.x,
nodejs14.x, nodejs12.x, provided, provided.al2, python3.9, python3.8, python3.7,
python3.10, ruby3.2, ruby2.7
--dependency-manager DEPENDENCY_MANAGER
Dependency manager for Lambda runtime.
Dependency managers: bundler, cli-package, pip, maven, npm, gradle, mod
-l, --location TEXT Template location (git, mercurial, http(s), zip, path).
--package-type PACKAGE_TYPE Lambda deployment package type.
Package Types: Zip, Image
--base-image BASE_IMAGE Lambda base image for deploying IMAGE based package type.
Base images: amazon/ruby2.7-base, amazon/python3.8-base, amazon/java11-base,
amazon/nodejs14.x-base, amazon/python3.9-base, amazon/nodejs16.x-base,
amazon/nodejs12.x-base, amazon/ruby3.2-base, amazon/python3.7-base,
amazon/java8-base, amazon/go-provided.al2-base, amazon/java8.al2-base,
amazon/python3.10-base, amazon/nodejs18.x-base, amazon/dotnet6-base,
amazon/go1.x-base, amazon/java17-base
--app-template TEXT Identifier of the managed application template to be used. Alternatively, run '$sam
init' without options for an interactive workflow.
-o, --output-dir PATH Directory to initialize AWS SAM application.
Non Interactive Options:
--no-interactive Disable interactive prompting for init parameters. (fail if any required values are
missing)
--no-input Disable Cookiecutter prompting and accept default values defined in the cookiecutter
config.
--extra-context TEXT Override custom parameters in the template's cookiecutter.json configuration e.g.
{"customParam1": "customValue1", "customParam2":"customValue2"}
Configuration Options:
Learn more about configuration files at:
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html.
--config-env TEXT Environment name specifying default parameter values in the configuration file.
[default: default]
--config-file TEXT Configuration file containing default parameter values. [default: samconfig.toml]
Additional Options:
--tracing / --no-tracing Enable AWS X-Ray tracing for application.
--application-insights / --no-application-insights
Enable CloudWatch Application Insights monitoring for application.
Beta Options:
--beta-features / --no-beta-features
Enable/Disable beta features.
Other Options:
--debug Turn on debug logging to print debug message generated by AWS SAM CLI and display
timestamps.
-h, --help Show this message and exit.
AWS Runtimes
Find more details in https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html
Name | Identifier | SDK | Operating system | Architectures | Deprecation (Phase 1) |
---|---|---|---|---|---|
Node.js 20 | nodejs20.x | 3.362.0 | Amazon Linux 2 | x86_64, arm64 | |
Node.js 18 | nodejs18.x | 3.362.0 | Amazon Linux 2 | x86_64, arm64 | |
Node.js 16 | nodejs16.x | 2.1374.0 | Amazon Linux 2 | x86_64, arm64 | Mar 11, 2024 |
Node.js 14 | nodejs14.x | 2.1374.0 | Amazon Linux 2 | x86_64, arm64 | Nov 27, 2023 |
Python 3.12 | python3.1 2 | boto3-1.28.83 botocore-1.31.83 | Amazon Linux 2023 | x86_64, arm64 | |
Python 3.11 | python3.11 | boto3-1.28.83 botocore-1.31.83 | Amazon Linux 2 | x86_64, arm64 | |
Python 3.10 | python3.10 | boto3-1.26.90 botocore-1.29.90 | Amazon Linux 2 | x86_64, arm64 | |
Python 3.9 | python3.9 | boto3-1.26.90 botocore-1.29.90 | Amazon Linux 2 | x86_64, arm64 | |
Python 3.8 | python3.8 | boto3-1.26.90 botocore-1.29.90 | Amazon Linux 2 | x86_64, arm64 | |
Python 3.7 | python3.7 | boto3-1.26.90 botocore-1.29.90 | Amazon Linux | x86_64 | Nov 27, 2023 |
Java 21 | java 21 | Amazon Linux 2023 | x86_64, arm64 | ||
Java 17 | java17 | Amazon Linux 2 | x86_64, arm64 | ||
Java 11 | java11 | Amazon Linux 2 | x86_64, arm64 | ||
Java 8 | java8.al2 | Amazon Linux 2 | x86_64, arm64 | ||
Java 8 | java8 | Amazon Linux | x86_64 | Dec 31, 2023 | |
.NET 7 (container only) | dotnet7 | Amazon Linux 2 | x86_64, arm64 | May 14, 2024 | |
.NET 6 | dotnet6 | Amazon Linux 2 | x86_64, arm64 | ||
Go 1.x | go1.x | Amazon Linux | x86_64 | Dec 31, 2023 | |
Ruby 3.2 | ruby3.2 | 3.1.0 | Amazon Linux 2 | x86_64, arm64 | |
Ruby 2.7 | ruby2.7 | 3.1.0 | Amazon Linux 2 | x86_64, arm64 | Dec 7, 2023 |
Custom Runtime | provided.al2 | Amazon Linux 2 | x86_64, arm64 | ||
Custom Runtime | provided | Amazon Linux | x86_64 | Dec 31, 2023 |
Creating Python Lambda
kenanhancer@kenans-MacBook-Pro python % sam init --name sam-app-demo1 --runtime python3.10 --app-template hello-world
sam-app-demo1/
├── README.md
├── __init__.py
├── events
│ └── event.json
├── hello_world
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
├── samconfig.toml
├── template.yaml
└── tests
├── __init__.py
├── integration
│ ├── __init__.py
│ └── test_api_gateway.py
├── requirements.txt
└── unit
├── __init__.py
└── test_handler.py
5 directories, 14 files
import json
# import requests
def lambda_handler(event, context):
"""Sample pure Lambda function
Parameters
----------
event: dict, required
API Gateway Lambda Proxy Input Format
Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
context: object, required
Lambda Context runtime methods and attributes
Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
Returns
------
API Gateway Lambda Proxy Output Format: dict
Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
"""
# try:
# ip = requests.get("http://checkip.amazonaws.com/")
# except requests.RequestException as e:
# # Send some context about this error to Lambda Logs
# print(e)
# raise e
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
# "location": ip.text.replace("\n", "")
}),
}
kenanhancer@kenans-MacBook-Pro python % cd sam-app-demo1
kenanhancer@kenans-MacBook-Pro sam-app-demo1 % pyenv local 3.10.5
kenanhancer@kenans-MacBook-Pro sam-app-demo1 % python -m venv .venv
kenanhancer@kenans-MacBook-Pro sam-app-demo1 % source .venv/bin/activate
Notice the shell prompt displayed as
kenanhancer@kenans-MacBook-Pro sam-app-demo1 %
but after activating Python virtual environment, it is changed as;(.venv) kenanhancer@kenans-MacBook-Pro sam-app-demo1 %
so(.venv)
prefix is added in shell prompt.If your SAM app relies on native dependencies, consider building inside a Docker container to match the AWS Lambda execution environment:
sam build --use-container
The--use-container
option tells SAM to build your function inside a Docker container that replicates the AWS Lambda execution environment. The built artifacts are stored in the .aws-sam/build directory for deployment to AWS Lambda
(.venv) kenanhancer@kenans-MacBook-Pro sam-app-demo1 % sam build
Starting Build use cache
Manifest file is changed (new hash: c3c57a0bb310fed52e5a83d79fd5e487) or dependency folder (.aws-sam/deps/73ce0ea5-1e56-4d89-9ebb-95f34ea9f14a) is
missing for (HelloWorldFunction), downloading dependencies and copying/building source
Building codeuri: /Users/kenanhancer/Documents/projects/python/sam-app-demo1/hello_world runtime: python3.10 metadata: {} architecture: x86_64
functions: HelloWorldFunction
Running PythonPipBuilder:CleanUp
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
sam-app-demo1/
├── .aws-sam
│ ├── build
│ ├── build.toml
│ ├── cache
│ └── deps
├── .gitignore
├── .python-version
├── .venv
│ ├── bin
│ ├── include
│ ├── lib
│ └── pyvenv.cfg
├── README.md
├── __init__.py
├── events
│ └── event.json
├── hello_world
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
├── samconfig.toml
├── template.yaml
└── tests
├── __init__.py
├── integration
├── requirements.txt
└── unit
13 directories, 14 files
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app-demo1
Sample SAM Template for sam-app-demo1
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Resources:
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: hello_world/
Handler: app.lambda_handler
Runtime: python3.10
Architectures:
- x86_64
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
HelloWorldApi:
Description: "API Gateway endpoint URL for Prod stage for Hello World function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
HelloWorldFunction:
Description: "Hello World Lambda Function ARN"
Value: !GetAtt HelloWorldFunction.Arn
HelloWorldFunctionIamRole:
Description: "Implicit IAM Role created for Hello World function"
Value: !GetAtt HelloWorldFunctionRole.Arn
HelloWorldFunctionName:
Description: "Hello World Lambda Function Name"
Value: !Ref HelloWorldFunction
# More information about the configuration file can be found here:
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
version = 0.1
[default]
[default.global.parameters]
stack_name = "sam-app-demo1"
[default.build.parameters]
cached = true
parallel = true
[default.validate.parameters]
lint = true
[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
s3_prefix = "sam-app-demo1"
region = "eu-west-2"
image_repositories = []
[default.package.parameters]
resolve_s3 = true
[default.sync.parameters]
watch = true
[default.local_start_api.parameters]
warm_containers = "EAGER"
[default.local_start_lambda.parameters]
warm_containers = "EAGER"
Deploying
$ sam build
$ sam deploy --guided
$ sam deploy
Print CloudFormation Output variables
Find
stack_name
insamconfig.toml
config file and use in--stack-name
parameter
In AWS CloudFormation and the AWS Serverless Application Model (SAM), the name you give to a resource (like "HelloWorldFunction" in your template) is a logical ID. This logical ID is unique within the CloudFormation stack and is used to refer to the resource within the template. However, when the stack is deployed, AWS often appends a unique identifier to the names of the resources to ensure they are globally unique and to avoid naming conflicts during subsequent deployments.
For the AWS Lambda function created by SAM, the deployed function name will usually have the format:<StackName>-<LogicalFunctionName>-<RandomCharacters>
Notice below output of command,
HelloWorldFunctionName
value issam-app-demo1-HelloWorldFunction-30wAqhKAlIN1
,sam deploy
generates changed function name in terms of above info.
$ aws cloudformation describe-stacks --stack-name sam-app-demo1 --query "Stacks[0].Outputs"
[
{
"OutputKey": "HelloWorldFunctionIamRole",
"OutputValue": "arn:aws:iam::111111111111:role/sam-app-demo1-HelloWorldFunctionRole-1EUQN2XJ2UAOR",
"Description": "Implicit IAM Role created for Hello World function"
},
{
"OutputKey": "HelloWorldApi",
"OutputValue": "https://hg6ru01vu4.execute-api.eu-west-2.amazonaws.com/Prod/hello/",
"Description": "API Gateway endpoint URL for Prod stage for Hello World function"
},
{
"OutputKey": "HelloWorldFunctionName",
"OutputValue": "sam-app-demo1-HelloWorldFunction-30wAqhKAlIN1",
"Description": "Hello World Lambda Function Name"
},
{
"OutputKey": "HelloWorldFunction",
"OutputValue": "arn:aws:lambda:eu-west-2:111111111111:function:sam-app-demo1-HelloWorldFunction-30wAqhKAlIN1",
"Description": "Hello World Lambda Function ARN"
}
]
Test your function with AWS SAM CLI
$ sam local invoke "HelloWorldFunction"
Invoking app.lambda_handler (python3.10)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.10-rapid-x86_64.
Mounting /Users/kenanhancer/Documents/projects/python/sam-app-demo1/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
START RequestId: e8e32b98-55df-4d7a-bab9-a053f6a1aed9 Version: $LATEST
END RequestId: e8e32b98-55df-4d7a-bab9-a053f6a1aed9
REPORT RequestId: e8e32b98-55df-4d7a-bab9-a053f6a1aed9 Init Duration: 0.52 ms Duration: 210.84 ms Billed Duration: 211 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}%
$ sam local invoke "HelloWorldFunction" -e events/event.json
Invoking app.lambda_handler (python3.10)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.10-rapid-x86_64.
Mounting /Users/kenanhancer/Documents/projects/python/sam-app-demo1/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
START RequestId: 787c1967-c851-4c60-995b-bc74770c3b0f Version: $LATEST
END RequestId: 787c1967-c851-4c60-995b-bc74770c3b0f
REPORT RequestId: 787c1967-c851-4c60-995b-bc74770c3b0f Init Duration: 0.58 ms Duration: 210.20 ms Billed Duration: 211 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}%
$ echo '{"message": "hello!"}' | sam local invoke HelloWorldFunction -e -
Reading invoke payload from stdin (you can also pass it from file with --event)
Invoking app.lambda_handler (python3.10)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/python:3.10-rapid-x86_64.
Mounting /Users/kenanhancer/Documents/projects/python/sam-app-demo1/.aws-sam/build/HelloWorldFunction as
/var/task:ro,delegated, inside runtime container
START RequestId: cdc59941-7437-4da3-9597-8d56a1820168 Version: $LATEST
END RequestId: cdc59941-7437-4da3-9597-8d56a1820168
REPORT RequestId: cdc59941-7437-4da3-9597-8d56a1820168 Init Duration: 0.48 ms Duration: 232.18 ms Billed Duration: 233 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}%
Test your function with AWS CLI
Use function name as
sam-app-demo1-HelloWorldFunction-30wAqhKAlIN1
instead ofHelloWorldFunction
in the below command
$ aws lambda invoke \
--function-name sam-app-demo1-HelloWorldFunction-30wAqhKAlIN1 \
--region eu-west-2 \
--payload $(echo '{"name": "kenan"}' | base64) \
/dev/stdout
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
Test your function with curl
$ curl --request POST https://hg6ru01vu4.execute-api.eu-west-2.amazonaws.com/Prod/hello/ --data '{"name": "kenan"}'
{"message": "hello world"}
Why do i need to create a Python virtual environment for AWS SAM Python App?
I really chat with ChatGPT on it, and realized that virtual environment is not needed if you created your AWS Python Lambda project with AWS SAM CLI, because running
sam build
will already isolate packages in project directory and somehow will not use globalpip
or virtual environment `pip`
So I had a very long conversation. This is the thing, ChatGPT recommended in final round 🙂




Adding new endpoint
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app-demo1 Sample SAM Template for sam-app-demo1 # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 3 Resources: 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: hello_world/ Handler: app.lambda_handler Runtime: python3.10 Architectures: - x86_64 Events: HelloWorldPost: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: post HelloWorldGet: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn HelloWorldFunctionName: Description: "Hello World Lambda Function Name" Value: !Ref HelloWorldFunction
$ sam build $ sam deploy