Hướng Dẫn Triển Khai API Serverless với AWS SAM và Github Action

Hướng Dẫn Triển Khai API Serverless với AWS SAM và Github Action

avatar

Long Ngo

2025.07.01

Trong bài blog này, chúng ta sẽ tìm hiểu cách sử dụng AWS Serverless Application Model (SAM) để triển khai một API serverless đơn giản theo mô hình "Hello World". Hướng dẫn này sẽ dẫn bạn qua các bước từ việc cài đặt môi trường, khởi tạo ứng dụng, xây dựng, triển khai, đến xóa tài nguyên trên AWS Cloud. Ứng dụng mẫu sẽ bao gồm một hàm AWS Lambda, một endpoint API Gateway và các vai trò IAM cần thiết.

Tổng quan

Trong thời đại công nghệ hiện nay, serverless computing đang trở thành xu hướng phổ biến nhờ khả năng giảm chi phí vận hành và tăng tính linh hoạt. AWS Serverless Application Model (SAM) là một công cụ mạnh mẽ giúp các nhà phát triển dễ dàng xây dựng và triển khai ứng dụng serverless trên AWS. Trong bài viết này, chúng ta sẽ tìm hiểu cách triển khai một API serverless đơn giản bằng SAM và tự động hóa quy trình triển khai bằng GitHub Actions, sử dụng xác thực OpenID Connect (OIDC) để tăng cường bảo mật.

Bài viết này sẽ hướng dẫn bạn qua các bước cụ thể, từ việc khởi tạo ứng dụng SAM, triển khai thủ công, đến thiết lập tự động hóa với GitHub Actions. Hướng dẫn được viết với giọng văn thân thiện, dễ hiểu, phù hợp cho cả người mới bắt đầu và người đã có kinh nghiệm với AWS.

Giới thiệu về AWS SAM

AWS SAM (Serverless Application Model) là một framework mã nguồn mở giúp các nhà phát triển xây dựng và triển khai ứng dụng serverless trên AWS. SAM sử dụng AWS CloudFormation để định nghĩa cơ sở hạ tầng và tài nguyên như Lambda Functions, API Gateway, và DynamoDB. Một số đặc điểm nổi bật của SAM:

  • Hỗ trợ nhiều ngôn ngữ lập trình: Node.js, Java, Python, .NET, và Go.
  • Cung cấp môi trường kiểm thử và gỡ lỗi cục bộ, giúp nhà phát triển kiểm tra mã trước khi triển khai.
  • Tích hợp với AWS CodePipeline để hỗ trợ CI/CD.
  • Cung cấp giao diện dòng lệnh (CLI) và tích hợp với AWS Toolkit for Visual Studio Code.
  • Miễn phí sử dụng.

Một số lệnh SAM CLI phổ biến:

  • sam init: Khởi tạo một ứng dụng serverless mới.
  • sam build: Chuẩn bị ứng dụng serverless cho kiểm thử cục bộ hoặc triển khai lên AWS.
  • sam deploy: Triển khai ứng dụng serverless lên AWS Cloud.
  • sam delete: Xóa tài nguyên của ứng dụng serverless bằng cách xóa CloudFormation stack.

Lab Introduction

  • Trình độ AWS: Người mới bắt đầu / Trung cấp
  • Thời gian hoàn thành: Khoảng 45 phút
  • Vùng AWS: US East (N. Virginia) us-east-1
  • Chi phí hoàn thành: Có thể sử dụng Free Tier
  • Dịch vụ sử dụng: AWS SAM, AWS Lambda, API Gateway, S3, IAM, GitHub Actions

Architecture Diagram

Dưới đây là kiến trúc tổng quan của ứng dụng sau khi hoàn thành triển khai:

Ứng dụng mẫu trong hướng dẫn này là một API "Hello World" đơn giản, bao gồm:

  • Một AWS Lambda Function xử lý các yêu cầu HTTP.
  • Một API Gateway để cung cấp endpoint cho API.
  • Một bucket S3 để lưu trữ artifact triển khai. (sam sẽ tự động tạo)
  • CloudFormation để quản lý cơ sở hạ tầng.
Tài nguyênMô tả
Lambda FunctionXử lý logic của API
API GatewayCung cấp endpoint để truy cập API
S3 BucketLưu trữ artifact triển khai
CloudFormationQuản lý và triển khai cơ sở hạ tầng

Prerequisites

Trước khi bắt đầu, bạn cần chuẩn bị:

  • Một tài khoản AWS .
  • Một tài khoản GitHub.
  • Git được cài đặt trên máy tính .

Task Details

  1. Cài đặt Sam CLI
  2. Khởi tạo ứng dụng SAM
  3. Xây dựng ứng dụng
  4. Triển khai ứng dụng lên AWS
  5. Thiết lập OIDC trong AWS
  6. Cấu hình GitHub Actions
  7. Test workflow:
  8. Clean Up

1. Cài đặt SAM CLI

Truy cập trang hướng dẫn chính thức để cài đặt SAM CLI phiên bản mới nhất cho hệ điều hành của bạn:

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html

Sau khi cài đặt, kiểm tra phiên bản:

sam --version

Tại thời điểm viết bài, phiên bản mới nhất là SAM CLI 1.135.x. Nếu gặp lỗi khi deploy, hãy kiểm tra release notes để cập nhật.

2. Khởi tạo ứng dụng SAM

Để bắt đầu, chúng ta sử dụng lệnh sam init để tạo một ứng dụng mẫu.

sam init

  • Chọn 1 - AWS Quick Start Templates
  • Chọn template "Hello World Example".
  • Chọn runtime là python (ấn y).
  • Không enable X-Ray tracing
  • Chọn không enable CloudWatch Application Insights
  • Enable Json format
  • Đặt tên dự án, ví dụ: soa-sam-app.

Sau khi chạy lệnh, thư mục dự án sẽ có cấu trúc như sau:

└── soa-sam-app
    ├── 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
  • template.yaml: Định nghĩa cơ sở hạ tầng của ứng dụng (Lambda Function, API Gateway, v.v.).
  • hello_world/app.py: Chứa mã nguồn của Lambda Function.

Hiểu file template.yaml — "trái tim" của SAM

File template.yaml là nơi bạn khai báo toàn bộ tài nguyên AWS mà ứng dụng cần. SAM sử dụng cú pháp mở rộng của CloudFormation, giúp viết ngắn gọn hơn nhiều. Dưới đây là nội dung mặc định của template Hello World:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31  # ← Dòng này báo cho CloudFormation biết đây là SAM template
Description: SAM Template for soa-sam-app

Globals:                     # Cấu hình chung cho tất cả Lambda functions
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:        # Tên logical của Lambda Function
    Type: AWS::Serverless::Function  # ← SAM resource type (viết ngắn hơn CloudFormation)
    Properties:
      CodeUri: hello_world/  # Thư mục chứa source code
      Handler: app.lambda_handler  # File app.py, function lambda_handler
      Runtime: python3.13
      Architectures:
        - x86_64
      Events:                # Định nghĩa trigger cho Lambda
        HelloWorld:
          Type: Api          # ← SAM tự động tạo API Gateway cho bạn
          Properties:
            Path: /hello
            Method: get

Outputs:
  HelloWorldApi:
    Description: "API Gateway endpoint URL"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"

Điểm quan trọng cần hiểu:

Khái niệmGiải thích
Transform: AWS::Serverless-2016-10-31Cho CloudFormation biết cần "dịch" SAM syntax sang CloudFormation chuẩn trước khi deploy
AWS::Serverless::FunctionResource type riêng của SAM — tự động tạo Lambda Function + IAM Role + Log Group. Nếu viết bằng CloudFormation thuần, bạn phải khai báo riêng từng resource
Events > Type: ApiSAM tự động tạo API Gateway + tích hợp với Lambda. Bạn không cần viết AWS::ApiGateway::RestApi riêng

SAM vs CloudFormation: Khi bạn chạy sam deploy, SAM sẽ transform template này thành CloudFormation template đầy đủ (có thể dài gấp 3-4 lần), sau đó gửi cho CloudFormation xử lý. Bạn có thể vào CloudFormation Console > chọn stack > tab Template để xem phiên bản đã được transform.

3. Xây dựng ứng dụng

Tiếp theo, chúng ta xây dựng ứng dụng bằng lệnh sam build để chuẩn bị các artifact cần thiết cho triển khai.

cd soa-sam-app
sam build

Lệnh này sẽ:

  • Tạo thư mục .aws-sam chứa các artifact đã được xây dựng.

(Bonus) Test local trước khi deploy

Một trong những điểm mạnh lớn nhất của SAM là khả năng chạy Lambda function ngay trên máy tính mà không cần deploy lên AWS. Điều này giúp bạn debug nhanh hơn và tiết kiệm thời gian.

Yêu cầu: Cần cài đặt Docker vì SAM sử dụng Docker container để mô phỏng môi trường Lambda.

Cách 1: Gọi function một lần (sam local invoke)

sam local invoke HelloWorldFunction --event events/event.json

Lệnh này sẽ khởi động Docker container, chạy Lambda function với event mẫu, rồi trả về kết quả.

Cách 2: Chạy API Gateway local (sam local start-api)

sam local start-api

Sau đó mở trình duyệt và truy cập http://127.0.0.1:3000/hello — bạn sẽ thấy kết quả tương tự như khi deploy lên AWS.

Trong lab này, bước test local là tùy chọn. Bạn có thể bỏ qua và deploy trực tiếp lên AWS ở bước tiếp theo.

4. Triển khai ứng dụng lên AWS

SAM deploy làm gì "behind the scenes"?

Trước khi chạy lệnh, hãy hiểu flow xử lý:

sam deploy
    ├── 1. Đọc template.yaml (SAM syntax)
    ├── 2. TransformCloudFormation template chuẩn
    ├── 3. Upload code artifact lên S3 bucket
    ├── 4. Tạo/Update CloudFormation Stack
    │       ├── Tạo Lambda Function
    │       ├── Tạo API Gateway
    │       ├── Tạo IAM Role cho Lambda
    │       └── Tạo CloudWatch Log Group
    └── 5. Output: API Gateway URL

Điểm mấu chốt: SAM không deploy trực tiếp. Nó chỉ là "translator" — dịch SAM template sang CloudFormation, rồi để CloudFormation làm việc nặng. Đây là lý do bạn thấy CloudFormation stack được tạo trong Console.

Chạy lệnh deploy

sam deploy --guided

Lệnh --guided sẽ hỏi bạn từng tham số. Dưới đây là giải thích chi tiết:

PromptGiá trịGiải thích
Stack NameSOA-Stack-Serverless-ApplicationTên CloudFormation stack — dùng để quản lý toàn bộ resources như một nhóm. Khi xóa stack, tất cả resources bên trong sẽ bị xóa theo
AWS Regionus-east-1Region nơi resources được tạo
Confirm changes before deployYHiển thị changeset (danh sách thay đổi) trước khi apply — giống terraform plan
Allow SAM CLI IAM role creationYCho phép SAM tự tạo IAM Role cho Lambda function
Disable rollbackyKhi deploy thất bại, giữ nguyên resources đã tạo (tiện debug). Trong production nên chọn N để tự động rollback
HelloWorldFunction has no authenticationYAPI Gateway endpoint sẽ public, không cần API key. Phù hợp cho demo, không nên dùng cho production
Save arguments to samconfig.tomlYLưu config để lần sau chỉ cần chạy sam deploy (không cần --guided)

Cuối cùng, nhập y để deploy changeset.

Sau khi deploy xong, vào CloudFormation Console và bạn sẽ thấy SAM đã tạo một stack chứa tất cả resources:

Nhớ: SAM = CloudFormation + syntactic sugar. Mọi thứ SAM tạo ra đều quản lý qua CloudFormation stack.

Sau khi triển khai, bạn có thể kiểm tra API bằng cách gửi yêu cầu HTTP đến endpoint được cung cấp.

  1. Kiểm tra lambda funtion mới được tạo
  2. API Gateway
  3. Vào Stage > Prd > Copy Invoke URL
  4. Vào trình duyệt và test:
https://{Invoke URL}/hello

  1. Sau khi chạy xong các bước trên các bạn sẽ có file samconfig.toml

5. Thiết lập OIDC trong AWS

Tại sao dùng OIDC thay vì Access Key?

Cách truyền thống để GitHub Actions truy cập AWS là lưu AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY vào GitHub Secrets. Nhưng cách này có rủi ro:

  • Access Key là long-lived credentials — nếu bị lộ, attacker có thể dùng mãi cho đến khi bạn xóa.
  • Phải rotate key định kỳ → phiền phức.

OIDC (OpenID Connect) giải quyết vấn đề này bằng cách:

GitHub Actions ──(1) Request OIDC Token──→ GitHub OIDC Provider
AWS STS ←──(2) Present Token + AssumeRole──────┘
   └──(3) Return temporary credentials (hết hạn sau 1 giờ)
  • Không cần lưu secret nào trong GitHub — mỗi lần workflow chạy, GitHub tự tạo temporary token.
  • AWS STS xác minh token và trả về temporary credentials (hết hạn sau 1 giờ).
  • Nếu token bị lộ, nó cũng vô dụng sau vài phút.

Tham khảo bài giải thích chi tiết OIDC của a PhongNX: Integrating GitHub Actions with AWS Using OIDC authentication

  1. Tạo Identity Provider

  2. Truy cập AWS Management Console, vào IAM > Identity providers > Add provider.

  3. Chọn OpenID Connect.

  4. Nhập Provider URL: https://token.actions.githubusercontent.com.

  5. Nhập Audience: sts.amazonaws.com.

  6. Nhấn Add provider để hoàn tất.

  7. Tạo IAM Role cần thiết cho Github Action

  8. Trong IAM Console, vào Roles > Create role.

  9. Chọn Web identity và chọn Identity Provider vừa tạo (token.actions.githubusercontent.com).

  10. Gắn các policy cần thiết. Thay vì dùng FullAccess (vi phạm nguyên tắc Least Privilege — một best practice quan trọng trong AWS), chúng ta tạo custom inline policy chỉ cấp đúng quyền cần thiết:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudFormationStack",
      "Effect": "Allow",
      "Action": [
        "cloudformation:CreateStack",
        "cloudformation:UpdateStack",
        "cloudformation:DeleteStack",
        "cloudformation:DescribeStacks",
        "cloudformation:DescribeStackEvents",
        "cloudformation:DescribeChangeSet",
        "cloudformation:CreateChangeSet",
        "cloudformation:ExecuteChangeSet",
        "cloudformation:DeleteChangeSet",
        "cloudformation:GetTemplateSummary",
        "cloudformation:ListStackResources"
      ],
      "Resource": "arn:aws:cloudformation:us-east-1:YOUR_ACCOUNT_ID:stack/SOA-Stack-*"
    },
    {
      "Sid": "S3DeploymentBucket",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:CreateBucket"
      ],
      "Resource": [
        "arn:aws:s3:::aws-sam-cli-managed-default-*",
        "arn:aws:s3:::aws-sam-cli-managed-default-*/*"
      ]
    },
    {
      "Sid": "LambdaManagement",
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:UpdateFunctionCode",
        "lambda:UpdateFunctionConfiguration",
        "lambda:DeleteFunction",
        "lambda:GetFunction",
        "lambda:ListTags",
        "lambda:TagResource",
        "lambda:UntagResource",
        "lambda:AddPermission",
        "lambda:RemovePermission",
        "lambda:GetFunctionConfiguration"
      ],
      "Resource": "arn:aws:lambda:us-east-1:YOUR_ACCOUNT_ID:function:SOA-Stack-*"
    },
    {
      "Sid": "APIGateway",
      "Effect": "Allow",
      "Action": [
        "apigateway:GET",
        "apigateway:POST",
        "apigateway:PUT",
        "apigateway:DELETE",
        "apigateway:PATCH"
      ],
      "Resource": "arn:aws:apigateway:us-east-1::*"
    },
    {
      "Sid": "IAMRoleForLambda",
      "Effect": "Allow",
      "Action": [
        "iam:CreateRole",
        "iam:DeleteRole",
        "iam:GetRole",
        "iam:PassRole",
        "iam:AttachRolePolicy",
        "iam:DetachRolePolicy",
        "iam:PutRolePolicy",
        "iam:DeleteRolePolicy",
        "iam:GetRolePolicy",
        "iam:TagRole",
        "iam:UntagRole"
      ],
      "Resource": "arn:aws:iam::YOUR_ACCOUNT_ID:role/SOA-Stack-*"
    }
  ]
}

Tại sao không dùng FullAccess? Trong thực tế và trong kỳ thi SOA, AWS luôn khuyến khích nguyên tắc Least Privilege — chỉ cấp đúng quyền cần thiết. Dùng AWSLambdaFullAccess hay AmazonS3FullAccess có thể cho phép xóa toàn bộ Lambda functions hoặc S3 buckets trong account, gây rủi ro bảo mật lớn.

  1. Đặt tên role, ví dụ: SOA-GitHubActions-SAMDeploy.
  2. Chỉnh sửa trust relationship của role:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:YOUR_GITHUB_USERNAME/YOUR_REPO_NAME:*"
        }
      }
    }
  ]
}

Giải thích Trust Policy:

FieldÝ nghĩa
FederatedCho phép OIDC provider của GitHub (không phải IAM user) assume role này
sts:AssumeRoleWithWebIdentityAction dùng cho xác thực qua web identity (OIDC)
aud: sts.amazonaws.comChỉ chấp nhận token được tạo cho AWS STS
sub: repo:YOUR_GITHUB_USERNAME/YOUR_REPO_NAME:*Chỉ cho phép repo cụ thể của bạn assume role. Dấu * cho phép tất cả branches

StringEquals vs StringLike: Dùng StringLike với wildcard * cho trường sub giúp workflow hoạt động trên mọi branch (main, master, feature/...). Nếu muốn giới hạn chỉ branch main, dùng StringEquals với giá trị repo:YOUR_GITHUB_USERNAME/YOUR_REPO_NAME:ref:refs/heads/main.

  • Thay YOUR_ACCOUNT_ID bằng ID tài khoản AWS của bạn.
  • Thay YOUR_GITHUB_USERNAMEYOUR_REPO_NAME bằng tên người dùng và kho lưu trữ GitHub của bạn.

6. Cấu hình GitHub Actions

Để tự động hóa triển khai, chúng ta tạo một workflow GitHub Actions.

  1. Trong kho lưu trữ GitHub, tạo thư mục .github/workflows và file deploy.yml:
name: SAM Deploy

on:
  push:
    paths:
      - 'hello_world/**' # Chỉ trigger khi code Lambda thay đổi

permissions:
  id-token: write   # Bắt buộc: cho phép GitHub request OIDC token
  contents: read     # Cho phép checkout code

jobs:
  deploy-sam:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5

      - name: Setup SAM CLI
        uses: aws-actions/setup-sam@v2

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: SAM Build
        run: sam build

      - name: SAM Deploy
        run: |
          sam deploy \
            --no-confirm-changeset \
            --no-fail-on-empty-changeset \
            --stack-name SOA-Stack-Serverless-Application \
            --capabilities CAPABILITY_IAM \
            --region ${{ secrets.AWS_REGION }}

Lưu ý về workflow:

  • id-token: writebắt buộc để GitHub Actions có thể request OIDC token gửi cho AWS STS.
  • actions/checkout@v4 chỉ cần gọi một lần (không cần fetch-depth: 0 trừ khi bạn cần git history).
  • actions/setup-python@v5 là phiên bản mới nhất (tránh dùng v3 đã cũ).
  • Region nên lấy từ secrets.AWS_REGION thay vì hardcode, để dễ thay đổi sau này.
  1. Đẩy mã nguồn lên GitHub:
git add .
git commit -m "Initial commit - AWS SAM API setup"
git push -u origin main

  1. Setting Secret :
  • Vào link : https://github.com/{GIT_USERNAME}/{PROJECTNAME}/settings/secrets/actions Thêm 2 Secret như bên dưới
  • Thay AWS_ROLE_ARN bằng ARN của role được tạo trong step Bước 4: Thiết lập OIDC trong AWS .
  • Thay AWS_REGION bằng us-east-1.

7. Test workflow

  1. Sửa api bằng cách sử nội dung message:
  2. Sau đó commit và push
  3. Confirm Workflow được trigger Action tab . Và đợi đến khi build thành công :
  4. Refresh browser và xác nhận change đã được phản ánh

8. Clean Up

Để tránh phát sinh chi phí, hãy xóa tất cả tài nguyên sau khi hoàn tất:

Bước 1: Xóa CloudFormation stack (xóa Lambda, API Gateway, IAM Role của Lambda)

sam delete --stack-name SOA-Stack-Serverless-Application

Hoặc vào AWS Console > CloudFormation > Chọn stack SOA-Stack-Serverless-Application > Delete.

Bước 2: Xóa S3 bucket (bucket do SAM CLI tạo để lưu artifact)

  • Vào S3 Console > Tìm bucket có tên bắt đầu bằng aws-sam-cli-managed-default-*
  • Empty bucket trước (bắt buộc) > rồi Delete bucket

Bước 3: Xóa IAM Role cho GitHub Actions

  • IAM Console > Roles > Tìm SOA-GitHubActions-SAMDeploy > Delete

Bước 4: Xóa OIDC Identity Provider

  • IAM Console > Identity providers > Chọn token.actions.githubusercontent.com > Delete

Bước 5: Xóa CloudWatch Log Groups (dễ bị bỏ quên!)

  • CloudWatch Console > Log groups > Tìm /aws/lambda/SOA-Stack-* > Delete

Tip: Nếu không chắc đã xóa hết, vào CloudFormation Console kiểm tra. Nếu stack đã bị xóa thành công, Lambda + API Gateway + IAM Role của Lambda đã được dọn sạch. Chỉ cần xóa thủ công S3 bucket, OIDC provider, GitHub Actions role, và CloudWatch Log Groups.

Nơi đặt resouce:

Troubleshooting — Các lỗi thường gặp

LỗiNguyên nhânCách khắc phục
Error: PythonPipBuilder:ResolveDependenciesPython version trên máy không khớp với runtime trong template.yamlKiểm tra python --version và đảm bảo khớp với Runtime trong template.yaml (ví dụ: python3.13)
Error: Failed to create changesetIAM permissions không đủ hoặc stack name đã tồn tạiKiểm tra IAM role có đủ quyền CloudFormation. Nếu stack đã tồn tại, dùng tên khác hoặc xóa stack cũ
GitHub Actions: Not authorized to perform: sts:AssumeRoleWithWebIdentityTrust policy sai hoặc repo name không khớpKiểm tra sub condition trong trust policy — repo name phải chính xác (phân biệt hoa/thường)
GitHub Actions: Error: No changes to deployCode không thay đổi so với lần deploy trướcĐây không phải lỗi — --no-fail-on-empty-changeset sẽ skip và báo success
S3 bucket does not existChưa chạy sam deploy --guided lần đầuChạy sam deploy --guided trước để SAM tạo S3 bucket. Các lần sau có thể dùng sam deploy

Tài liệu tham khảo

Kết luận

Bằng cách sử dụng AWS SAM và GitHub Actions với xác thực OIDC, bạn có thể triển khai và tự động hóa các ứng dụng serverless một cách an toàn và hiệu quả. Phương pháp này không chỉ giúp tiết kiệm thời gian mà còn tăng cường bảo mật bằng cách loại bỏ nhu cầu lưu trữ thông tin xác thực lâu dài. Hãy thử áp dụng và khám phá thêm các tính năng của SAM và GitHub Actions để xây dựng các ứng dụng serverless mạnh mẽ hơn!