Chúng ta sẽ tạo một hàm Lambda để đọc tất cả dữ liệu trong bảng DynamoDB.
Bạn phải cài đặt Python trên máy tính với cùng phiên bản với Lambda runtime được chỉ định trong SAM template (trong workshop này, chúng ta sử dụng Python 3.13).
Tại sao cần phải cài?
AWS SAM CLI sử dụng Python cục bộ trên máy của bạn để build deployment package cho Lambda function. Trong quá trình sam build, SAM sẽ cài đặt các dependency trong requirements.txt bằng Python runtime trên máy. Nếu phiên bản Python trên máy không khớp với phiên bản runtime được chỉ định trong template.yaml, quá trình build có thể thất bại hoặc tạo ra các package không tương thích, gây lỗi khi Lambda function chạy trên AWS.
Cách cài đặt Python 3.13 trên Windows:
Truy cập trang tải Python chính thức: https://www.python.org/downloads/
Tải xuống Python 3.13.x (phiên bản 3.13 mới nhất).
Chạy trình cài đặt:
✅ Đánh dấu “Add python.exe to PATH” ở cuối trình cài đặt.
Nhấp “Install Now” hoặc “Customize installation” nếu cần.
Sau khi cài đặt, kiểm tra phiên bản bằng cách mở terminal và chạy:
python --version
Bạn sẽ thấy output như: Python 3.13.x
Đối với macOS/Linux, bạn có thể sử dụng pyenv để cài đặt và quản lý nhiều phiên bản Python:
# Cài đặt pyenv (macOS với Homebrew)
brew install pyenv
# Cài đặt Python 3.13
pyenv install 3.13
# Đặt làm phiên bản cục bộ
pyenv local 3.13
Kiểm tra phiên bản Python trước khi tiếp tục:
python --version

Mở tệp template.yaml trong thư mục fcaj-book-shop.
Thêm tài nguyên sau vào phần Resources:
BooksList:
Type: AWS::Serverless::Function
Properties:
CodeUri: fcaj-book-shop/books_list
Handler: books_list.lambda_handler
Runtime: python3.13
FunctionName: books_list
Environment:
Variables:
TABLE_NAME: !Ref BooksTable
Architectures:
- x86_64
Policies:
- Statement:
- Sid: ReadDynamoDB
Effect: Allow
Action:
- dynamodb:Scan
- dynamodb:Query
Resource:
- !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${booksTableName}
- !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${booksTableName}/index/*

Tài nguyên này định nghĩa một Lambda function tên books_list với:
TABLE_NAME tham chiếu đến bảng DynamoDB BooksTableTạo cấu trúc thư mục như sau:
fcaj-book-shop
├── fcaj-book-shop
│ └── books_list
│ └── books_list.py
└── template.yaml
import json
import os
import boto3
from decimal import *
from boto3.dynamodb.types import TypeDeserializer
client = boto3.client('dynamodb')
serializer = TypeDeserializer()
table_name = os.environ['TABLE_NAME']
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return str(obj)
return json.JSONEncoder.default(self, obj)
def deserialize(data):
if isinstance(data, list):
return [deserialize(v) for v in data]
if isinstance(data, dict):
try:
return serializer.deserialize(data)
except TypeError:
return {k: deserialize(v) for k, v in data.items()}
else:
return data
def lambda_handler(event, context):
data_books = client.scan(
TableName=table_name,
IndexName='name-index'
)
format_data_books = deserialize(data_books["Items"])
for book in format_data_books:
data_comment = client.query(
TableName=table_name,
KeyConditionExpression="id = :id AND rv_id > :rv_id",
ExpressionAttributeValues={
":id": {"S": book['id']},
":rv_id": {"N": "0"}
}
)
format_data_comment = deserialize(data_comment['Items'])
print(data_comment['Items'])
book["comments"] = format_data_comment
print (format_data_books)
return {
"statusCode": 200,
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,PUT,POST,DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method,X-Access-Token,XKey,Authorization"
},
"body": json.dumps(format_data_books, cls=DecimalEncoder)
}

Chạy các lệnh sau để build và validate SAM template:
sam validate
sam build

Triển khai stack đã cập nhật:
sam deploy
Changeset sẽ hiển thị hai tài nguyên mới được thêm:
BooksListRole (AWS::IAM::Role)BooksList (AWS::Lambda::Function)Nhập y để xác nhận triển khai.

Chờ quá trình triển khai hoàn tất. Bạn sẽ thấy thông báo Successfully created/updated stack.

Mở CloudFormation console, nhấp vào stack fcaj-book-shop và chuyển sang tab Resources. Bạn sẽ thấy 5 tài nguyên bao gồm BooksList và BooksListRole.

Mở Lambda console. Nhấp vào hàm books_list.

Tại trang function books_list, bạn có thể xem:
books_list.py đã được deploy.

Nhấp vào tab Configuration, sau đó chọn Environment variables từ menu bên trái. Xác nhận TABLE_NAME được đặt là Books.

Chọn Permissions từ menu bên trái. Nhấp vào tên execution role (ví dụ: fcaj-book-shop-BooksListRole-...).

Tại trang IAM Role, kiểm tra phần Permissions policies. Bạn sẽ thấy:

Nhấp vào BooksListRolePolicy0 để mở rộng. Xem chi tiết policy JSON cấp quyền dynamodb:Scan và dynamodb:Query trên bảng Books.
