Build and Deploy Serverless App with AWS SAM on CloudShell

Build and Deploy Serverless App with AWS SAM on CloudShell

avatar

TrungTin Tran

2025.07.14

Bài lab này sẽ hướng dẫn bạn các bước để create, build và deploy một serverless app gồm CloudFront, S3, API Gateway và Lambda bằng cách sử dụng AWS Serverless Application Model (SAM). Toàn bộ các bước sẽ được thực hiện trực tiếp trên AWS CloudShell, giúp bạn không cần cài đặt thủ công trên máy local.

Lab Details

  1. Duration: 20 minutes
  2. AWS Region: US East (N. Virginia) us-east-1

Introduction

  1. AWS SAM (Serverless Application Model) là một open-source framework giúp Developer dễ dàng build và deploy serverless applications trên AWS
  2. Nó sử dụng AWS CloudFormation để định nghĩa infrastructure và resource cho serverless application ví dụ như Lambda Function, API Gateway, DynamoDB
  3. SAM hỗ trợ nhiều ngôn ngữ lập trình Node. js, Java, Python, .NET and Go
  4. SAM cung cấp môi trường test và debug ở local cho phép Developer có thể test code trước khi deploy lên AWS
  5. Nó cũng cung cấp pre-built templates cho những common serverless application architectures, giúp chúng ta dễ dầng bắt đầu build một serverless applications.
  6. Tích hợp với  AWS CodePipeline cho CI/CD
  7. Cung cấp command-line interface (CLI) và AWS Toolkit for Visual Studio Code
  8. Đây là công cụ free
  9. Một số command line
    • sam init - cung cấp các option để khởi tạo new serverless application
    • sam build - chuẩn bị serverless application cho quy trình deployment tiếp theo như  local testing hoặc deploying to the AWS Cloud.
    • sam deploy - command to deploy your serverless application to the AWS Cloud.
    • sam delete - command cho phép xóa resource của serverless application bằng cách xóa Cloudformation stack

Architecture Diagram

Task Details

  1. Create an AWS CloudShell development environment.
  2. Build app
    • sam init
    • AWS SAM template
    • Lambda code
    • Deploy
  3. Test hoạt động
    • Upload index.html to S3 bucket
    • Access trực tiếp API
    • Access statis web thông qua CloudFront
    • Access API Gateway thông qua CloudFront
  4. Clean up

1. Create an AWS CloudShell development environment.

Bạn hoàn toàn có thể cài đặt Python, cấu hình aws configure và cài đặt SAM CLI để build và deploy ứng dụng trên máy local. Tuy nhiên, để tránh trường hợp môi trường không đồng nhất khiến bạn gặp lỗi khi chạy các lệnh trong blog này, mình sẽ sử dụng AWS CloudShell — một môi trường terminal được cấu hình sẵn trong AWS Console.

Việc dùng CloudShell giúp đảm bảo tất cả mọi người đều làm việc trên cùng một môi trường, nhất quán với môi trường mà mình dùng để demo.

Tại AWS Console:

  • Tìm kiếm CloudShell → Click chọn CloudShell.
  • Chờ khoảng 5–10 giây, môi trường CloudShell sẽ được khởi tạo.

Vậy là bạn đã có một IDE tích hợp command line để làm việc, viết code, và tương tác với các dịch vụ AWS.

Kiểm tra các công cụ cần thiết đã có sẵn chưa:

python3 --version
sam --version
aws s3 ls

Các lệnh trên sẽ giúp bạn xác nhận Python, AWS SAM CLIAWS CLI đã được cài sẵn trên CloudShell.

2. Build and deploy app

2.1 sam init

Run lệnh sau tại terminal của CloudShell

Thay {your-name} bằng tên của bạn

sam init \
    --runtime python3.9 \
    --name api-gateway-cloudfront-{your-name} \
    --app-template hello-world \
    --no-tracing \
    --no-application-insights \
    --structured-logging \
    --package-type Zip

AWS SAM CLI sẽ khởi tạo cho bạn project mẫu trong thư mục api-gateway-cloudfront-{your-name}.

Tiếp theo sẽ chuyển đến thư mục ứng dụng và kiểm tra cấu trúc bên trong:

cd api-gateway-cloudfront-{your-name}/
ls -la

2.2 Update AWS SAM template

Update file template.yaml với nội dung sau:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: api-gateway-cloudfront-sample

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: v1
      OpenApiVersion: 3.0.1

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Timeout: 5
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !Ref MyApi

  HelloWorldFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}

  SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub api-gateway-sample-${AWS::AccountId}-${AWS::Region}
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  SampleBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref SampleBucket
      PolicyDocument:
        Id: SampleBucket-BucketPolicy
        Statement:
          - Effect: Allow
            Action:
              - s3:GetObject
            Resource:
              - !Sub arn:aws:s3:::${SampleBucket}/*
            Principal:
              CanonicalUser: !GetAtt SampleBucketCloudFrontOriginAccessIdentity.S3CanonicalUserId

  SampleBucketCloudFrontOriginAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: !Sub Allows CloudFront to reach the ${SampleBucket}

  SampleDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        DefaultRootObject: index.html
        CustomErrorResponses:
          - ErrorCachingMinTTL: 300
            ErrorCode: 403
            ResponseCode: 200
            ResponsePagePath: /index.html
          - ErrorCachingMinTTL: 300
            ErrorCode: 404
            ResponseCode: 200
            ResponsePagePath: /index.html
        Origins:
          - Id: !Sub S3-${SampleBucket}
            DomainName: !GetAtt SampleBucket.RegionalDomainName
            S3OriginConfig:
              OriginAccessIdentity: !Sub origin-access-identity/cloudfront/${SampleBucketCloudFrontOriginAccessIdentity}
          - Id: !Sub API-Gateway-${MyApi}
            DomainName: !Sub ${MyApi}.execute-api.${AWS::Region}.amazonaws.com
            CustomOriginConfig:
              OriginProtocolPolicy: https-only
        DefaultCacheBehavior:
          TargetOriginId: !Sub S3-${SampleBucket}
          AllowedMethods:
            - GET
            - HEAD
          ViewerProtocolPolicy: redirect-to-https
          # CachingDisabled
          # https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html
          CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad
        CacheBehaviors:
          - PathPattern: 'v1/*'
            TargetOriginId: !Sub API-Gateway-${MyApi}
            AllowedMethods:
              - GET
              - HEAD
              - OPTIONS
              - PUT
              - PATCH
              - POST
              - DELETE
            CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad
            ViewerProtocolPolicy: redirect-to-https
        HttpVersion: http2

Outputs:
  HelloWorldApi:
    Value: !Sub 'https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/v1/hello/'

Cách 1 — Dùng CLI

  • Xoá file template.yaml cũ
rm template.yaml
  • Tạo file mới
nano template.yaml
  • Dán nội dung template.yaml phía trên vào.
  • Nhấn Ctrl + OEnter để save file.
  • Nhấn Ctrl + X để thoát nano.

Cách 2 — Upload file trực tiếp lên CloudShell

  1. Ở máy local: Tạo file template.yaml bằng VSCode, Notepad hoặc bất cứ editor nào.
  2. Tại CloudShell Console:
    • Click ActionsUpload file
    • Chọn file template.yaml từ máy tính

2.3 Build

Chạy lệnh để build project

sam build

2.4 Deploy

Chạy lệnh để deploy

sam deploy \
    --guided \
    --region us-east-1 \
    --stack-name api-gateway-cloudfront-{your-name}-stack

Thực hiện thao tác theo hướng dẫn, chỗ nào hỏi Y/N thì nhấn y và Enter. Không hỏi thì Y/N thì để các giá trị mặc định và nhấn Enter.

Quá trình Provisioning resource sẽ mất 2-3 phút.

AWS SAM thực chất sử dụng CloudFormation để tạo các resource, vì vậy có thể theo dõi toàn bộ quá trình khởi tạo và cập nhật resource trên AWS CloudFormation Console.

Khi quá trình hoàn tất, template sẽ output cho chúng ta API URL

3. Test hoạt động

3.1 Upload index.html to S3 bucket

Tải file index.html được cung cấp tại đây và upload lên S3 bucket vừa được tạo bởi SAM

3.2 Access trực tiếp API

3.3 Access static web thông qua CloudFront

3.4 Access API Gateway thông qua CloudFront

3.5 Invoke your Lambda function in the cloud

Chúng ta có thể sử dụng AWS SAM CLI để invoke Lambda function:

  1. Take note of your function’s LogicalResourceId from the template.yaml. It should be HelloWorldFunction.
  2. Run command bên dưới
sam remote invoke HelloWorldFunction --stack-name api-gateway-cloudfront-{your-name}-stack

Kết quả như bên dưới:

api-gateway-cloudfront-mentor $ sam remote invoke HelloWorldFunction --stack-name api-gateway-cloudfront-mentor-stack
Invoking Lambda Function HelloWorldFunction
START RequestId: d80261e2-5cc1-44e4-9b86-16c3fcc1c50a Version: $LATEST
END RequestId: d80261e2-5cc1-44e4-9b86-16c3fcc1c50a
REPORT RequestId: d80261e2-5cc1-44e4-9b86-16c3fcc1c50a  Duration: 6.58 ms       Billed Duration: 7 ms   Memory Size: 128 MB     Max Memory Used: 31 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}api-gateway-cloudfront-mentor $

4. Clean up

Vậy là chúng ta đã hoàn thành việc triển khai serverless web app với AWS SAM một cách nhanh chóng trên CloudShell. Sau khi kiểm tra xong, hãy xoá toàn bộ resource (bằng cách xoá CloudFormation stack) để tránh phát sinh chi phí không cần thiết.

  1. Empty S3 bucket: api-gateway-sample-{your-account-id}-us-east-1
  2. Delete SAM stack
sam delete \
    --stack-name api-gateway-cloudfront-{your-name}-stack

Thực hiện thao tác theo hướng dẫn, chỗ nào hỏi Y/N thì nhấn y và Enter.

Đợi 3-5 phút để quá trình delete resources hoàn tất

Challenges

Chắc hẳn các bạn khi làm việc với Lambda đều muốn có thể debug Lambda ở local. Không quá khó để thực hiện việc này, các công cụ cần thiết là

  • VS Code / AWS Cloud9 / JetBrains v.v
  • AWS Toolkit for VScode
  • Docker
  • SAM CLI

Tài liệu tham khảo