AWS CLI tool - AWS SAM CLI
AWS SAM CLI is a AWS CLI tool that allows you to develop, test and analysis your application in the local environment.
In MAC environment, install SAM tool by brew:
brew tap aws/tap
brew install aws-sam-cli
sam --version
If your SAM tool already exists, can execute the following command to update:
brew upgrade aws-sam-cli
Install AWS Toolkit plugin
Lambda Boilerplate Snippet for VS Code
After installing plugins, you can start to create AWS serverless application locally.
In VS Code, press Shift+Command+P
and search AWS: Create Lambda SAM Application
(Here we are using Mac M1)
Lambda supports two types of deployment packages, for example in NodeJS with: File archives(.zip): nodejs16.x Container images: nodejs16.x (image)
Here we select items nodejs16.x, arm64, AWS SAM Hello World, current-path, my-app.
Install and test helloworld
After installing the hello world application, cd hello-world/
and run npm install
next, go to the test folder to install Mocha test framework test tool and run testing:
cd test/
npm install
npm run test
Run lambda function locally
In the my-app path run the following commands:
sam local invoke -e events/event.json
Will output the following content:
Invoking app.lambdaHandler (nodejs16.x)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs16.x:rapid-1.60.0-arm64.
Mounting /local-lambda/my-app/hello-world as /var/task:ro,delegated inside runtime container
START RequestId: xxx-41ba-4f99-86b4-958478ee08c8 Version: $LATEST
{"statusCode":200,"body":"{\"message\":\"hello world\"}"}END RequestId: f7b63d4c-41ba-4f99-86b4-958478ee08c8
REPORT RequestId: xxx-41ba-4f99-86b4-958478ee08c8 Init Duration: 0.10 ms Duration: 101.99 ms Billed Duration: 102 ms Memory Size: 128 MB Max Memory Used: 128 MB
Mock the Event JSON from SQS source
Here we change the events/event.json content to mock the member subscription event message from SQS source:
{
"Records": [
{
"messageId": "xxx-xxx-xxx",
"receiptHandle": "d",
"body": "{\"id\":\"1\",\"type\":\"SUBSCRIPTION\",\"has_payload\":true,\"payload\":{\"@type\":\"t\",\"id\":\"32\",\"type\":\"BASIC_PLAN\",\"status\":\"START_REGISTED\",\"amount\":{\"currency_code\":\"TWD\",\"units\":\"100\",\"nanos\":0},\"tax\":{\"currency_code\":\"TWD\",\"units\":\"0\",\"nanos\":0},\"user_id\":\"3445\",\"subscription_id\":\"\",\"create_time\":\"2022-10-20T10:45:19.363Z\",\"update_time\":\"2022-10-20T10:45:19.363Z\"}}",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1666302877792",
"SenderId": "xxxx",
"ApproximateFirstReceiveTimestamp": "1666302878792"
},
"messageAttributes": {},
"md5OfBody": "xxxx",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:ap-northeast-1:xxx:xxxxsqsname_SQS",
"awsRegion": "ap-northeast-1"
}
]
}
Change the lambda app.js function content to output SQS body:
exports.lambdaHandler = async (event) => {
console.log("==output event body==");
let body = event.Records[0].body;
console.log(body);
try {
return {
'statusCode': 200,
'body': JSON.stringify({
message: 'hello world',
})
}
} catch (err) {
console.log(err);
return err;
}
};
Excute local command:
sam local invoke -e events/event.json
Output:
Invoking app.lambdaHandler (nodejs16.x)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs16.x:rapid-1.60.0-arm64.
Mounting /local-lambda/my-app/hello-world as /var/task:ro,delegated inside runtime container
START RequestId: xxx-16c5-4003-a486-58905c76a699 Version: $LATEST
2022-10-21T09:12:07.835Z xxx-16c5-4003-a486-58905c76a699 INFO ==output event body==
2022-10-21T09:12:07.836Z xxx-16c5-4003-a486-58905c76a699 INFO {"id":"1","type":"SUBSCRIPTION","has_payload":true,"payload":{"@type":"t","id":"32","type":"BASIC_PLAN","status":"START_REGISTED","amount":{"currency_code":"TWD","units":"100","nanos":0},"tax":{"currency_code":"TWD","units":"0","nanos":0},"user_id":"3445","subscription_id":"","create_time":"2022-10-20T10:45:19.363Z","update_time":"2022-10-20T10:45:19.363Z"}}
END RequestId: xxx-16c5-4003-a486-58905c76a699
REPORT RequestId: xxx-16c5-4003-a486-58905c76a699 Init Duration: 0.25 ms Duration: 112.33 ms Billed Duration: 113 ms Memory Size: 128 MB Max Memory Used: 128 MB
{"statusCode":200,"body":"{\"message\":\"hello world\"}"}%
Mock Lambda Environment Variables Locally
Here declare our local lambda environment variables like: “HOST”, “PATH”, “STAG” in a env.json file
(Here we use Parameters
is means the globally apply variables, and here can change to function name. Can refer here)
env/env.json
{
"Parameters": {
"HOST": "localtable",
"PATH": "/user/subscription",
"STAGE": "testing"
}
}
Those environments need to be declared in the cloudformation template file, open, and modify the template. yaml to add Environment
.Variables
with those variable
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
testing_payment_integration_lambda
Sample SAM Template for testing_payment_integration_lambda
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.lambdaHandler
Runtime: nodejs16.x
Architectures:
- arm64
Environment:
Variables:
HOST: host
PATH: path
STAGE: staging
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
....
Open app.js and using the process.env
get environment variables:
exports.lambdaHandler = async (event) => {
console.log("==output event body==");
let body = event.Records[0].body;
console.log(body);
console.log("==output env variables==");
let env = JSON.stringify(process.env.HOST);
console.log(env);
console.log("===stop");
try {
return {
'statusCode': 200,
'body': JSON.stringify({
message: 'hello world',
})
}
} catch (err) {
console.log(err);
return err;
}
};
Finally, execute the following command --env-vars file_name
(or -n file_name
) can override the env.json to global environment variables in the template
sam local invoke --env-vars env/env.json -e events/event.json