During work, or having problems, notes here always avoid forgetting
What is a lambda function
Lambda function is a very good service of AWS has just appeared in recent years. It allows users to get their programs up and running without having to install an environment like EC2. However, the Lambda function cannot be run on its own, it needs a trigger event, be it called via API, or via Jobs form from AWS CloudWatch. And it’s not all for a system but just a part of it. It is often the role of business logic, receiving information, retrieving information from other modules, returning results or writing data to the Database (DynamoDB or S3). If there is a cost for the server such as E2, then it only charges based on the time the function is called. Very economical, isn’t it. Documentation about Lambda function
What is API Gateway
Literally, API Gateway provides a way for external parties to communicate with system resources, such as api, or s3. With a variety of options, it can be restricted to pre-made permissions, keys, or to limit the IP address. API Gateway Documentation
What is SAM
SAM is an AWS service that helps deploy, install and configure system services and modules automatically on the AWS environment, via the configuration file template.yaml. Very convenient in the process of developing, testing and deploying with different parameter settings for each environment. Documentation about AWS SAM
Configure these services together
Below is a sample content of a typical yaml file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <span class="token key atrule">AWSTemplateFormatVersion</span> <span class="token punctuation">:</span> <span class="token string">'2010-09-09'</span> <span class="token key atrule">Transform</span> <span class="token punctuation">:</span> AWS <span class="token punctuation">:</span> <span class="token punctuation">:</span> Serverless <span class="token punctuation">-</span> <span class="token datetime number">2016-10-31</span> <span class="token key atrule">Description</span> <span class="token punctuation">:</span> <span class="token punctuation">...</span> <span class="token comment"># tham số dùng để truyền khi chạy từ aws cli</span> <span class="token key atrule">Parameters</span> <span class="token punctuation">:</span> <span class="token key atrule">Stage</span> <span class="token punctuation">:</span> <span class="token key atrule">Type</span> <span class="token punctuation">:</span> String <span class="token key atrule">AllowedValues</span> <span class="token punctuation">:</span> <span class="token punctuation">-</span> staging <span class="token punctuation">-</span> production <span class="token comment"># Định nghĩa các tham số tuỳ thuộc vào môi trường(staging/production)</span> <span class="token key atrule">Mappings</span> <span class="token punctuation">:</span> <span class="token key atrule">Configs</span> <span class="token punctuation">:</span> <span class="token key atrule">staging</span> <span class="token punctuation">:</span> <span class="token key atrule">tham_số</span> <span class="token punctuation">:</span> Giá_trị <span class="token key atrule">SourceVpce</span> <span class="token punctuation">:</span> <span class="token punctuation">-</span> vpce <span class="token punctuation">-</span> abc <span class="token comment">#VPC endpoint mà dùng để truy cập private api gateway</span> <span class="token key atrule">production</span> <span class="token punctuation">:</span> <span class="token comment">#môi trường production</span> <span class="token key atrule">tham_số</span> <span class="token punctuation">:</span> Giá_trị <span class="token key atrule">SourceVpce</span> <span class="token punctuation">:</span> <span class="token punctuation">-</span> vpce <span class="token punctuation">-</span> def <span class="token comment"># Định nghĩa biến môi trường, sau này có thể truy cập trong chương trình lambda</span> <span class="token comment"># Ví dụ: process.env.XXXX</span> <span class="token key atrule">Globals</span> <span class="token punctuation">:</span> <span class="token key atrule">Function</span> <span class="token punctuation">:</span> <span class="token key atrule">Timeout</span> <span class="token punctuation">:</span> <span class="token number">3</span> <span class="token key atrule">Environment</span> <span class="token punctuation">:</span> <span class="token key atrule">Variables</span> <span class="token punctuation">:</span> <span class="token key atrule">RELEASE_STAGE</span> <span class="token punctuation">:</span> <span class="token tag">!Ref</span> Stage <span class="token key atrule">BIẾN_TOÀN_CỤC</span> <span class="token punctuation">:</span> <span class="token tag">!FindInMap</span> <span class="token punctuation">[</span> Configs <span class="token punctuation">,</span> <span class="token tag">!Ref</span> Stage <span class="token punctuation">,</span> tham_số <span class="token punctuation">]</span> <span class="token comment"># Định nghĩa các service</span> <span class="token key atrule">Resources</span> <span class="token punctuation">:</span> <span class="token key atrule">FooBarApi</span> <span class="token punctuation">:</span> <span class="token key atrule">Type</span> <span class="token punctuation">:</span> AWS <span class="token punctuation">:</span> <span class="token punctuation">:</span> Serverless <span class="token punctuation">:</span> <span class="token punctuation">:</span> Api <span class="token key atrule">Properties</span> <span class="token punctuation">:</span> <span class="token key atrule">Name</span> <span class="token punctuation">:</span> FooBarApi <span class="token key atrule">StageName</span> <span class="token punctuation">:</span> Prod <span class="token key atrule">EndpointConfiguration</span> <span class="token punctuation">:</span> PRIVATE <span class="token comment"># option cho private API gateway</span> <span class="token key atrule">Auth</span> <span class="token punctuation">:</span> <span class="token key atrule">ResourcePolicy</span> <span class="token punctuation">:</span> <span class="token comment"># giới hạn resource có thể truy cập api gateway</span> <span class="token key atrule">CustomStatements</span> <span class="token punctuation">:</span> <span class="token key atrule">Effect</span> <span class="token punctuation">:</span> Allow <span class="token key atrule">Action</span> <span class="token punctuation">:</span> <span class="token string">'execute-api:Invoke'</span> <span class="token key atrule">Resource</span> <span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token string">'execute-api:/*/*/*'</span> <span class="token key atrule">Principal</span> <span class="token punctuation">:</span> <span class="token string">'*'</span> <span class="token key atrule">Condition</span> <span class="token punctuation">:</span> <span class="token key atrule">ForAnyValue:StringEquals</span> <span class="token punctuation">:</span> <span class="token comment"># Chỉ những vpce định nghĩa ở trên mới có thể truy cập đến private api gateway này</span> <span class="token key atrule">aws:sourceVpce</span> <span class="token punctuation">:</span> <span class="token tag">!FindInMap</span> <span class="token punctuation">[</span> Configs <span class="token punctuation">,</span> <span class="token tag">!Ref</span> Stage <span class="token punctuation">,</span> SourceVpce <span class="token punctuation">]</span> |
Points to note
Set API gateway as private
1 2 | <span class="token key atrule">EndpointConfiguration</span> <span class="token punctuation">:</span> PRIVATE |
Vpce limit
1 2 3 | <span class="token key atrule">ForAnyValue:StringEquals</span> <span class="token punctuation">:</span> <span class="token key atrule">aws:sourceVpce</span> <span class="token punctuation">:</span> <span class="token tag">!FindInMap</span> <span class="token punctuation">[</span> Configs <span class="token punctuation">,</span> <span class="token tag">!Ref</span> Stage <span class="token punctuation">,</span> SourceVpce <span class="token punctuation">]</span> |
Point to this API when defining a Lambda function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token key atrule">FooBarFunction</span> <span class="token punctuation">:</span> <span class="token key atrule">Type</span> <span class="token punctuation">:</span> <span class="token string">'AWS::Serverless::Function'</span> <span class="token key atrule">Properties</span> <span class="token punctuation">:</span> <span class="token key atrule">CodeUri</span> <span class="token punctuation">:</span> foor <span class="token punctuation">-</span> bar/ <span class="token key atrule">Handler</span> <span class="token punctuation">:</span> lambda.handler <span class="token key atrule">Runtime</span> <span class="token punctuation">:</span> nodejs10.x <span class="token key atrule">Timeout</span> <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token key atrule">Events</span> <span class="token punctuation">:</span> <span class="token comment"># Định ngĩa sự kiện kích hoạt Lambda function</span> <span class="token key atrule">PutLogistics</span> <span class="token punctuation">:</span> <span class="token key atrule">Type</span> <span class="token punctuation">:</span> Api <span class="token key atrule">Properties</span> <span class="token punctuation">:</span> <span class="token key atrule">RestApiId</span> <span class="token punctuation">:</span> <span class="token key atrule">Ref</span> <span class="token punctuation">:</span> FooBarApi <span class="token key atrule">Path</span> <span class="token punctuation">:</span> /foo/bar <span class="token key atrule">Method</span> <span class="token punctuation">:</span> put |
With the above definition, we have defined it at the same time
- API gateway
- Lambda function
- … can configure both S3, DynamoDB …
How to deploy SAM to AWS environment via cli
Note: you need to install
- cli aws
- sam cli
- Configure profiles inside 2 files ./aws/config and ./aws/credentials
1 2 3 4 5 6 7 8 | <span class="token punctuation">[</span> default <span class="token punctuation">]</span> output <span class="token operator">=</span> json region <span class="token operator">=</span> ap-northeast-1 <span class="token punctuation">[</span> xyz-staging <span class="token punctuation">]</span> output <span class="token operator">=</span> json region <span class="token operator">=</span> ap-northeast-1 |
1 2 3 4 5 6 7 8 | <span class="token punctuation">[</span> default <span class="token punctuation">]</span> aws_access_key_id <span class="token operator">=</span> <span class="token punctuation">..</span> . aws_secret_access_key <span class="token operator">=</span> <span class="token punctuation">..</span> <span class="token punctuation">..</span> <span class="token punctuation">[</span> xyz-staging <span class="token punctuation">]</span> aws_access_key_id <span class="token operator">=</span> <span class="token punctuation">..</span> . aws_secret_access_key <span class="token operator">=</span> <span class="token punctuation">..</span> . |
Build and deploy (deploy)
1 2 3 4 5 6 7 8 | sam build --profile xyz-staging sam package --profile xyz-staging --output-template packaged.yaml --s3-bucket xyz-sam-staging <span class="token comment"># xyz-sam-staging là S3 bucket dùng để lưu trữ data của cấu hình SAM này</span> sam deploy --profile xyz-staging --template-file packaged.yaml --region ap-northeast-1 --capabilities CAPABILITY_IAM --stack-name xyz-staging --parameter-overrides Stage <span class="token operator">=</span> staging <span class="token comment"># --stack-name xyz-staging: tên của stack khi triển khai lên aws, có thể vào AWS > Cloudformation để xem các stack, trạng thái của việc thực thi, thành công hay lỗi</span> |
Discuss the API definition in a template
There are two ways to define an api:
- Independent definition (as above example)
- Defining inside the events property of Function In this case, if you want to make the API private, you must define it in the Global Section (Because at this time, the
EndpointConfiguration
property is not supported) Refer to the example below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <span class="token key atrule">Globals</span> <span class="token punctuation">:</span> <span class="token key atrule">Api</span> <span class="token punctuation">:</span> <span class="token key atrule">EndpointConfiguration</span> <span class="token punctuation">:</span> PRIVATE <span class="token punctuation">...</span> <span class="token key atrule">FooBarFunction</span> <span class="token punctuation">:</span> <span class="token key atrule">Type</span> <span class="token punctuation">:</span> <span class="token string">'AWS::Serverless::Function'</span> <span class="token key atrule">Properties</span> <span class="token punctuation">:</span> <span class="token key atrule">CodeUri</span> <span class="token punctuation">:</span> foo <span class="token punctuation">-</span> bar/ <span class="token key atrule">Handler</span> <span class="token punctuation">:</span> lambda2.handler <span class="token key atrule">Runtime</span> <span class="token punctuation">:</span> nodejs10.x <span class="token key atrule">Timeout</span> <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token key atrule">Events</span> <span class="token punctuation">:</span> <span class="token key atrule">Foobar</span> <span class="token punctuation">:</span> <span class="token key atrule">Type</span> <span class="token punctuation">:</span> Api <span class="token key atrule">Properties</span> <span class="token punctuation">:</span> <span class="token key atrule">Path</span> <span class="token punctuation">:</span> /foo/bar <span class="token key atrule">Method</span> <span class="token punctuation">:</span> put <span class="token key atrule">Auth</span> <span class="token punctuation">:</span> <span class="token key atrule">ResourcePolicy</span> <span class="token punctuation">:</span> <span class="token key atrule">CustomStatements</span> <span class="token punctuation">:</span> <span class="token key atrule">Effect</span> <span class="token punctuation">:</span> Allow <span class="token key atrule">Action</span> <span class="token punctuation">:</span> <span class="token string">'execute-api:Invoke'</span> <span class="token key atrule">Resource</span> <span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token string">'execute-api:/*/*/*'</span> <span class="token key atrule">Principal</span> <span class="token punctuation">:</span> <span class="token string">'*'</span> <span class="token key atrule">Condition</span> <span class="token punctuation">:</span> <span class="token key atrule">ForAnyValue:StringEquals</span> <span class="token punctuation">:</span> <span class="token key atrule">aws:sourceVpce</span> <span class="token punctuation">:</span> <span class="token tag">!FindInMap</span> <span class="token punctuation">[</span> Configs <span class="token punctuation">,</span> <span class="token tag">!Ref</span> Stage <span class="token punctuation">,</span> SourceVpce <span class="token punctuation">]</span> <span class="token key atrule">Policies</span> <span class="token punctuation">:</span> <span class="token punctuation">-</span> AWSLambdaVPCAccessExecutionRole <span class="token punctuation">-</span> SecretsManagerReadWrite <span class="token punctuation">-</span> <span class="token key atrule">S3ReadPolicy</span> <span class="token punctuation">:</span> <span class="token key atrule">BucketName</span> <span class="token punctuation">:</span> <span class="token tag">!FindInMap</span> <span class="token punctuation">[</span> Configs <span class="token punctuation">,</span> <span class="token tag">!Ref</span> Stage <span class="token punctuation">,</span> ShopInfoBucket <span class="token punctuation">]</span> |
As you can see, instead of using property: RestApiId:
to point to the predefined API, we describe this API right in Function. It was quite convenient
Last words
So you’ve completed the configuration and deployment of interlinked services on AWS. Now it’s time to verify that they are implemented correctly by going to the AWS Manage console, looking in CloudFormation, Lambda function, API Gateway.
In the following articles, I will guide how to call this API Gateway from the command line, from the program, as well as separate tests Lambda function, API Gateway on the AWS Manage Console itself.
Love!