Ứng dụng Kubernetes của bạn đang 'ì ạch' vào giờ cao điểm? Đừng chỉ biết thêm node! Khám phá 3 giải pháp hiệu quả, tiết kiệm chi phí: Service Mesh, tối ưu CoreDNS và Caching API, giúp ứng dụng chạy mượt mà, phản hồi nhanh chóng.
Chào bạn! Bạn có bao giờ cảm thấy 'ngán ngẩm' với việc phải quản lý những con server lằng nhằng, cấu hình đủ thứ rồi lo lắng chuyện nâng cấp, mở rộng không? Nếu câu trả lời là 'CÓ', thì hôm nay chúng ta sẽ cùng khám phá một 'phép màu' trong thế giới công nghệ: **Serverless Computing**! Đây là một khái niệm đã thay đổi hoàn toàn cách chúng ta xây dựng các ứng dụng backend. Thay vì phải làm đủ thứ "việc vặt" đó, giờ đây bạn chỉ cần tập trung vào việc viết ra những dòng code quan trọng nhất – còn lại, 'chú' nhà cung cấp đám mây sẽ lo tất tần tật!Trong số các nền tảng serverless, bộ đôi **AWS Lambda** và **API Gateway** nổi lên như một 'cặp bài trùng' đáng tin cậy và được sử dụng rộng rãi nhất. Với sự kết hợp này, bạn có thể tạo ra những API không chỉ 'ngon, bổ, rẻ' mà còn sẵn sàng cho môi trường 'sản phẩm thật' (production-ready) và tự động mở rộng mà không cần bạn phải động tay động chân chút nào. Tuyệt vời đúng không?Loạt bài viết này sẽ 'giải mã' toàn bộ quá trình xây dựng một API serverless, từng bước một, cực kỳ dễ hiểu. Và trong **Phần 1** này, chúng ta sẽ 'nhập môn' với những kiến thức cơ bản về AWS Lambda: nó là gì, tại sao nó lại quan trọng đến thế, và làm cách nào để 'triệu hồi' hàm Lambda đầu tiên của bạn!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/serverless_concept.png' alt='Khái niệm Serverless: Phát triển mà không cần quản lý server'><h3>Tại sao chúng ta lại 'phải lòng' Serverless?</h3>Tưởng tượng mà xem, ngày xưa khi xây dựng backend, bạn sẽ phải làm đủ thứ: 'sắm sửa' server, cài đặt phần mềm, cập nhật hệ điều hành, rồi còn phải canh cánh lo lắng làm sao để hệ thống luôn 'sẵn sàng chiến đấu' (highly available). Nghe thôi đã thấy mệt rồi đúng không? Mặc dù cách làm truyền thống này vẫn 'chạy tốt', nhưng nó lại 'đeo' cho chúng ta vô số gánh nặng, làm chậm quá trình phát triển và đội chi phí lên không ít.Đấy là lúc Serverless xuất hiện như một 'vị cứu tinh'! Nó 'cuốn bay' mọi sự phức tạp đó. Bạn sẽ không cần phải bận tâm về việc có bao nhiêu server, liệu chúng có đủ mạnh không, hay phải vá lỗi hạ tầng nữa. Việc của bạn đơn giản là: **viết code, tải lên, và để AWS lo phần còn lại!**Đặc biệt, Serverless là lựa chọn 'siêu hạng' cho các trường hợp sau:<ul><li>Các startup và 'dev cô đơn' muốn triển khai sản phẩm thật nhanh chóng.</li><li>Các ứng dụng có lưu lượng truy cập 'lúc lên lúc xuống' thất thường.</li><li>Những API không cần phải chạy 'phè phỡn' 24/7 trên các server riêng biệt.</li></ul><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/serverless_vs_traditional.png' alt='So sánh phát triển truyền thống và Serverless'><h3>AWS Lambda: 'Trái tim' của Serverless trên AWS</h3>À, vậy thì **AWS Lambda** chính là 'ngôi sao' của buổi tiệc serverless này! Nó là dịch vụ tính toán 'thần thánh' của AWS, giúp bạn biến những ý tưởng thành hiện thực mà không cần chạm vào server. Tưởng tượng Lambda như một đội quân robot siêu nhỏ, siêu hiệu quả, có thể:<ul><li>**Tiếp nhận 'mệnh lệnh' dưới dạng code:** Bạn chỉ cần 'giao' cho nó những đoạn code nhỏ (chúng ta gọi là 'hàm' – functions) để thực hiện một nhiệm vụ cụ thể.</li><li>**Chỉ hoạt động khi cần thiết:** Những 'robot' này sẽ 'ngủ đông' cho đến khi có ai đó 'gọi' chúng (trigger bởi một sự kiện). Không chạy = không tốn tiền! Quá tuyệt đúng không?</li><li>**Tự động 'nhân bản' khi đông khách:** Dù có hàng trăm, hàng nghìn yêu cầu đổ về cùng lúc, Lambda sẽ tự động 'tạo thêm' robot để xử lý hết, bạn không phải lo lắng gì cả!</li><li>**Trả tiền theo... thời gian chạy:** Bạn chỉ phải trả phí cho chính xác khoảng thời gian mà code của bạn chạy thôi. Không lãng phí một giây nào!</li></ul>Các hàm Lambda được thiết kế để 'phản ứng' với các sự kiện. Chúng có thể được kích hoạt bởi vô vàn thứ, ví dụ như:<ul><li>Có yêu cầu API đến (thông qua API Gateway – anh bạn thân của Lambda!).</li><li>Có file mới được tải lên kho lưu trữ S3.</li><li>Có sự kiện xảy ra trong cơ sở dữ liệu (qua DynamoDB streams).</li><li>Các tác vụ được lên lịch sẵn (qua CloudWatch – như một cái đồng hồ báo thức vậy).</li></ul>Với API của chúng ta, 'kẻ' chủ yếu kích hoạt Lambda chính là **API Gateway**. Nhưng trước khi chúng ta kết nối 'cặp đôi hoàn hảo' này, hãy cùng tạo ra hàm Lambda đầu tiên của mình đã nhé!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/lambda_event_driven.png' alt='Cách Lambda phản ứng với các sự kiện khác nhau'><h3>Bước 1: 'Triệu hồi' hàm Lambda đầu tiên</h3>Đừng chần chừ nữa, chúng ta cùng 'xắn tay áo' vào làm ngay thôi! Hãy mở **AWS Management Console** và tìm đến dịch vụ **Lambda** nhé.<ol><li>Nhấp vào nút **Create function** (Tạo hàm).</li><li>Chọn **Author from scratch** (Tự tạo từ đầu) – vì chúng ta là những người 'tự lực cánh sinh' mà!</li><li>Đặt tên cho hàm của bạn (ví dụ: `myFirstLambda`). Nghe có vẻ 'hoành tráng' đấy chứ!</li><li>Chọn một **runtime** (môi trường chạy code). **Python** hoặc **Node.js** là hai lựa chọn phổ biến và dễ dùng nhất.</li><li>Tạm thời cứ để mặc định phần quyền hạn (permissions) nhé.</li></ol>Sau khi hàm được tạo xong, AWS sẽ 'dâng tận tay' cho bạn một trình soạn thảo code có sẵn. Giờ thì, hãy 'thay máu' đoạn code mặc định bằng một cái gì đó thật đơn giản nhưng hiệu quả, như thế này:<pre><code class="language-python">def lambda_handler(event, context): return { "statusCode": 200, "body": "Hello from Lambda!" }</code></pre>Đoạn code 'bé tí tẹo' này có nghĩa là: mỗi khi hàm Lambda của bạn được kích hoạt, nó sẽ 'trả về' một phản hồi với trạng thái 'OK' (200) và một thông điệp siêu thân thiện: **"Hello from Lambda!"**.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/create_lambda_function.png' alt='Các bước tạo hàm Lambda trên AWS Console'><h3>Bước 2: 'Kiểm tra hàng' – Xem thử hàm có chạy không?</h3>Trước khi 'kết nối' em Lambda của chúng ta với thế giới bên ngoài, hãy cùng 'thử sức' nó ngay trong giao diện AWS Console nhé. Dễ lắm!<ol><li>Nhấn nút **Test** (Kiểm tra) trên bảng điều khiển Lambda.</li><li>Cung cấp một **sample event** (sự kiện mẫu). Đừng lo, AWS có sẵn các mẫu để bạn dùng đó. Cứ chọn một cái bất kỳ, ví dụ `hello-world` chẳng hạn.</li><li>Chạy thử (Run test) và 'chiêm ngưỡng' kết quả! Bạn sẽ thấy một phản hồi với trạng thái **200 OK** và thông điệp **"Hello from Lambda!"**. Cảm giác thật 'phê' đúng không nào?</li></ol>Tuyệt vời! Đến đây, bạn đã thành công 'triển khai' và 'chạy thử' hàm Lambda của mình rồi đó. Tuy nhiên, nó vẫn đang 'một mình một cõi', chưa hề được 'phơi bày' ra thế giới bên ngoài. Để biến nó thành một API công khai mà ai cũng có thể truy cập, chúng ta cần 'sáp nhập' nó với **API Gateway**!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/test_lambda_function.png' alt='Màn hình kiểm tra hàm Lambda thành công'>Và đây chính là lúc 'hành trình thực sự' của chúng ta bắt đầu! Trong phần tiếp theo, chúng ta sẽ cùng 'thiết lập' API Gateway, tạo ra các 'con đường' (routes) và 'kết nối' chúng với Lambda – để bất kỳ ai cũng có thể 'gọi' hàm của bạn thông qua một endpoint REST công khai.Bạn muốn tiếp tục khám phá và xây dựng API serverless 'trong mơ' của mình không? Hãy đón đọc **Phần 2** của chuỗi bài viết này để không bỏ lỡ những bước tiếp theo siêu thú vị nhé!
Chào mừng bạn đến với phần 3 cực kỳ hấp dẫn của series bài viết về Amazon Bedrock AgentCore Gateway! Trong những phần trước, chúng ta đã cùng nhau khám phá AgentCore Gateway – một "cánh cổng thần kỳ" giúp biến các API và hàm Lambda hiện có thành những công cụ sẵn sàng cho Agent AI, mở ra khả năng truy cập thống nhất qua nhiều giao thức, bao gồm cả Model Context Protocol (MCP), và khả năng tự động khám phá công cụ trong thời gian chạy. Ở phần 2, chúng ta đã biến một REST API Gateway thành công cụ tương thích MCP. Hôm nay, chúng ta sẽ "độ" tiếp các hàm Lambda của mình để chúng cũng trở thành những "trợ thủ đắc lực" cho các AI Agent thông qua AgentCore Target! Chúng ta sẽ tiếp tục sử dụng hai hàm Lambda quen thuộc: `GetOrderByID` và `GetOrdersByCreatedDates`. Hãy cùng bắt đầu hành trình biến hóa này nhé!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/gVj3Y7o.png' alt='Sơ đồ tổng quan AgentCore Gateway và Lambda'>Bạn muốn "hô biến" các hàm AWS Lambda hiện có của mình thành công cụ MCP qua Bedrock AgentCore Gateway? Nghe có vẻ phức tạp nhưng thực ra chỉ là vài bước cấu hình thôi! Để minh họa, chúng ta sẽ tái sử dụng ứng dụng mẫu và API Gateway đã được mô tả chi tiết trong bài viết "Serverless applications with Java and Aurora DSQL - Part 1". Bạn có thể tìm thấy toàn bộ mã nguồn tại đây.Chúng ta sẽ dùng một Jupyter Notebook Python có sẵn từ kho lưu trữ GitHub chính thức của AWS (amazon-bedrock-agentcore-samples) và tùy chỉnh nó để phù hợp với yêu cầu của mình. Tôi cũng đã chia sẻ phiên bản cuối cùng của playbook này trên GitHub cá nhân của mình.Đây là kiến trúc tổng quan về cách chúng ta sẽ biến đổi các hàm AWS Lambda hiện có thành công cụ MCP sử dụng Bedrock AgentCore Gateway:<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/tY7g8Y4.png' alt='Kiến trúc biến Lambda thành công cụ MCP'>Quy trình hoạt động của Gateway để kết nối các agent của bạn với các công cụ bên ngoài bao gồm các bước sau:<ul><li><b>Tạo công cụ cho Gateway của bạn:</b> Định nghĩa các công cụ bằng schemas, bao gồm ARN của hàm Lambda, các tham số công cụ và kiểu dữ liệu của chúng.</li><li><b>Tạo một Gateway endpoint:</b> Xây dựng cổng gateway sẽ là điểm truy cập MCP với xác thực đầu vào.</li><li><b>Thêm target vào Gateway của bạn:</b> Cấu hình các target là hàm Lambda, xác định cách gateway định tuyến yêu cầu đến các công cụ cụ thể. Tất cả các hàm Lambda này sẽ trở thành một công cụ tương thích MCP và sẽ được cung cấp thông qua URL của Gateway endpoint của bạn. Cấu hình ủy quyền IAM đầu ra cho mỗi target Lambda.</li><li><b>Cập nhật mã agent của bạn:</b> Kết nối agent của bạn với Gateway endpoint để truy cập tất cả các công cụ đã cấu hình thông qua giao diện MCP thống nhất.</li></ul>Để thực hiện hướng dẫn này, bạn cần chuẩn bị:<ul><li>Jupyter Notebook (với kernel Python)</li><li>`uv` (một công cụ quản lý package Python siêu nhanh)</li><li>Thông tin đăng nhập AWS (đã cấu hình trong `.aws\credentials` là đủ)</li><li>Amazon Cognito</li></ul>Bây giờ, chúng ta sẽ cùng nhau đi từng bước qua các phần quan trọng của Python Jupyter Notebook. Để chạy được nó, bạn cũng cần tải file `agent_core_utils.py` và đặt nó cùng thư mục với notebook. Tôi đã copy file này từ kho mẫu của AWS để tiện tùy chỉnh sau này.<h3>1. Cài đặt các thư viện cần thiết</h3>Bước đầu tiên luôn là kiểm tra và cài đặt các 'nguyên liệu' cơ bản! Chúng ta sẽ kiểm tra xem `uv` đã có chưa, sau đó dùng nó để cài `botocore` và `boto3`. Đơn giản phải không nào?<h3>2. Cấu hình Môi trường</h3>Tiếp theo, chúng ta đặt biến môi trường `AWS_DEFAULT_REGION` là 'us-east-1' (tất nhiên bạn có thể chọn một region khác mà AgentCore được hỗ trợ). Nếu bạn đã cấu hình `AWS_ACCESS_KEY_ID` và `AWS_SECRET_ACCESS_KEY` trong `.aws\credentials` thì khỏi cần đặt lại nhé, các client của AWS sẽ tự động nhận diện từ đó!```pythonimport osimport agent_core_utilsos.environ['AWS_DEFAULT_REGION'] = 'us-east-1'```<h3>3. Tạo hoặc Tái sử dụng IAM Role cho AgentCore Gateway</h3>Đây là bước quan trọng để cấp quyền cho Gateway. Chúng ta sẽ dùng `agent_core_utils` để tạo một IAM role cho AgentCore Gateway, hoặc tái sử dụng role đã tạo ở phần 2. Role này sẽ cho phép Gateway thực hiện các thao tác cần thiết.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47m71a784rxwk1frqgyg.png' alt='IAM role và policy cho AgentCore Gateway'>```pythonimport agent_core_utilsagentcore_gateway_iam_role = agent_core_utils.create_agentcore_gateway_role("sample-lambdagateway")print("Agentcore gateway role ARN: ", agentcore_gateway_iam_role['Role']['Arn'])```Sau khi chạy bước này, IAM role và policy của bạn sẽ trông như thế này trong AWS.<h3>4. Cấu hình Amazon Cognito User Pool</h3>Để đảm bảo an toàn, chúng ta cần một cơ chế xác thực. Bước này sẽ tạo một Cognito User Pool (nếu chưa có, hoặc tái sử dụng nếu bạn đã tạo ở phần 2). Chúng ta cũng sẽ tạo hoặc lấy lại client ID và client secret cho ứng dụng machine-to-machine (M2M) của Cognito. Các thông tin này cực kỳ quan trọng để tạo ra token xác thực khi Agent muốn "nói chuyện" với Gateway.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7is538yqn95ue5c7lo4u.png' alt='Cognito User Pool đã cấu hình'>```pythonimport osimport boto3import requestsimport timefrom botocore.exceptions import ClientErrorREGION = os.environ['AWS_DEFAULT_REGION']USER_POOL_NAME = "sample-agentcore-gateway-pool"RESOURCE_SERVER_ID = "sample-agentcore-gateway-id"RESOURCE_SERVER_NAME = "sample-agentcore-gateway-name"CLIENT_NAME = "sample-agentcore-gateway-client"SCOPES = [ {"ScopeName": "gateway:read", "ScopeDescription": "Read access"}, {"ScopeName": "gateway:write", "ScopeDescription": "Write access"}]scopeString = f"{RESOURCE_SERVER_ID}/gateway:read {RESOURCE_SERVER_ID}/gateway:write"cognito = boto3.client("cognito-idp", region_name=REGION)print("Creating or retrieving Cognito resources...")user_pool_id = agent_core_utils.get_or_create_user_pool(cognito, USER_POOL_NAME)print(f"User Pool ID: {user_pool_id}")agent_core_utils.get_or_create_resource_server(cognito, user_pool_id, RESOURCE_SERVER_ID, RESOURCE_SERVER_NAME, SCOPES)print("Resource server ensured.")client_id, client_secret = agent_core_utils.get_or_create_m2m_client(cognito, user_pool_id, CLIENT_NAME, RESOURCE_SERVER_ID)print(f"Client ID: {client_id}")# Get discovery URLcognito_discovery_url = f'https://cognito-idp.{REGION}.amazonaws.com/{user_pool_id}/.well-known/openid-configuration'print(cognito_discovery_url)```Sau khi thực hiện, Cognito Pool của chúng ta sẽ hiển thị như hình trên trong AWS (các thông tin nhạy cảm như ARN và URL khóa ký token đã được ẩn đi).<h3>5. Tạo AgentCore Gateway</h3>Đây là trái tim của hệ thống! Chúng ta sẽ tạo một Gateway với tên `LambdaOrderGateway`, sử dụng Cognito Authorizer (không dùng CMK) dựa trên user pool đã tạo ở bước trước. Giao thức sẽ là MCP. Gateway này sẽ là điểm kết nối cho các Lambda của chúng ta.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frod0lhly9nuzc5ki20n0.png' alt='AgentCore Gateway đã tạo'>```pythonimport boto3gateway_client = boto3.client('bedrock-agentcore-control', region_name = os.environ['AWS_DEFAULT_REGION'])auth_config = { "customJWTAuthorizer": { "allowedClients": [client_id], # Client MUST match with the ClientId configured in Cognito. Example: 7rfbikfsm51j2fpaggacgng84g "discoveryUrl": cognito_discovery_url }}create_response = gateway_client.create_gateway(name='LambdaOrderGateway', roleArn = agentcore_gateway_iam_role['Role']['Arn'], # The IAM Role must have permissions to create/list/get/delete Gateway protocolType='MCP', authorizerType='CUSTOM_JWT', authorizerConfiguration=auth_config, description='AgentCore Gateway with AWS Lambda target type')print(create_response)gatewayID = create_response["gatewayId"]gatewayURL = create_response["gatewayUrl"]print(gatewayID)```Sau khi thực hiện bước này, AgentCore Gateway đã tạo sẽ xuất hiện như hình trên trong AWS.<h3>6. Tạo AgentCore Gateway Targets (cho từng hàm Lambda)</h3>Bây giờ là lúc kết nối các "trợ thủ" Lambda của chúng ta! Chúng ta sẽ tạo hai AgentCore Gateway Targets, mỗi target cho một hàm Lambda hiện có. Công việc này gồm hai phần chính: cấu hình target Lambda và cấu hình xác thực.<h4>6.1. Cấu hình Target Lambda cho `GetOrderByIdWithJava21Lambda`</h4>Chúng ta cần cung cấp ARN của hàm Lambda (nhớ thay bằng ARN của bạn nhé!), sau đó định nghĩa tên và mô tả của công cụ MCP. Quan trọng nhất là `inputSchema` – nơi chúng ta chỉ định các tham số đầu vào (ở đây là `id` cho order id) và đánh dấu chúng là `required` (bắt buộc).```pythonorder_by_id_lambda_target_config = { "mcp": { "lambda": { "lambdaArn": '${YourGetOrderByIdLambdaFunctionARN}', # Thay thế bằng ARN Lambda của bạn "toolSchema": { "inlinePayload": [ { "name": "get_order_by_id_tool", "description": "tool to get the order by id", "inputSchema": { "type": "object", "properties": { "id": { "type": "string" } }, "required": ["id"] } } ] } } }}```<h4>6.2. Cấu hình Target Lambda cho `GetOrdersByCreatedDatesLambda`</h4>Tương tự, với hàm `GetOrdersByCreatedDatesLambda`, chúng ta có hai tham số bắt buộc là `startDate` và `endDate`.<h4>6.3. Cấu hình Xác thực</h4>Phần này khá đơn giản, chúng ta chỉ cần đặt kiểu nhà cung cấp thông tin xác thực là `GATEWAY_IAM_ROLE`.```jsoncredential_config = [ { "credentialProviderType" : "GATEWAY_IAM_ROLE" }]```<h4>6.4. Tạo các AgentCore Targets</h4>Cuối cùng, chúng ta tạo hai AgentCore Targets bằng cách truyền cấu hình target Lambda và cấu hình xác thực đã chuẩn bị.Ví dụ cho target `GetOrderByIdLambda`:```pythonorder_by_id_targetname='GetOrderByIdLambda'response = gateway_client.create_gateway_target( gatewayIdentifier=gatewayID, name=order_by_id_targetname, description='Order by id Lambda Target', targetConfiguration=order_by_id_lambda_target_config, credentialProviderConfigurations=credential_config)```Đây là toàn bộ đoạn mã để thực thi hai target:```pythonorder_by_id_lambda_target_config = { "mcp": { "lambda": { "lambdaArn": '${YourGetOrderByIdLambdaFunctionARN}', # Thay thế bằng ARN Lambda của bạn "toolSchema": { "inlinePayload": [ { "name": "get_order_by_id_tool", "description": "tool to get the order by id", "inputSchema": { "type": "object", "properties": { "id": { "type": "string" } }, "required": ["id"] } } ] } } }}order_by_created_dates_lambda_target_config = { "mcp": { "lambda": { "lambdaArn": '${YourGetOrdersByCreatedDatesLambdaFunctionARN}', # Thay thế bằng ARN Lambda của bạn "toolSchema": { "inlinePayload": [ { "name": "get_orders_by_created_dates_tool", "description": "tool to get the order by created dates", "inputSchema": { "type": "object", "properties": { "startDate": { "type": "string" }, "endDate": { "type": "string" } }, "required": ["startDate","endDate"] } } ] } } }}credential_config = [ { "credentialProviderType" : "GATEWAY_IAM_ROLE" }]order_by_id_targetname='GetOrderByIdLambda'response = gateway_client.create_gateway_target( gatewayIdentifier=gatewayID, name=order_by_id_targetname, description='Order by id Lambda Target', targetConfiguration=order_by_id_lambda_target_config, credentialProviderConfigurations=credential_config)order_by_id_targetname='GetOrderByCreatedDatesLambda'response = gateway_client.create_gateway_target( gatewayIdentifier=gatewayID, name=order_by_id_targetname, description='Orders by created dates Lambda Target', targetConfiguration=order_by_created_dates_lambda_target_config, credentialProviderConfigurations=credential_config)```Sau khi chạy bước này, các AgentCore Gateway Targets của bạn sẽ được tạo ra như thế này:<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqv5n5huvkxi0s4pjwjl.png' alt='AgentCore Gateway Targets'>Và chi tiết hơn cho từng target:<ul><li>**`GetOrderByIdLambda`:**<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzzkc4ar46u8mna22m65.png' alt='Cấu hình GetOrderByIdLambda Target'></li><li>**`GetOrderByCreatedDatesLambda`:**<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgp0nwfg5qgaaw10cgdt9.png' alt='Cấu hình GetOrderByCreatedDatesLambda Target'></li></ul><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvw6ng37bi60q4vz9j27.png' alt='Chi tiết Target 1'><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2rjjkisqa55jr05wg90.png' alt='Chi tiết Target 2'>Vậy là chúng ta đã hoàn tất việc tạo và cấu hình AgentCore Gateway! Bây giờ, hãy cùng "trò chuyện" với agent xem sao nhé.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy5x6q57pyxz4yaptd6rs.png' alt='Giao diện View invocation code'>Bạn có thể sao chép mã cho "Python with Requests", "MCP Python SDK", hoặc "Strands MCP Client" từ phần "View invocation code" của AgentCore Gateway.Trong trường hợp chúng ta sử dụng notebook này, nơi chúng ta dùng Strands MCP Client, bạn cần lặp lại các bước 2 (đặt AWS Region mặc định và import `agent_core_utils`) và bước 4 (lấy lại Cognito Pool hiện có để đặt các biến `client_id`, `client_secret` và `cognito_discovery_url`).Chúng ta sẽ chạy agent cục bộ và khám phá AgentCore Runtime trong một series bài viết khác. Amazon Bedrock AgentCore Runtime cung cấp một môi trường lưu trữ an toàn, không máy chủ và được xây dựng chuyên biệt để triển khai và chạy các agent hoặc công cụ AI. Đây là một ví dụ về cách triển khai Strands Agents lên Amazon Bedrock AgentCore Runtime.<h4>Lấy Token Xác thực</h4>Đầu tiên, chúng ta cần lấy token xác thực. Đây là chìa khóa để agent có thể "trò chuyện" với Gateway.```pythonimport agent_core_utilsprint("Requesting the access token from Amazon Cognito authorizer...May fail for some time till the domain name propagation completes")token_response = agent_core_utils.get_token(user_pool_id, client_id, client_secret,scopeString,REGION)token = token_response["access_token"]print("Token response:", token)```<h4>Tạo MCP Client và Agent</h4>Tiếp theo, chúng ta tạo một MCP client và một agent. Agent này sẽ sử dụng mô hình Amazon Bedrock (`us.amazon.nova-pro-v1:0` với `temperature=0.7`). Bạn có thể thử nghiệm với các cài đặt này. Strands Agent hỗ trợ tất cả các mô hình, kể cả những mô hình chạy cục bộ như Ollama. Nhưng nhớ đảm bảo rằng nếu dùng Amazon Bedrock, mô hình đó phải được kích hoạt trong Model Access nhé.Sau đó, chúng ta yêu cầu client liệt kê tất cả các công cụ (qua lệnh `client.list_tools_sync`). Đừng quên đặt `gateway_url` của AgentCore Gateway đã tạo trước đó.```pythonfrom strands import Agentimport loggingfrom strands.models import BedrockModelfrom strands.tools.mcp.mcp_client import MCPClientfrom mcp.client.streamable_http import streamablehttp_clientimport osimport requestsimport jsondef fetch_access_token(): return token;def create_streamable_http_transport(mcp_url: str, access_token: str): return streamablehttp_client(mcp_url, headers={"Authorization": f"Bearer {token}"})def get_full_tools_list(client): """ List tools w/ support for pagination """ more_tools = True tools = [] pagination_token = None while more_tools: tmp_tools = client.list_tools_sync(pagination_token=pagination_token) tools.extend(tmp_tools) if tmp_tools.pagination_token is None: more_tools = False else: more_tools = True pagination_token = tmp_tools.pagination_token return toolsdef run_agent(mcp_url: str, access_token: str): model = BedrockModel( model_id="us.amazon.nova-pro-v1:0", temperature=0.7) mcp_client = MCPClient(lambda: create_streamable_http_transport(mcp_url, access_token)) with mcp_client: tools = get_full_tools_list(mcp_client) print(f"Found the following tools: {[tool.tool_name for tool in tools]}")gateway_url = "${YOUR_Gateway_resource_URL}"run_agent(gateway_url, fetch_access_token())```Khi chạy đoạn mã này, kết quả sẽ hiển thị danh sách các công cụ mà agent đã tìm thấy:```textFound the following tools: ['GetOrderByCreatedDatesLambda_get_orders_by_created_dates_tool', 'GetOrderByIdLambda_get_order_by_id_tool']```Tuyệt vời! Agent đã nhận diện được hai hàm Lambda của chúng ta là các công cụ hợp lệ. Bây giờ, chúng ta sẽ làm tương tự như ở phần 2: "trò chuyện" với cùng hàm Lambda, nhưng lần này là trực tiếp qua AgentCore Gateway chứ không phải qua Open API.Tôi đã tạo sẵn một số đơn hàng và sản phẩm trong cơ sở dữ liệu. Giờ thì hãy tạo Strands Agent và hỏi về đơn hàng có ID là `12345` nhé!Dưới đây là đoạn mã bổ sung liên quan. Chúng ta truyền thông tin về mô hình Bedrock đã tạo và các công cụ MCP đã lấy được cho Strands Agent:```pythonwith mcp_client: tools = get_full_tools_list(mcp_client) print(f"Found the following tools: {[tool.tool_name for tool in tools]}") agent = Agent(model=model, tools=tools) agent("Give me the information about order with id 12345")```Khi chạy đoạn mã này, bạn sẽ thấy... không có gì cả! Agent bị "treo". Hãy cùng kiểm tra CloudWatch xem có chuyện gì nhé. Hàm Lambda (viết bằng Java) đã được thực thi (nghĩa là mapping hoạt động), nhưng một ngoại lệ đã được ném ra:<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbt022npm8mhj2fxnhx9.png' alt='Lỗi NullPointerException trong Lambda'>Lý do là `requestEvent.getPathParameters()` bị `null`, trong khi chúng ta mong đợi nó chứa tham số "id":```java@Overridepublic APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent requestEvent, Context context) { String id = requestEvent.getPathParameters().get("id");...```Mặc dù đối tượng `APIGatewayProxyRequestEvent requestEvent` được tạo, nó lại hoàn toàn rỗng (không có thuộc tính nào được đặt: không có tham số đường dẫn, không có chuỗi truy vấn, v.v.). Vậy chuyện gì đã xảy ra? Hàm Lambda hiện có của chúng ta được kích hoạt bởi sự kiện HTTP GET của API Gateway, nhưng AgentCore Gateway không thể biết trigger nào được cấu hình (nó có thể là tất cả các trigger có thể như SQSEvent) và không thể đặt các tham số một cách chính xác.Với mong muốn tái sử dụng hoàn toàn hàm Lambda mà không cần sửa đổi, tôi đã hy vọng có một cấu hình nào đó để truyền vào trong trường hợp này (loại sự kiện là gì và đặt các thuộc tính công cụ ở đâu: dưới dạng HTTP path, query parameters, hay trong HTTP body...). Vì AgentCore hiện đang ở bản preview, tôi sẽ đề xuất loại thay đổi này trước khi ra mắt chính thức. Nhưng hiện tại, thật tiếc là tôi chưa tìm thấy cách nào để tái sử dụng hàm Lambda với một trigger cụ thể làm tham số.Điều tôi tìm thấy là định dạng đầu vào của hàm Lambda, trong đó nói rằng các tham số đầu vào sẽ được truyền vào hàm Lambda dưới dạng cặp khóa-giá trị trong một map/dictionary. Tôi cho rằng vấn đề này có thể chỉ liên quan đến một số runtime Lambda được quản lý nhất định như Java, và không liên quan đến các runtime khác như Python, nơi hàm Lambda đã nhận đối tượng sự kiện kiểu map hoặc dictionary.Vì vậy, tôi đã viết 2 hàm Lambda mới: `GetOrderById2Handler` và `GetOrdersByCreatedDates2Handler` để sử dụng `Map` trong Java làm kiểu sự kiện đầu vào cho Lambda. Các điều chỉnh cần thực hiện cho các hàm Lambda ban đầu là khá nhỏ. Đây là một ví dụ về cách nó hoạt động:```java@Overridepublic APIGatewayProxyResponseEvent handleRequest(Map<String, String> params, Context context) { String id = params.get("id"); .....```Vì vậy, hãy nhớ thay đổi ARN của các hàm Lambda sang các hàm mới này khi bạn tạo AgentCore Gateway Lambda Targets ở bước 6 nhé!Bây giờ, hãy "trò chuyện" lại với agent:```pythonwith mcp_client: tools = get_full_tools_list(mcp_client) print(f"Found the following tools: {[tool.tool_name for tool in tools]}") agent = Agent(model=model, tools=tools) agent("Give me the information about order with id 12345")```Và đây là kết quả!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q00quick84qtkmhgl7e.png' alt='Agent phản hồi về đơn hàng theo ID'>Tuyệt vời! Công cụ `getOrderById` đã được xác định chính xác và chúng ta đã nhận được thông tin chính xác về đơn hàng từ đầu ra của hàm Lambda.Hãy tiếp tục hỏi agent những câu hỏi khác như chúng ta đã làm ở phần 2:```pythonagent('Can you list orders created between 1 of August 2025 5am and 5 of August 2025 3am. ''Please use the following date format, for example: 2025-08-02T19:50:55')```Ở đây, chúng ta muốn lấy danh sách đơn hàng được tạo trong một khoảng thời gian cụ thể và gợi ý cho agent về định dạng ngày tháng. Hãy cùng xem kết quả:<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcq89m2ebyt12njyw5ss.png' alt='Agent phản hồi về đơn hàng theo ngày tạo'>Lại một lần nữa, công cụ `getOrdersByCreatedDates` đã được nhận diện chính xác và các ngày tháng đã được định dạng đúng (tôi đã kiểm tra trong log). Chúng ta đã nhận được thông tin chính xác về các đơn hàng. Tôi đã giới hạn số lượng đơn hàng trả về là 10 trong câu lệnh SQL để tiết kiệm token đầu ra. Và tôi cũng đã đặt lại timestamp tạo cho đơn hàng thành một giá trị nhất định. Nhưng câu trả lời hoàn toàn chính xác!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpt8f9cbrz1ok9q55sirt.png' alt='Kết quả chi tiết đơn hàng theo ngày tạo'>Hãy hỏi agent thêm một câu hỏi nữa:```pythonagent('What is the total value of all these orders together?')```Câu trả lời hoàn toàn chính xác!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgwuquh4ewuflgbpvlc0.png' alt='Agent tính tổng giá trị đơn hàng'>Đúng vậy, agent đã tự động tính tổng giá trị của tất cả 10 đơn hàng (10*350) một cách chính xác.Thử hỏi về một đơn hàng không tồn tại xem agent xử lý thế nào nhé:```pythonagent("Give me the information about order with id 1234589090")```Chúng ta nhận được kết quả chính xác, vì hàm Lambda đã xử lý loại yêu cầu này mà không ném ra lỗi nào:<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5rxitmowm2gx7v7vnr3.png' alt='Agent phản hồi về đơn hàng không tồn tại'>Có một điều tôi nhận thấy, tương tự như phần I đã mô tả khi expose Open API làm target cho AgentCore Gateway, đó là trường hợp hàm Lambda gặp lỗi (ví dụ như Nullpointer exception). Trong trường hợp đó, Agent không trả về bất cứ điều gì và tiếp tục "suy nghĩ" trong nhiều phút, buộc tôi phải dừng nó. Chắc chắn vẫn còn rất nhiều điều để thử nghiệm và khám phá. Tôi sẽ dành phần này cho bạn đọc. Nhưng đây là một cái nhìn đầu tiên về chức năng của AgentCore Gateway với hàm Lambda là Target.Cuối cùng, hãy cùng xem xét một số chỉ số CloudWatch hữu ích được cung cấp cho Amazon Bedrock AgentCore Gateway:<h4>Đối với các hoạt động `ListMemory` và `InitializeMcp`:</h4><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23volrpjkdkakkosuvcn.png' alt='CloudWatch Metrics cho ListMemory và InitializeMcp'><h4>Đối với hoạt động `ListToolsMcp`:</h4><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuffj66ct5q6x6y22dcva.png' alt='CloudWatch Metrics cho ListToolsMcp'><h4>Đối với hoạt động `CallToolMcp`:</h4><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wnv1ybjxe2foxa69qej.png' alt='CloudWatch Metrics cho CallToolMcp'>Trong phần này của series bài viết, chúng ta đã cùng nhau tìm hiểu cách "biến hình" hàm Lambda thành một AgentCore Target. Chúng ta đã sử dụng lại các hàm Lambda quen thuộc (`GetOrderByID` và `GetOrdersByCreatedDates`) mà ở phần 2 đã expose qua Open API thông qua API Gateway. Và đặc biệt, chúng ta đã dùng Strands MCP Client để "giao tiếp" với AgentCore Gateway endpoint này. Hy vọng bạn đã có một cái nhìn rõ nét và thú vị về cách "mở khóa" tiềm năng của Lambda với AI Agent!
Khám phá SiliconPrimeX, hệ thống AI tự phục hồi giúp AWS Glue jobs tự động vá lỗi, phân tích nguyên nhân gốc rễ chỉ trong 10 giây thay vì hàng giờ. Tạm biệt nỗi lo thức khuya!
Explore the real impact of AI in enterprise operations, distinguishing between successful applications in supply chain, customer service, and HR, and areas where AI falls short like overhyped predictive analytics and generative AI. Understand critical risks, and learn why strategic AI adoption is essential for business success.
Chào bạn! Hôm nay chúng ta sẽ cùng khám phá thế giới đầy mê hoặc của Trí tuệ Nhân tạo Tạo sinh (Gen AI) và cách các dịch vụ của AWS biến những điều phức tạp thành đơn giản, hiệu quả đến không ngờ. Dù bạn là giám đốc, CTO, hay một lập trình viên, thì những kiến thức này chắc chắn sẽ siêu hữu ích đó!
Chào các bạn! Trong vài tuần vừa qua, mình đã có cơ hội "tăm tia" và trải nghiệm Kiro – một trợ lý lập trình GenAI thế hệ mới, được thiết kế riêng cho các kỹ sư, nhà phát triển và chuyên gia bảo mật. Sau khi dùng Amazon Q "xuyên lục địa" từ ngày nó ra mắt, mình cứ nghĩ tốc độ làm việc không thể nhanh hơn được nữa đâu. Ấy vậy mà Kiro đã làm mình phải "há hốc mồm" luôn đấy! Nó thực sự là một đẳng cấp hoàn toàn khác biệt!Dù là xây dựng các công cụ Red Team độc đáo hay "tốc biến" các script kiểm thử xâm nhập, Kiro đều xử lý mọi thứ với tốc độ chóng mặt, gần như không cần chỉnh sửa và đặc biệt là sở hữu một bộ nhớ "siêu phàm" về ngữ cảnh. Nhờ đó, việc phát triển cả một hệ sinh thái phức tạp bỗng trở nên... tự nhiên như hơi thở! Nó không chỉ giúp mình tiết kiệm thời gian, mà còn biến những điều tưởng chừng "bất khả thi" thành hiện thực.Bạn có tin không, một dự án mà thông thường phải mất đến 5 tuần và tiêu tốn hơn 30.000 đô la để xây dựng, mình đã hoàn thành chỉ trong vòng chưa đầy 8 tiếng đồng hồ với Kiro! Nghe có vẻ "phét lác" nhưng đó là sự thật 100% đấy! Mình chỉ cần một ý tưởng, phác thảo một prompt ban đầu, và đến cuối ngày, mình đã có một đoạn mã Python hoàn chỉnh, đa luồng, đa vùng, có khả năng quét môi trường AWS của mình bằng boto3. Kiro không chỉ "hiểu" được yêu cầu mà còn "nhớ" cách mình cấu trúc công cụ, tái sử dụng các mẫu mình yêu thích, và tự điều chỉnh linh hoạt. Đây chính là sức mạnh "đáng gờm" của bộ nhớ GenAI bền bỉ!Để các bạn dễ hình dung Kiro "khủng" cỡ nào, mình sẽ "khoe" một script nhỏ nhưng cực kỳ hiệu quả mà mình đã tạo ra, có tên là EC2 Exposure Scanner (tạm dịch: Công cụ quét lỗ hổng EC2). Nó làm những gì ư? Đơn giản thôi:Nó sẽ liệt kê "sạch sành sanh" tất cả các vùng (region) AWS mà bạn đang dùng.Sau đó, nó "mách lẻo" những subnet công cộng bằng cách "soi" các bảng định tuyến xem có đường dẫn nào đi thẳng ra Internet Gateway (IGW) với dải IP 0.0.0.0/0 hay không.Kế đến là "khám xét" từng instance EC2 (ngay cả những cái đang "ngủ đông"!).Nó sẽ chỉ đích danh những instance nào đang nằm trong subnet công cộng mà lại có Security Group (như "hàng rào bảo vệ") cho phép bất kỳ ai (0.0.0.0/0) truy cập vào cổng 80 (HTTP) hoặc 443 (HTTPS) TCP. Kể cả những quy tắc quá "thoáng" hay dải cổng rộng cũng bị "tóm gọn" hết!Cuối cùng, nó xuất ra báo cáo "chuẩn không cần chỉnh" dưới dạng JSON và Markdown.Và đỉnh của chóp là nó còn "khuyến mãi" cả các đoạn mã gợi ý để "vá" lỗi (remediation snippets) bằng cả CloudFormation lẫn Terraform nữa chứ!Script này chỉ tốn vài lần "đàm phán" với Kiro là xong, và giờ thì mình dùng nó như cơm bữa trong các đợt đánh giá nội bộ rồi đó!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kktdqnhsy0iaraievll.png' alt='Giao diện Kiro đang tạo EC2 Exposure Scanner'>À mà này, có một phong cách làm việc với GenAI mà mình cực kỳ "khoái" đó là "Vibe Coding". Nghe tên là thấy "chill" rồi đúng không? Nó hoàn hảo cho mấy cái script nhỏ gọn, dùng một lần rồi thôi. Cách mình dùng thì thế này:Bắt đầu mỗi phiên làm việc với Kiro bằng một "session prompt" (kiểu như dặn dò trước AI đó). Nó sẽ cho Kiro biết mình muốn code phải được cấu trúc ra sao, theo chuẩn nào, và mình thích kiểu đa luồng (threading) hay ghi log (logging) nào.Sau đó, mình chỉ việc "tám chuyện" với Kiro, mô tả chi tiết cái script mình muốn nó làm.Thế là Kiro trả về ngay một đoạn code AWS sạch bong, có đa luồng, nhận diện vùng (region-aware), với đầu ra nhất quán, tóm tắt rõ ràng và cả phần xử lý lỗi nữa chứ. "Bảo sao không mê"!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b5swchwaj3g189y8jpvs.png' alt='Giao diện Kiro Vibe Coding'>Mình có để lại chi tiết cái "đơn đặt hàng" cho Kiro về dự án EC2 Exposure Scanner này đây, để bạn thấy nó "xử lý" cả một "rừng" yêu cầu kỹ thuật chi tiết như thế nào nhé:Mục tiêu: Tạo ra một script Python chạy trên CLI (dòng lệnh) để tìm tất cả các instance EC2 nào đang nằm trong subnet công cộng (tức là có đường ra Internet) mà lại có nhóm bảo mật (Security Group) cho phép truy cập từ mọi nơi (0.0.0.0/0) vào cổng TCP 80 hoặc 443 – dù là trực tiếp hay thông qua dải cổng. Công cụ phải xuất kết quả cả dạng dễ đọc và JSON, kèm theo gợi ý vá lỗi bằng CloudFormation hoặc Terraform.Đầu vào: Chỉ cần dùng AWS credentials mặc định của boto3, quét một tài khoản AWS duy nhất, qua tất cả các vùng AWS, và sử dụng tối đa 3 luồng (thread) để xử lý song song các vùng.Các bước triển khai (mà Kiro đã "hiểu" và "làm"):1. Phát hiện vùng: Liệt kê tất cả các vùng đang hoạt động.2. Xác định Subnet công cộng: Ở mỗi vùng, kiểm tra bảng định tuyến để tìm subnet có đường ra Internet Gateway.3. Liệt kê Instance EC2: Quét tất cả instance EC2 (kể cả đang dừng) trong các subnet công cộng, lấy thông tin về instance và Security Group đính kèm.4. Đánh giá Security Group: Kiểm tra từng Security Group của các instance công cộng, xem có luật nào cho phép truy cập từ 0.0.0.0/0 vào cổng 80 hoặc 443 (hoặc dải cổng bao gồm chúng) không.5. Báo cáo kết quả: Ghi lại chi tiết từng instance vi phạm.6. Gợi ý vá lỗi: Tự động tạo ra mã Terraform và CloudFormation để khắc phục (ví dụ: loại bỏ luật truy cập 0.0.0.0/0 hoặc giới hạn CIDR).7. Tổng kết: Theo dõi và báo cáo tổng số instance, số instance trong subnet công cộng, và số instance bị lộ cổng 80/443, chi tiết theo từng vùng và toàn tài khoản.8. Đầu ra: Lưu kết quả vào các file JSON, Markdown và file last_checked.txt. Báo cáo Markdown phải cực kỳ rõ ràng, dễ đọc.9. Đa luồng & Ghi log: Sử dụng concurrent.futures.ThreadPoolExecutor để xử lý đa luồng và ghi lỗi vào error.log.Sản phẩm cuối cùng: Một script CLI scan_ec2_exposure.py hoạt động ngon lành, các file báo cáo cấu trúc rõ ràng, và các đoạn mã khắc phục 'chuẩn không cần chỉnh'.Lưu ý quan trọng: Không hề quét cổng trực tiếp hay kiểm tra mạng 'sống' gì hết, chỉ dùng AWS API. Đánh giá tất cả EC2 dù đang chạy hay dừng. Phát hiện mọi trường hợp lộ cổng TCP qua 0.0.0.0/0 (trực tiếp hoặc qua dải cổng). Chỉ dùng các thư viện chuẩn như boto3, json, threading, logging.Vibe coding siêu nhanh, cực kỳ 'phiêu', và rất phù hợp cho các Red Teamers hay kỹ sư bảo mật đám mây, những người cần công cụ tùy chỉnh mà không muốn mất công xây dựng từ đầu mỗi lần.Nếu 'Vibe Coding' là dành cho những nhiệm vụ 'nhỏ gọn, nhanh gọn', thì Kiro còn có một 'vũ khí' lợi hại hơn nhiều, đó là 'Spec-Based Coding' (Lập trình dựa trên đặc tả). Với cách này, mình sẽ bắt đầu bằng việc chuẩn bị một bộ tài liệu:requirements.md: Nơi mình ghi rõ 'phi vụ' này là gì và tại sao nó lại 'ra đời'.design.md: Bản đồ kỹ thuật chi tiết cho dự án.tasks.md: 'Phân công lao động' chi tiết từng bước, thường là hơn chục đầu việc nhỏ cho các công cụ lớn.Cách làm này giúp Kiro 'sản xuất' mã nguồn có cấu trúc rõ ràng theo từng giai đoạn, cực kỳ lý tưởng cho việc xây dựng các dashboard, đường ống dữ liệu (data pipelines), tự động hóa trên đám mây (cloud-native automation) hay các tiện ích bảo mật quy mô lớn hơn. Kết quả là bạn sẽ có được một đoạn code 'sạch bong kin kít', nhất quán, dễ dàng quản lý phiên bản, bảo trì và mở rộng!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvscpba2893o8uwfzssq.jpg' alt='Quy trình Spec-Based Coding với Kiro'>"Công cụ nên là đồng đội, chứ không chỉ là tính năng tự động hoàn thành!" Đúng vậy! Kiro không chỉ đơn thuần là phản hồi theo yêu cầu, nó còn đóng vai trò như một 'đồng phát triển' thực thụ. Với khả năng ghi nhớ các mẫu code, chủ động gợi ý sửa lỗi, và thậm chí tự tạo ra mã vá lỗi (bằng CloudFormation và Terraform), Kiro là lựa chọn 'số zách' cho các nhóm muốn tăng tốc mà không phải 'cắt xén' chất lượng. Đặc biệt trong lĩnh vực bảo mật, Kiro càng phát huy tối đa sức mạnh:Tốc độ: Giúp vá lỗi kịp thời trước khi hệ thống bị xâm nhập.Nhất quán: Đảm bảo sẵn sàng cho các cuộc kiểm toán.Tùy chỉnh: Giúp 'qua mặt' các hệ thống phát hiện trong công việc của Red Team.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25nkfjab7nz3gbgv1gq8.png' alt='Lợi ích của Kiro trong bảo mật'>Bạn là một kỹ sư đám mây, một chuyên gia DevSecOps hay trưởng nhóm Red Team ư? Vậy thì Kiro chắc chắn phải có mặt trong 'tủ đồ nghề' của bạn rồi! Hãy bắt đầu với một dự án nhỏ, thử 'vibe coding' một công cụ quét đơn giản hoặc một script liệt kê thông tin. Sau đó, bạn sẽ dần 'lên level' với phong cách phát triển dựa trên đặc tả. Tin mình đi, bạn sẽ phải 'mắt tròn mắt dẹt' với những gì mình có thể xây dựng đấy! 🔗 Muốn thử Kiro ngay và luôn? Ghé thăm: Kiro.devTóm lại, Kiro đã thay đổi hoàn toàn cách mình xây dựng mọi thứ. Giờ đây, câu chuyện không chỉ là code nhanh hơn, mà là cách chúng ta tư duy khác đi. Tự động hóa những tác vụ mà trước đây mình thường 'lười' bỏ qua. Xây dựng những công cụ mà mình chưa bao giờ có thời gian để làm. Phát hiện ra những lỗ hổng mà người khác có thể bỏ sót. Đây chính là 'phép màu' khi GenAI trở thành một 'đồng đội' thực thụ, chứ không còn chỉ là một công cụ đơn thuần nữa!
Chào bạn! Bạn có bao giờ cảm thấy "đau đầu" khi phải triển khai hạ tầng đám mây một cách thủ công không? Kiểu như phải nhớ từng bước một, sợ sai sót, hay phải thức khuya thức hôm để làm những việc lặp đi lặp lại? AWS CloudFormation chính là "cứu tinh" của bạn đó! Nó giúp chúng ta định nghĩa toàn bộ hạ tầng (từ mạng lưới đến máy chủ) chỉ bằng một file "công thức" duy nhất. Từ đó, mọi thứ sẽ được triển khai tự động, nhất quán và cực kỳ đáng tin cậy, thậm chí bạn có thể lên lịch cho nó chạy mà không cần động tay động chân. Trong bài lab này, chúng ta sẽ cùng nhau khám phá cách biến những ý tưởng hạ tầng phức tạp thành hiện thực chỉ với vài cú click trên AWS CloudFormation, từ triển khai các tầng hạ tầng khác nhau, cập nhật "stack" (tập hợp tài nguyên) cho đến xóa bỏ nó một cách thông minh (giữ lại những gì cần thiết).Sau bài lab này, bạn sẽ "nắm trong lòng bàn tay" những kỹ năng siêu đỉnh sau đây:Triển khai cả một mạng lưới ảo (VPC) bằng AWS CloudFormation – xây nhà cần có móng vững chãi mà!Dựng lên một "tòa nhà" ứng dụng (với máy chủ, nhóm bảo mật) và kết nối nó với mạng lưới vừa tạo – mọi thứ liên kết chặt chẽ như mô hình lego vậy!Thăm dò các "công thức" (template) bằng AWS CloudFormation Designer (Infrastructure Composer) – công cụ giúp bạn "vẽ" ra hạ tầng một cách trực quan, sinh động.Dọn dẹp "chiến trường" bằng cách xóa stack nhưng vẫn giữ lại những tài nguyên quan trọng nhờ chính sách xóa thông minh – dọn nhà mà không làm mất đồ quý!Giờ thì, chúng ta cùng "xắn tay áo" vào việc thôi nào!Bạn đã sẵn sàng để "phù phép" ra một mạng lưới ảo trên AWS chưa? Nhiệm vụ đầu tiên của chúng ta là triển khai một template AWS CloudFormation để tạo ra một "tầng mạng" bằng Amazon VPC.1. Đầu tiên, hãy tải ngay file template "công thức" này về máy: lab-network.yaml. Bạn biết không, các template có thể được viết bằng JSON hoặc YAML đấy. Nhưng YAML thì dễ đọc và dễ chỉnh sửa hơn nhiều, cứ như là ngôn ngữ "thân thiện với người dùng" hơn vậy!2. Truy cập vào CloudFormation Dashboard và cùng "điền thông tin" cho stack của chúng ta nào:Chọn Create stack > With new resources (standard). Đây là kiểu tạo stack mới toanh luôn đó.Prepare template: Chọn Template is ready vì chúng ta đã có file template rồi.Template source: Tải lên file lab-network.yaml mà bạn vừa down về.Stack name: Đặt tên stack là lab-network nhé. Tên này sẽ giúp bạn dễ dàng nhận diện nó sau này.Tags: Thêm một cái tag Key: application với Value: inventory. Việc gán tag này cực kỳ hữu ích đó, nó giúp chúng ta dễ dàng quản lý và phân loại tài nguyên sau này. Cứ như dán nhãn cho từng món đồ trong kho vậy!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frk8iye6eqdu847b5losq.png' alt='Giao diện tạo stack CloudFormation'>Sau khi CloudFormation đọc xong "công thức" này, nó sẽ tự động tạo ra một "stack" (một tập hợp các tài nguyên) trong tài khoản AWS của bạn. Đơn giản là CloudFormation sẽ "làm theo" những gì bạn đã mô tả trong file template!3. Chọn tab Resources. Bạn sẽ thấy một danh sách chi tiết các tài nguyên mà template vừa "phù phép" ra. Cứ như xem danh sách những món đồ mới tinh trong nhà bạn vậy!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspqq5q28urd7jd13peq0.png' alt='Danh sách tài nguyên trong CloudFormation stack'>4. Chọn tab Events và "dạo quanh" xem các sự kiện đã diễn ra. Mọi hoạt động của CloudFormation đều được ghi lại ở đây, từ lúc bắt đầu tạo tài nguyên cho đến khi hoàn thành. Nếu có bất kỳ lỗi nào xảy ra trong quá trình tạo stack, bạn cũng sẽ thấy nó xuất hiện ở đây đó!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0n5i0go1l54duc5vt6q1.png' alt='Các sự kiện trong CloudFormation stack'>5. Cuối cùng, hãy ghé thăm tab Outputs. Đây là nơi các stack có thể "chia sẻ" giá trị cho nhau. Trong trường hợp này, các ID của VPC và Subnet đã được gán tên "xuất" (export names) để các stack khác có thể dễ dàng "lấy" chúng. Nhờ vậy, những stack sau này có thể xây dựng tài nguyên bên trong chính cái VPC và Subnet mà chúng ta vừa tạo ra!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd8fsp9dec4xmmn874lsw.png' alt='Outputs của CloudFormation stack'>Mạng lưới đã có, giờ là lúc dựng ứng dụng lên thôi! Chúng ta sẽ triển khai một tầng ứng dụng bao gồm một máy chủ Amazon EC2 (một máy tính ảo trên đám mây) và một nhóm bảo mật (Security Group) – cánh cổng bảo vệ máy chủ của bạn.Template AWS CloudFormation lần này sẽ "nhập khẩu" các ID của VPC và Subnet từ output của stack lab-network mà chúng ta vừa tạo. Sau đó, nó sẽ dùng thông tin này để tạo nhóm bảo mật trong VPC và máy chủ EC2 trong Subnet đã có sẵn. Thật là tiện lợi phải không nào?1. Tải ngay file template lab-application.yaml về máy tính của bạn.2. Quay lại CloudFormation Dashboard và cấu hình tương tự như Task 1:Create stack > With new resources (standard).Prepare template: Template is ready.Template source: Tải lên file lab-application.yaml.Stack name: Đặt là lab-application.Tags: Key: application với Value: inventory.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbstovxtqfojz2q7e5sv0.png' alt='Giao diện tạo stack ứng dụng CloudFormation'>3. Sau khi stack lab-application hoàn tất, hãy vào tab Output. Sao chép đường dẫn URL hiển thị ở đó, mở một tab trình duyệt mới, dán URL vào và nhấn Enter. Bạn sẽ thấy ứng dụng của mình đang chạy rồi đó!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qlzh8cde3t8ihkydqtg.png' alt='Output của stack ứng dụng'>Bạn thấy không, một stack CloudFormation hoàn toàn có thể dùng các giá trị từ một stack khác! Ví dụ, đoạn code nhỏ này trong template lab-application đã "mượn" thông tin từ lab-network:WebServerSecurityGroup:Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Enable HTTP ingress VpcId: Fn::ImportValue: !Sub ${NetworkStackName}-VPCID Dòng cuối cùng, !Fn::ImportValue, chính là "chìa khóa" thần kỳ đó! Nó dùng tên stack mạng mà bạn đã cung cấp (lab-network) để nhập giá trị lab-network-VPCID từ output của stack đầu tiên. Kết quả là, nhóm bảo mật của bạn được tạo ra chính xác trong cái VPC mà chúng ta đã xây dựng từ đầu!Giờ thì hãy thử tài năng "nâng cấp" của mình nhé! Trong nhiệm vụ này, chúng ta sẽ cập nhật stack lab-application để thay đổi một cài đặt trong nhóm bảo mật.1. Vào EC2 dashboard và tìm đến mục Security Group.2. Quan sát các quy tắc Inbound rules của nhóm lab-application-WebServerSecurityGroup. Hiện tại, chỉ có một quy tắc cho phép lưu lượng HTTP (cổng 80) thôi.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21a2svarho8ptzerpadj.png' alt='Quy tắc Inbound ban đầu của Security Group'>3. Tải ngay template đã được cập nhật lab-application2.yaml về máy bạn.Template mới này có thêm một "phép thuật" nhỏ nữa là cho phép lưu lượng HTTPS (cổng 443) đi vào. Cụ thể là đoạn này:- IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/04. Trong CloudFormation console, hãy chọn stack lab-application và chọn Update rồi cấu hình như sau:Prepare template: Chọn Replace current template.Template source: Chọn Upload a template file.Upload a template file: Tải lên file lab-application2.yaml mà bạn vừa down.Trước khi bạn xác nhận, CloudFormation sẽ hiển thị bản xem trước các thay đổi (Change set preview). Bạn sẽ thấy WebServerSecurityGroup được liệt kê với Replacement = False. Điều này có nghĩa là CloudFormation sẽ chỉ "chỉnh sửa" nhỏ gọn nhóm bảo mật này mà không cần phải xóa đi tạo lại hoàn toàn. Thật thông minh phải không? Không cần phải "thay cả áo" chỉ vì muốn thêm một cái túi!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxs9ava1sa5gfzyjyoo7z.png' alt='Xem trước các thay đổi của CloudFormation'><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu712zjdk9np341n0j571.png' alt='Màn hình xác nhận cập nhật stack'>Sau khi cập nhật xong, hãy quay lại Amazon EC2 console, chọn lab-application-WebServerSecurityGroup trong danh sách Security Groups. Bạn sẽ thấy tab Inbound rules giờ đây đã có thêm một quy tắc mới, cho phép lưu lượng HTTPS qua cổng TCP 443 rồi đó! Quá tuyệt vời phải không?<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fza3t6dq6o3xhfph82zue.png' alt='Quy tắc Inbound sau khi cập nhật'>Bạn có muốn "vẽ vời" hạ tầng đám mây của mình một cách trực quan không? AWS CloudFormation Designer (hay còn gọi là Designer hoặc Infrastructure Composer) chính là công cụ dành cho bạn! Nó giống như một bảng vẽ thần kỳ, giúp bạn tạo, xem và chỉnh sửa các template CloudFormation một cách dễ dàng. Bạn có thể kéo thả các tài nguyên vào "bức tranh" hạ tầng của mình, sau đó chỉnh sửa chi tiết ngay trong trình soạn thảo JSON và YAML tích hợp.1. Trong CloudFormation Console, chọn Infrastructure Composer.2. Tải lên template lab-application2.yaml mà chúng ta đã dùng trước đó. Và bùm! Designer sẽ hiển thị một biểu đồ đồ họa tuyệt đẹp về template của bạn. Nhìn là hiểu liền!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhqly5dbu5banyl8qbdxv.png' alt='Giao diện CloudFormation Designer'>Mọi cuộc vui nào cũng đến lúc tàn, và hạ tầng cũng vậy! Khi không còn cần đến tài nguyên nào đó nữa, AWS CloudFormation có thể giúp bạn "dọn dẹp" sạch sẽ. Nhưng có một điều thú vị hơn, bạn có thể thiết lập "chính sách xóa" (Deletion Policy) cho các tài nguyên. Chính sách này cho phép bạn bảo tồn hoặc thậm chí sao lưu một tài nguyên nào đó khi stack của nó bị xóa. Điều này cực kỳ hữu ích cho các cơ sở dữ liệu, ổ đĩa, hoặc bất kỳ tài nguyên quan trọng nào mà bạn muốn giữ lại ngay cả khi ứng dụng không còn chạy nữa. Nó cũng là một "lá chắn" tuyệt vời để ngăn chặn việc vô tình xóa mất dữ liệu quan trọng!Stack lab-application của chúng ta đã được cấu hình để tự động chụp một bản snapshot (ảnh chụp nhanh) của ổ đĩa Amazon Elastic Block Store (Amazon EBS) trước khi bị xóa. Đoạn code "thần kỳ" làm được điều đó chính là đây:DiskVolume:Type: AWS::EC2::VolumeProperties:Size: 100AvailabilityZone: !GetAtt WebServerInstance.AvailabilityZoneTags:- Key: NameValue: Web DataDeletionPolicy: Snapshot Bạn thấy đấy, dòng DeletionPolicy: Snapshot đã "ra lệnh" cho CloudFormation phải tạo một bản sao lưu trước khi "tiễn" ổ đĩa đi đó!1. Trong CloudFormation console, chọn liên kết lab-application và chọn Delete.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzauq5ffos794665hqrlm.png' alt='Xóa CloudFormation stack'>Stack ứng dụng đã được "dọn dẹp", nhưng stack mạng lưới (lab-network) thì vẫn còn nguyên vẹn. Điều này nhấn mạnh một ý tưởng tuyệt vời: các nhóm khác nhau (ví dụ: nhóm mạng hoặc nhóm ứng dụng) có thể quản lý các stack của riêng họ một cách độc lập!2. Để kiểm tra xem bản snapshot của ổ đĩa EBS đã được tạo trước khi nó bị xóa hay chưa, hãy vào EC2 Dashboard và chọn Snapshots. Bạn sẽ thấy "bằng chứng" ngay!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3q5dg9uk2gqbkjkdy154.png' alt='Danh sách Snapshots'>Vậy là chúng ta đã cùng nhau trải qua một hành trình thú vị với AWS CloudFormation rồi đó! Sau bài lab này, bạn đã bỏ túi được những kiến thức siêu xịn sò như:Triển khai cả một "khu phố" mạng ảo (VPC) bằng AWS CloudFormation – xây nền tảng vững chắc!Dựng lên một "ngôi nhà" ứng dụng và kết nối nó với "khu phố" mạng đã có – mọi thứ hoạt động hài hòa!Trực quan hóa và "chơi đùa" với các template bằng AWS CloudFormation Designer – biến những dòng code khô khan thành hình ảnh sống động!Biết cách "dọn dẹp" stack một cách thông minh, vừa sạch sẽ vừa giữ được những thứ quan trọng – dọn nhà như một chuyên gia vậy!Chúc mừng bạn đã hoàn thành xuất sắc bài lab này! Giờ thì bạn đã có thêm một "siêu năng lực" mới trong thế giới đám mây rồi đó!
Khám phá AWS Kiro, IDE AI mới toanh từ AWS với khả năng tự động tạo spec, quản lý tác vụ và tích hợp hạ tầng. So sánh chi tiết với GitHub Copilot, Google Gemini Code Assist và Cursor để xem đâu là lựa chọn tốt nhất cho bạn.
Bạn đang xây dựng giải pháp GenAI trên AWS nhưng lại 'bí' khoản dữ liệu? Bài viết này sẽ hướng dẫn chi tiết cách biến kho dữ liệu hỗn độn thành một hệ thống thông minh, dễ quản lý, từ cấu trúc S3 đến tự động hóa với Glue, DataBrew, Textract, Lake Formation và DataZone. Khám phá bí quyết 'biến garage thành thư viện' cho dữ liệu GenAI của bạn!
Bạn có bao giờ giật mình thót tim khi thấy hóa đơn AWS cứ tăng vùn vụt, trong khi bạn cứ nghĩ mình đã "tắt" hết mọi thứ rồi không? ☁️💸 Đừng lo, tôi hiểu cảm giác đó! Và hôm nay, tôi sẽ "bật mí" cho bạn một chiêu cực hay để tự động kiểm soát chi phí AWS, đảm bảo túi tiền của bạn luôn an toàn. Chúng ta sẽ cùng nhau biến hóa bằng cách: Dựng một em Lambda "thông minh" với Boto3, dùng AWS SNS để "gọi" em ấy ra thông báo, thiết lập một "ngân sách" siêu bé chỉ $0.01, và tự động "đá đít" mấy em EC2 đang chạy khi chi phí vượt ngưỡng! Nghe có vẻ phức tạp nhưng đảm bảo dễ hơn ăn kẹo luôn!Đầu tiên, hãy đến với AWS SNS (Simple Notification Service) – dịch vụ gửi thông báo "tức tốc" của AWS. Hãy tưởng tượng nó như một người đưa tin siêu tốc vậy đó!1. Vào giao diện SNS, chọn Topics (Chủ đề).2. Nhấn Create topic (Tạo chủ đề mới).3. Chọn Type: Standard (Loại: Tiêu chuẩn).4. Đặt tên cho chủ đề là BudgetAlertsTopic.5. Nhấn Create topic để hoàn tất.Giờ thì, làm sao để "người đưa tin" này biết báo cho ai?1. Trong tab Subscriptions (Đăng ký) của chủ đề vừa tạo, nhấn Create subscription (Tạo đăng ký mới).2. Chọn Protocol: Email (Giao thức: Email).3. Tại Endpoint (Điểm cuối), nhập địa chỉ email của bạn vào nhé.4. Cuối cùng, hãy kiểm tra hộp thư email của bạn và xác nhận đăng ký. Vậy là mỗi khi có tin báo từ chủ đề này, bạn sẽ nhận được email ngay tắp lự! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6nludyqljny61uj9b2n.png' alt='Tạo chủ đề SNS BudgetAlertsTopic'>Giờ thì chúng ta sẽ đặt ra "ngân sách giới hạn" cho AWS của mình. Đơn giản là mình sẽ bảo AWS: "Này, khi nào chi phí của tôi chạm đến con số này thì báo động cho tôi nhé!"1. Vào Billing (Thanh toán) > Budgets (Ngân sách).2. Nhấn Create Budget (Tạo ngân sách mới).3. Chọn Type: Cost Budget (Loại: Ngân sách chi phí).4. Đặt tên cho ngân sách là MyBillingBudget.5. Phần Budget amount (Số tiền ngân sách), hãy mạnh dạn gõ 0.01 đô la nhé (vì chúng ta muốn test ngay lập tức mà!).6. Scope (Phạm vi) chọn All services (Tất cả dịch vụ) để bao quát hết mọi thứ.7. Đến phần Notifications (Thông báo): Threshold (Ngưỡng): Đặt 100% (Tức là khi chi phí đạt đúng 100% của $0.01 thì báo). Send to: Chọn chủ đề SNS mà bạn vừa tạo – BudgetAlertsTopic.8. Cuối cùng, nhấn Create budget để lưu lại. Vậy là bạn đã có một "người gác cổng" tài chính siêu chặt chẽ rồi đấy! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9nk5kkqrja9cxplv9ide.png' alt='Thiết lập ngân sách $0.01 trong AWS'>Để "em" Lambda của chúng ta có quyền năng "dừng" các dịch vụ và "khóa" S3, chúng ta cần cấp cho em ấy một cái "visa đặc biệt" mang tên IAM Role (Vai trò IAM).1. Vào IAM > Roles (Vai trò).2. Nhấn Create Role (Tạo vai trò).3. Phần Use Case (Trường hợp sử dụng), chọn Lambda.4. Tiếp theo, đến phần cấp quyền (Permissions). Chúng ta sẽ tạo một custom policy (chính sách tùy chỉnh) mới. Hãy dán đoạn JSON "quyền năng" này vào nhé:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:StopInstances", "s3:ListBucket", "s3:PutPublicAccessBlock" ], "Resource": "*" } ]}Giải thích xíu: Đoạn này cho phép Lambda của chúng ta "nhìn" được các EC2 đang chạy (ec2:DescribeInstances), "dừng" chúng lại (ec2:StopInstances), "liệt kê" các bucket S3 (s3:ListBucket), và "khóa" quyền truy cập công cộng của chúng (s3:PutPublicAccessBlock). "Resource": "*" nghĩa là áp dụng cho tất cả tài nguyên (dù không khuyến khích trong môi trường production, nhưng để demo thì okela nhé!).5. Cuối cùng, đặt tên cho vai trò này là LambdaBillingStopperRole. Xong! Bây giờ em Lambda đã có giấy phép hành nghề rồi!Đây là phần "linh hồn" của cả hệ thống tự động của chúng ta – Lambda function! Lambda là một dịch vụ "serverless" của AWS, nghĩa là bạn chỉ cần viết code, còn việc chạy và quản lý server cứ để AWS lo. Siêu tiện lợi luôn!1. Vào Lambda > Create Function (Tạo hàm mới).2. Đặt tên cho hàm là StopAWSResources.3. Runtime (Môi trường chạy): Chọn Python 3.12.4. Role (Vai trò): Gắn vai trò LambdaBillingStopperRole mà bạn vừa tạo vào nhé.5. Giờ thì đến màn "ma thuật" đây! Hãy dán đoạn mã Python "thần thánh" này vào trình soạn thảo code của Lambda:import boto3def lambda_handler(event, context): ec2 = boto3.client('ec2') s3 = boto3.client('s3') # Dừng tất cả các phiên bản EC2 đang chạy print("Đang tìm và dừng các phiên bản EC2 đang chạy...") instances = ec2.describe_instances(Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]) for reservation in instances['Reservations']: for instance in reservation['Instances']: ec2.stop_instances(InstanceIds=[instance['InstanceId']]) print(f"Đã dừng phiên bản EC2: {instance['InstanceId']}") # Khóa quyền truy cập công cộng của tất cả các S3 bucket print("Đang khóa quyền truy cập công cộng của các S3 bucket...") buckets = s3.list_buckets() for bucket in buckets['Buckets']: try: s3.put_public_access_block( Bucket=bucket['Name'], PublicAccessBlockConfiguration={ 'BlockPublicAcls': True, 'IgnorePublicAcls': True, 'BlockPublicPolicy': True, 'RestrictPublicBuckets': True } ) print(f"Đã khóa quyền truy cập công cộng cho bucket: {bucket['Name']}") except Exception as e: print(f"Không thể khóa quyền truy cập công cộng cho bucket {bucket['Name']}: {e}") return { 'statusCode': 200, 'body': 'EC2 đã dừng và các S3 bucket đã bị khóa quyền truy cập công cộng.' }Giải thích Code: import boto3: Đây là thư viện Python giúp chúng ta "nói chuyện" với các dịch vụ AWS. ec2 = boto3.client('ec2') và s3 = boto3.client('s3'): Khởi tạo "người đại diện" để làm việc với EC2 và S3. Phần dừng EC2: Code sẽ đi "kiểm tra" tất cả các EC2 đang ở trạng thái running (đang chạy), sau đó "ra lệnh" cho chúng dừng lại. Phần khóa S3: Code sẽ "đi vòng quanh" tất cả các S3 bucket của bạn và bật chế độ Public Access Block (Chặn truy cập công cộng) toàn diện. Điều này giúp ngăn chặn việc dữ liệu trong S3 vô tình bị lộ ra ngoài, tránh các chi phí phát sinh không đáng có từ truy cập lạ.6. Sau khi dán xong, nhấn Deploy (Triển khai) để lưu và kích hoạt hàm nhé! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdh9m7qap8utbvwkny6z.png' alt='Giao diện tạo Lambda Function'> <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9dsg3pa9aa11d21183n8.png' alt='Code Lambda Function được dán vào'>Tuyệt vời! Chúng ta đã có "người gác cổng" (Budget), "người đưa tin" (SNS), và "người hành động" (Lambda). Giờ là lúc kết nối chúng lại với nhau để tạo thành một cỗ máy tự động hoàn chỉnh! Chúng ta sẽ cho SNS biết rằng khi có tin báo từ BudgetAlertsTopic, hãy "kích hoạt" Lambda StopAWSResources nhé.1. Quay lại SNS > Topics > Chọn BudgetAlertsTopic.2. Click Create subscription (Tạo đăng ký mới).3. Protocol (Giao thức): Chọn AWS Lambda.4. Endpoint (Điểm cuối): Chọn hàm StopAWSResources của bạn.Hoặc cách khác, bạn có thể thực hiện từ phía Lambda (thường dễ hơn để quản lý quyền):1. Vào Lambda > Chọn hàm StopAWSResources của bạn.2. Trong tab Permissions (Quyền), nhấn Add trigger (Thêm trình kích hoạt).3. Chọn SNS làm loại trình kích hoạt.4. Tại SNS topic, chọn BudgetAlertsTopic.5. Nhấn Add để hoàn tất.Thế là xong! Bây giờ, mỗi khi ngân sách của bạn chạm ngưỡng $0.01, SNS sẽ gửi thông báo, và ngay lập tức kích hoạt hàm Lambda để "cứu nguy" cho hóa đơn của bạn! <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2olqcuh5hhdztn5uf1l5.png' alt='Kết nối SNS với Lambda'>Và đây là lúc chứng kiến "phép màu" của chúng ta hoạt động! Khi chi phí AWS của bạn vừa chạm ngưỡng $0.01 (hoặc bất kỳ ngưỡng nào bạn đặt), điều kỳ diệu sẽ xảy ra:1. Budget phát hiện chi phí vượt ngưỡng, ngay lập tức gửi cảnh báo.2. Cảnh báo này được gửi đến SNS Topic BudgetAlertsTopic.3. SNS nhận được tin, lập tức "kích hoạt" hàm Lambda StopAWSResources.4. Hàm Lambda được chạy, và BÙM! Tất cả các phiên bản EC2 đang chạy của bạn sẽ tự động "đi ngủ" (stopped), đồng thời các S3 bucket sẽ được "khóa cửa" (block public access).Bạn có thể tự mình kiểm tra để xem mọi thứ hoạt động trơn tru đến mức nào nhé: Vào EC2 Dashboard: Bạn sẽ thấy những phiên bản EC2 đáng lẽ đang chạy giờ đã chuyển sang trạng thái stopped một cách tự động. Tuyệt vời phải không? <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7113tmppkfmncvqg9ep.png' alt='EC2 instances đã dừng tự động'> Kiểm tra CloudWatch Logs: Để chắc chắn hơn, bạn có thể vào CloudWatch > Log groups, tìm log group của hàm Lambda StopAWSResources. Trong các Log stream gần nhất, bạn sẽ thấy các thông báo mà hàm Lambda đã in ra, xác nhận rằng nó đã thực hiện việc dừng EC2 và khóa S3 thành công. <img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2x0ute96md7fptmeta2.png' alt='Kiểm tra log CloudWatch của Lambda'>Vậy là chúng ta đã hoàn thành xuất sắc nhiệm vụ kiểm soát chi phí AWS một cách tự động rồi đó! Không còn nỗi lo về những hóa đơn bất ngờ nữa. Tự động hóa thật là "chân ái" phải không nào? 💥Hãy cùng chờ đón thêm nhiều bài viết và hướng dẫn triển khai hấp dẫn khác nhé! 🫡🔥
Bạn có bao giờ 'đau đầu' với Kubernetes trên EKS? Đừng lo, kubectl-ai chính là 'siêu trợ lý' mà bạn đang tìm kiếm! Bài viết này sẽ giúp bạn khám phá cách kubectl-ai, một công cụ mã nguồn mở từ Google Cloud, biến việc gỡ lỗi, quản lý và hiểu lỗi Kubernetes trở nên dễ dàng chỉ bằng ngôn ngữ tự nhiên. Từ cách cài đặt trên Linux, macOS, Windows đến việc cấu hình với Google Gemini và các trường hợp sử dụng thực tế (như khắc phục lỗi pod CrashLoopBackOff hay ImagePullBackOff), bạn sẽ thấy việc quản lý cụm EKS chưa bao giờ 'nhẹ nhàng' đến thế. Hãy cùng tìm hiểu cách tận dụng AI để làm việc hiệu quả hơn và biến những dòng lệnh 'khô khan' thành cuộc trò chuyện thú vị!
Khám phá LogManticsAI, công cụ dòng lệnh mã nguồn mở sử dụng LLM để phân tích ngữ nghĩa log JSON, phát hiện bất thường thời gian thực và giám sát liên tục ngay tại terminal của bạn. Nâng cấp quy trình DevOps với AI!
Hướng dẫn chi tiết xây dựng pipeline tự động hóa xử lý PDF, tạo embeddings với OpenAI và lưu trữ vào Zilliz Cloud, sử dụng AWS Lambda và CircleCI cho CI/CD.
Khám phá Canvas Cloud AI với tính năng "Learn by Describe" giúp bạn tạo ra kiến trúc điện toán đám mây phức tạp chỉ bằng cách mô tả đơn giản. Tiết kiệm thời gian, đảm bảo chuẩn mực và tối ưu hóa quy trình DevOps của bạn.
Chào các bạn lập trình viên thân mến! Có bao giờ bạn muốn một 'sân chơi' riêng để vọc vạch code Go ngay lập tức, không cần cài đặt lằng nhằng không? Hôm nay, mình sẽ dẫn các bạn đi một vòng khám phá cách mình đã "hô biến" ý tưởng đó thành hiện thực – một phiên bản Go Playground REPL "xịn sò" từ A đến Z! Từ backend Go mạnh mẽ biên dịch code trong Docker siêu bảo mật, đến frontend Vue.js đẹp mắt, rồi cả quy trình triển khai tự động lên AWS Elastic Beanstalk bằng GitHub Actions nữa. Nghe thôi đã thấy hấp dẫn rồi đúng không?<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/go_playground_intro.png' alt='Giới thiệu Go Playground REPL'> Ngôi nhà Go Playground này được xây dựng từ những viên gạch công nghệ nào nhỉ?Để xây dựng nên 'đứa con tinh thần' này, mình đã kết hợp một dàn 'siêu anh hùng' công nghệ đó:Backend: Go (Golang) – Ngôn ngữ quốc dân cho hiệu năng cao, cùng với Docker để 'đóng gói' môi trường chạy code an toàn, framework Gin siêu tốc, và gói os/exec thần thánh để 'điều khiển' các lệnh hệ thống.Frontend: Vue 3 – Ngôi sao sáng trong thế giới giao diện người dùng, đi kèm Pinia để quản lý trạng thái mượt mà, Tailwind CSS giúp 'trang điểm' cho giao diện lung linh, và Monaco Editor (cái trình soạn thảo code mà các bạn thấy trong VS Code ấy) để mang lại trải nghiệm gõ code cực đỉnh.DevOps: GitHub Actions – Người 'quản gia' tự động hóa mọi thứ, từ build Docker image, đẩy lên DockerHub, đến triển khai 'phù phép' lên AWS Elastic Beanstalk một cách tự động.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/tech_stack_collage.png' alt='Các công nghệ sử dụng trong dự án'> Vậy sản phẩm cuối cùng của chúng ta 'chất' như thế nào?Cái Go Playground REPL này không chỉ là một trình soạn thảo code thông thường đâu nhé, nó còn có:Một "sân vận động" code tương tác, nơi bạn có thể tha hồ viết và chạy các chương trình Go của mình.Một 'hậu trường' siêu an toàn, có khả năng:Chạy code của người dùng bên trong một "chiếc hộp" Docker riêng biệt, đảm bảo không ảnh hưởng gì đến hệ thống chính.Thiết lập 'hẹn giờ' để chặn đứng các đoạn code bị lỗi vòng lặp vô tận (đừng lo, không còn cảnh chờ đợi mòn mỏi nữa!).Xử lý mọi loại 'đầu vào' bất thường hay có ý đồ xấu một cách duyên dáng.Một 'mặt tiền' lung linh, tự động thay đổi giao diện sáng/tối, kèm theo các ví dụ code Go có sẵn để bạn thử nghiệm và xem kết quả ngay tức thì.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/repl_features.png' alt='Các tính năng chính của Go Playground REPL'> Xây Dựng 'Trái Tim' Hệ Thống: Backend Go và DockerĐể biến code của bạn thành kết quả, backend chính là 'bộ não' trung tâm. Mình đã dùng gói os/exec trong Go để biên dịch và chạy code của người dùng ngay bên trong một 'thùng' Docker riêng biệt, tách biệt hoàn toàn khỏi máy chủ. Tưởng tượng nó như một khu vực thử nghiệm được cô lập vậy đó!Đây là một đoạn code Go handler đơn giản minh họa cách xử lý yêu cầu chạy code:func RunCode(c *gin.Context) { var payload struct { Code string `json:"code"` } if err := c.ShouldBindJSON(&payload); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Định dạng yêu cầu không hợp lệ"}) return } output, err := runInDocker(payload.Code) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"output": output, "error": ""})} Và đây là 'công thức' Dockerfile để xây dựng môi trường chạy ứng dụng Go của chúng ta:FROM golang:1.24-alpineWORKDIR /appCOPY . .RUN go build -o repl-server ./cmdCMD [ "./repl-server" ] Đơn giản là: lấy ảnh Go, tạo thư mục làm việc, copy code vào, biên dịch thành file chạy được, rồi 'bảo' Docker chạy file đó khi container khởi động.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/backend_docker_flow.png' alt='Sơ đồ luồng xử lý Backend Go với Docker'> Tự Động Hóa Triển Khai: GitHub Actions 'Gánh Team'Bạn có chán nản với việc cứ phải làm đi làm lại các bước build rồi deploy mỗi khi có thay đổi không? Mình đã dùng GitHub Actions để tự động hóa toàn bộ quy trình CI/CD (Continuous Integration/Continuous Deployment)! Tưởng tượng thế này: mỗi khi mình push code lên GitHub, GitHub Actions sẽ tự động 'đóng gói' ứng dụng thành Docker image, đẩy nó lên ECR (Elastic Container Registry) của AWS, và cuối cùng là 'gửi' nó đến AWS Elastic Beanstalk – dịch vụ giúp triển khai ứng dụng lên mây dễ dàng.Các bước chính trong luồng CI/CD của chúng ta trông như thế này:Build Docker Image: Tạo ra 'bản sao' Docker của ứng dụng.Push to ECR: Đẩy 'bản sao' đó lên kho chứa của AWS.Deploy to EBS: 'Hô biến' ứng dụng lên máy chủ trên AWS Elastic Beanstalk.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/github_actions_pipeline.png' alt='Quy trình CI/CD với GitHub Actions'> Xây Dựng 'Gương Mặt' Dự Án: Frontend Vue.js và Monaco EditorSau khi có một backend vững chắc, giờ là lúc 'trang điểm' cho giao diện người dùng thật lung linh. Mình đã chọn Vue 3 kết hợp với Pinia để quản lý dữ liệu một cách gọn gàng, và Monaco Editor để mang lại trải nghiệm soạn thảo code giống hệt như VS Code yêu thích của bạn! Còn Tailwind CSS thì khỏi phải nói, giúp giao diện trở nên đẹp mắt và responsive (thân thiện với mọi kích thước màn hình) chỉ trong nháy mắt.Đây là một đoạn code Vue siêu đơn giản để tích hợp Monaco Editor:<template> <MonacoEditor v-model="code" :theme="isDark ? 'vs-dark' : 'vs-light'" language="go" /></template><script setup>import MonacoEditor from '@monaco-editor/vue'import { ref } from 'vue' // Đừng quên import ref nhé!const code = ref(`package main\n\nimport "fmt"\n\nfunc main() {\n\tfmt.Println("Xin chào thế giới!")\n}`)</script> Đơn giản không? Cứ như bạn đang 'kêu gọi' một trình soạn thảo code chuyên nghiệp vào ứng dụng của mình vậy!<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/frontend_vue_monaco.png' alt='Giao diện Frontend với Monaco Editor và Vue.js'> Menu Các Ví Dụ Code Go Có SẵnĐể các bạn không phải vò đầu bứt tóc nghĩ xem nên viết gì, mình đã 'khéo léo' thêm một menu thả xuống với các ví dụ code Go có sẵn cực kỳ thú vị như:Tính dãy Fibonacci (số thỏ đẻ con kiểu gì?)Số nguyên Peano (một cách định nghĩa số học rất 'hack não'!)Kiểm tra số nguyên tố (ai là số độc thân?)Thuật toán Bubble Sort (sắp xếp 'nổi bọt' như thế nào?)Tính toán số Pi (con số 'thần thánh' trong hình học!)<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/go_examples_dropdown.png' alt='Menu các ví dụ code Go có sẵn'> Bảo Mật Hệ Thống: Không Lo 'Phá Hoại'Khi cho phép người dùng chạy code trên máy chủ của mình, vấn đề bảo mật là CỰC KỲ QUAN TRỌNG. Lỡ người dùng tinh nghịch viết một đoạn code 'vô tận' hoặc có ý đồ xấu thì sao? Đừng lo, mình đã áp dụng vài 'chiêu' để đảm bảo 'sân chơi' này luôn an toàn:Hẹn giờ (Timeout) bằng context.WithTimeout: Giống như một chiếc đồng hồ đếm ngược vậy đó. Nếu code chạy quá thời gian quy định, nó sẽ bị 'ngắt' ngay lập tức. Bye bye vòng lặp vô tận!Giới hạn tài nguyên Docker (--memory, --cpus): Đảm bảo mỗi 'chiếc hộp' Docker chỉ được dùng một lượng tài nguyên nhất định (RAM, CPU), tránh việc một đoạn code 'đói' tài nguyên làm ảnh hưởng đến cả hệ thống.Giới hạn kích thước đầu ra/lỗi: Tránh trường hợp code in ra hàng tỉ dòng chữ làm 'ngập lụt' hệ thống.Xác thực cấu trúc JSON đầu vào: Đảm bảo chỉ những yêu cầu hợp lệ mới được xử lý, tránh các kiểu tấn công khai thác lỗi định dạng.<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/code_security_sandbox.png' alt='Các biện pháp bảo mật khi chạy code người dùng'> Tương Lai 'Rạng Ngời' của Go PlaygroundDự án này được xây dựng với tư duy mở rộng nên vẫn còn rất nhiều tiềm năng để 'phát tướng' đó các bạn:Thêm hỗ trợ cho các ngôn ngữ khác như JavaScript, Java, Python, v.v. (tưởng tượng có một playground đa ngôn ngữ thì sao nhỉ?).Cho phép nhập liệu từ bàn phím (stdin) trong Docker để code có thể tương tác với người dùng.Tạo tài khoản người dùng và lưu lại lịch sử các phiên code (để khoe thành tích với bạn bè!).Sử dụng WebSocket cho các luồng biên dịch thời gian thực (nhìn code chạy 'từng bước' luôn thì sao ta?).<img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/future_roadmap_ideas.png' alt='Những ý tưởng phát triển trong tương lai'> Trải Nghiệm Ngay và Lời KếtThôi nói nhiều làm gì, tự tay trải nghiệm là thích nhất! Các bạn có thể ghé thăm 'sân chơi' của chúng ta tại đây:<a href="https://bit.ly/4iFifWT">🌐 Go Playground Trực Tuyến</a>Đây thực sự là một dự án cực kỳ thú vị, kết hợp giữa hiệu năng backend, trải nghiệm người dùng frontend mượt mà, và sự tự động hóa thần kỳ của DevOps. Một 'sân chơi' hoàn hảo để các bạn vừa thử nghiệm Go, vừa xây dựng một công cụ lập trình 'full-stack' hoàn chỉnh.Đừng ngần ngại fork (tạo bản sao) và mở rộng dự án này nhé! Hy vọng bài viết này sẽ giúp ích cho hành trình học hỏi của các bạn.Mã nguồn đầy đủ có ở đây nha: <a href="https://github.com/gedons/go_Repl">🔗 Github Repo</a><img src='https://truyentranh.letranglan.top/api/v1/proxy?url=https://i.imgur.com/happy_gopher_coding.png' alt='Kết luận về dự án Go Playground'>
Khám phá Hướng dẫn toàn diện về AWS Cost Optimization Hub, dịch vụ mạnh mẽ giúp bạn tiết kiệm đáng kể chi phí đám mây. Tìm hiểu cách xác định các cơ hội tối ưu hóa và giảm hóa đơn AWS của bạn một cách hiệu quả.
Tưởng tượng dữ liệu GenAI của bạn như một cái gara đầy hộp lộn xộn? Đừng lo! Bài viết này là 'bản đồ kho báu' giúp bạn từng bước tổ chức, làm sạch và biến dữ liệu thô thành tài nguyên 'siêu chất' trên AWS, sẵn sàng cho các mô hình AI bùng nổ. Cùng tìm hiểu cách 'biến hình' dữ liệu cực vui!
Khám phá AWS DeepRacer - chiếc xe đua AI 1/18 cùng mô phỏng 3D giúp bạn học Machine Learning và Reinforcement Learning (RL) một cách vui nhộn, thực tế. Bắt đầu hành trình AI của bạn ngay!
Hướng dẫn chi tiết cách xây dựng bot tạo blog tự động bằng AI và các dịch vụ serverless của AWS như Amazon Bedrock, Lambda, S3 và API Gateway. Tìm hiểu kiến trúc không máy chủ và tạo nội dung thông minh.