Sử dụng cơ sở hạ tầng dưới dạng code tạo sinh với Application Composer

bởi Julian Wood | ngày 16 tháng 1 năm 2024 | in Amazon CodeWhisperer, AWS Amplify, AWS Application Composer, Serverless | Permalink |  Share

Bài viết này được viết bởi Anna Spysz, Frontend Engineer, AWS Application Composer

AWS Application Composer đã ra mắt trong AWS Management Console cách đây một năm và hiện đã mở rộng sang VS Code IDE như một phần của AWS Toolkit.  Điều này bao gồm quyền truy cập vào đối tác generative AI giúp bạn viết cơ sở hạ tầng dưới dạng mã (IaC) cho tất cả hơn 1100 tài nguyên AWS CloudFormation mà Application Composer hỗ trợ.

Tổng quan

Application Composer cho phép bạn tạo các mẫu IaC bằng cách kéo và thả các thẻ trên khung vẽ ảo. Chúng đại diện cho các tài nguyên CloudFormation mà bạn có thể kết nối với nhau để tạo quyền và tài liệu tham khảo. Với sự hỗ trợ cho hơn 1100 tài nguyên mà CloudFormation cho phép, giờ đây bạn có thể xây dựng bằng mọi thứ từ AWS Amplify đến AWS X-Ray.

Trước đây, tài nguyên CloudFormation tiêu chuẩn chỉ có cấu hình cơ bản. Theo mặc định, việc thêm Amplify App resource sẽ dẫn đến cấu hình sau:

MyAmplifyApp:

    Type: AWS::Amplify::App

    Properties:

      Name: <String>

Và trong bảng điều khiển:

AWS App Composer trong bảng điều khiển

Bây giờ, Application Composer trong IDE sử dụng generative AI để tạo các cấu hình dành riêng cho tài nguyên với các biện pháp bảo vệ như xác thực dựa trên lược đồ CloudFormation để đảm bảo các giá trị hợp lệ. Khi làm việc trên mẫu CloudFormation hoặc AWS Serverless Application Model (AWS SAM) trong VS Code, bạn có thể đăng nhập bằng Builder ID của mình và tạo nhiều cấu hình được đề xuất trong Application Composer. Dưới đây là ví dụ về cấu hình do AI tạo cho loại AWS::Amplify::App:

AI đã  tạo cấu hình cho loại Amplify App

Những đề xuất này dành riêng cho loại tài nguyên và được bảo vệ bằng cách kiểm tra lược đồ CloudFormation để đảm bảo các giá trị hợp lệ hoặc phần giữ chỗ hữu ích. Sau đó, bạn có thể chọn, sử dụng và sửa đổi các đề xuất cho phù hợp với nhu cầu của mình.

Bây giờ bạn đã biết cách tạo một ví dụ cơ bản từ một tài nguyên, nhưng hãy xem việc xây dựng đầy đủ một ứng dụng với sự trợ giúp do AI-generated đề xuất. Ví dụ này sẽ tạo lại một ứng dụng không có máy chủ từ hướng dẫn của Serverless Land, “Use GenAI capabilities to build a chatbot”  bằng cách sử dụng Application Composer và các đề xuất mã được tạo ra bởi AI-powered.

Bắt đầu với AWS Toolkit trong VS Code

Nếu chưa có tiện ích mở rộng AWS Toolkit, bạn có thể tìm thấy tiện ích này tại tab Extensions trong VS Code. Hãy cài đặt hoặc cập nhật lên ít nhất phiên bản 2.1.0 để màn hình hiển thị Amazon Q và Application Composer:

Amazon Q và Application Composer

Tiếp theo, để bật đề xuất mã AI-powered, bạn phải bật Amazon CodeWhisperer bằng ID Builder của mình. Cách dễ nhất là mở Amazon Q chat và chọn Authenticate. Tại màn hình tiếp theo, chọn tùy chọn Builder ID, sau đó đăng nhập bằng Builder ID của bạn.

Bật Amazon CodeWhisperer dùng Builder ID của bạn

Sau khi đăng nhập, thấy kết nối của bạn sẽ được xuất hiện trong VS Code toolkit panel:

Kết nối trong VS Code toolkit panel

Xây dựng với Application Composer

Với bộ toolkit được cài đặt và kết nối với Builder ID của bạn, vậy nên bạn sẽ  sẵn sàng bắt đầu xây dựng. 

  1. Trong không gian làm việc mới, hãy tạo một thư mục cho ứng dụng và một tệp template.yaml trống. 
  2. Mở tệp này và khởi chạy Application Composer bằng cách chọn biểu tượng ở trên cùng bên phải.

Khởi chạy Application Composer

Tất cả hướng dẫn sẽ xoay quanh sơ đồ kiến ​​trúc này:

Sơ đồ kiến ​​trúc gốc

Đầu tiên, thêm các dịch vụ vào sơ đồ để phác thảo kiến ​​trúc ứng dụng, đồng thời tạo ra mẫu CloudFormation có thể triển khai: 

  1. Từ danh sách Enhanced components, hãy kéo Lambda function và một Lambda layer vào. 
  2. Double-click vào tài nguyên Function để chỉnh sửa thuộc tính của nó. Đổi tên Logical ID của Lambda function thành LexGenAIBotLambda. 
  3. Thay đổi đường dẫn Source thành src/LexGenAIBotLambda và Runtime thành Python. 
  4. Thay đổi giá trị handler thành TextGeneration.lambda_handler và chọn Save
  5. Double-click vào tài nguyên Layer để chỉnh sửa thuộc tính của nó. Đổi tên lớp Boto3Layer và thay đổi phương pháp xây dựng của nó thành Python. Thay đổi đường dẫn Source của nó thành src/Boto3PillowPyshorteners.zip. 
  6. Cuối cùng, kết nối lớp với hàm để thêm tham chiếu giữa chúng. Canvas của bạn trông như thế này:

App Composer canvas của bạn

Tệp template.yaml hiện đã được cập nhật để bao gồm các tài nguyên đó. Trong thư mục nguồn, bạn có thể thấy một số tệp chức năng được tạo. Bạn sẽ thay thế chúng bằng chức năng hướng dẫn và các lớp sau. 

Ở bước đầu tiên, bạn đã thêm một số tài nguyên và Application Composer đã tạo ra IaC bao gồm các thiết lập mặc định tuân thủ các quy tắc tốt nhất. Tiếp theo, bạn sẽ sử dụng các thành phần tiêu chuẩn của CloudFormation. 

Sử dụng AI cho các thành phần tiêu chuẩn 

Bắt đầu bằng cách sử dụng thanh tìm kiếm để tìm kiếm và thêm một số thành phần tiêu chuẩn cần thiết cho ứng dụng của bạn.

Tìm kiếm và thêm các thành phần Tiêu chuẩn

  1. Trong thanh tìm kiếm, nhập “lambda” và thêm loại tài nguyên AWS::Lambda::Permission vào canvas. 
  2. Nhập “iam” vào thanh tìm kiếm và thêm loại AWS::IAM::Policy. 
  3. Thêm hai tài nguyên thuộc loại AWS::IAM::Role.

Ứng dụng của bạn bây giờ sẽ như thế này:

Canvas được cập nhật

Một số tài nguyên tiêu chuẩn có tất cả các giá trị mặc định mà bạn cần. Ví dụ: khi bạn thêm tài nguyên AWS::Lambda::Permission, hãy thay thế các giá trị tạm thời bằng:

FunctionName: !Ref LexGenAIBotLambda

Action: lambda:InvokeFunction

Principal: lexv2.amazonaws.com

Các tài nguyên khác, chẳng hạn như IAM roles và IAM policy, có cấu hình cơ bản. Đây là nơi bạn có thể sử dụng trợ lý AI. Chọn một tài nguyên IAM role và chọn Generate suggestions để xem những gì trợ lý trí tuệ sinh ra.

Tạo Generate suggestions

Vì những đề xuất này được tạo bởi Mô hình ngôn ngữ lớn Large Language Model (LLM) nên chúng có thể khác nhau giữa mỗi lần tạo ra. Chúng được kiểm tra dựa trên lược đồ CloudFormation, nhằm đảm bảo tính hợp lệ và cung cấp một loạt cấu hình cho nhu cầu của bạn. 

Việc tạo các cấu hình khác nhau sẽ giúp bạn biết chính sách của tài nguyên sẽ trông như thế nào và thường cung cấp cho bạn các khóa để sau đó bạn có thể điền các giá trị bạn cần. Sử dụng các cài đặt sau cho từng tài nguyên, thay thế các giá trị được tạo nếu có.

  1. Double-click vào tài nguyên “Permission” để chỉnh sửa các thiết lập của nó. Thay đổi ID logical ID  của nó thành LexGenAIBotLambdaInvoke và thay đổi cấu hình tài nguyên của nó bằng cấu hình sau, sau đó chọn Save:

Action: lambda:InvokeFunction

FunctionName: !GetAtt LexGenAIBotLambda.Arn

Principal: lexv2.amazonaws.com

  1. Double-click vào tài nguyên “Role” để chỉnh sửa các thiết lập của nó. Thay đổi Logical ID của nó thành CfnLexGenAIDemoRole và thay đổi cấu hình tài nguyên  của nó bằng cấu hình sau, sau đó chọn Save:

AssumeRolePolicyDocument:

  Statement:

    – Action: sts:AssumeRole

      Effect: Allow

      Principal:

        Service: lexv2.amazonaws.com

  Version: ‘2012-10-17’

ManagedPolicyArns:

  – !Join

    – ”

    – – ‘arn:’

      – !Ref AWS::Partition

      – ‘:iam::aws:policy/AWSLambdaExecute’

  1. Double-click vào tài nguyên “Role2” để chỉnh sửa các thiết lập của nó. Thay đổi Logical ID của nó thành LexGenAIBotLambdaServiceRole và thay đổi cấu hình tài nguyên  của nó bằng cấu hình sau, sau đó chọn Save:

AssumeRolePolicyDocument:

  Statement:

    – Action: sts:AssumeRole

      Effect: Allow

      Principal:

        Service: lambda.amazonaws.com

  Version: ‘2012-10-17’

ManagedPolicyArns:

  – !Join

    – ”

    – – ‘arn:’

      – !Ref AWS::Partition

      – ‘:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole’

  1. Double-click vào tài nguyên “Policy” để chỉnh sửa các thiết lập của nó. Thay đổi Logical ID của nó thành LexGenAIBotLambdaServiceRoleDefaultPolicy và thay đổi cấu hình tài nguyên  của nó bằng cấu hình sau, sau đó chọn Save:

PolicyDocument:

  Statement:

    – Action:

        – lex:*

        – logs:*

        – s3:DeleteObject

        – s3:GetObject

        – s3:ListBucket

        – s3:PutObject

      Effect: Allow

      Resource: ‘*’

    – Action: bedrock:InvokeModel

      Effect: Allow

      Resource: !Join

        – ”

        – – ‘arn:aws:bedrock:’

          – !Ref AWS::Region

          – ‘::foundation-model/anthropic.claude-v2’

  Version: ‘2012-10-17’

PolicyName: LexGenAIBotLambdaServiceRoleDefaultPolicy

Roles:

  – !Ref LexGenAIBotLambdaServiceRole

  1. Sau khi bạn đã cập nhật thuộc tính của mỗi tài nguyên, bạn sẽ thấy các kết nối và nhóm được tạo tự động giữa chúng:

Kết nối và nhóm tự động

Để thêm bot Amazon Lex

  1. Trong bộ chọn tài nguyên, tìm kiếm và thêm loại AWS::Lex::Bot. Đây là một cơ hội khác để xem cấu hình mà AI đề xuất . 
  2. Thay đổi logical ID của bot Amazon Lex thành LexGenAIBot và cập nhật cấu hình của nó thành như sau:

DataPrivacy:

  ChildDirected: false

IdleSessionTTLInSeconds: 300

Name: LexGenAIBot

RoleArn: !GetAtt CfnLexGenAIDemoRole.Arn

AutoBuildBotLocales: true

BotLocales:

  – Intents:

      – InitialResponseSetting:

          CodeHook:

            EnableCodeHookInvocation: true

            IsActive: true

            PostCodeHookSpecification: {}

        IntentClosingSetting:

          ClosingResponse:

            MessageGroupsList:

              – Message:

                  PlainTextMessage:

                    Value: Hi there, I’m a GenAI Bot. How can I help you?

        Name: WelcomeIntent

        SampleUtterances:

          – Utterance: Hi

          – Utterance: Hey there

          – Utterance: Hello

          – Utterance: I need some help

          – Utterance: Help needed

          – Utterance: Can I get some help?

      – FulfillmentCodeHook:

          Enabled: true

          IsActive: true

          PostFulfillmentStatusSpecification: {}

        InitialResponseSetting:

          CodeHook:

            EnableCodeHookInvocation: true

            IsActive: true

            PostCodeHookSpecification: {}

        Name: GenerateTextIntent

        SampleUtterances:

          – Utterance: Generate content for

          – Utterance: ‘Create text ‘

          – Utterance: ‘Create a response for ‘

          – Utterance: Text to be generated for

      – FulfillmentCodeHook:

          Enabled: true

          IsActive: true

          PostFulfillmentStatusSpecification: {}

        InitialResponseSetting:

          CodeHook:

            EnableCodeHookInvocation: true

            IsActive: true

            PostCodeHookSpecification: {}

        Name: FallbackIntent

        ParentIntentSignature: AMAZON.FallbackIntent

    LocaleId: en_US

    NluConfidenceThreshold: 0.4

Description: Bot created demonstration of GenAI capabilities.

TestBotAliasSettings:

  BotAliasLocaleSettings:

    – BotAliasLocaleSetting:

        CodeHookSpecification:

          LambdaCodeHook:

            CodeHookInterfaceVersion: ‘1.0’

            LambdaArn: !GetAtt LexGenAIBotLambda.Arn

        Enabled: true

      LocaleId: en_US

  1. chọn Save trên tài nguyên.

Khi tất cả các tài nguyên của bạn được cấu hình, ứng dụng của bạn sẽ nhìn như thế này:

Canvas mới được tạo bởi AI

Thêm mã chức năng và triển khai 

Khi kiến ​​trúc của bạn được xác định, hãy xem xét và tinh chỉnh tệp template.yaml của bạn. Để biết tham khảo chi tiết và đảm bảo tất cả các giá trị của bạn đều đúng, truy cập vào GitHub repository và kiểm tra so sánh với tệp template.yaml. 

  1. Sao chép Lambda layer trực tiếp từ kho, và thêm vào ./src/Boto3PillowPyshorteners.zip. 
  2. Trong thư mục .src/, đổi tên handler.py được tạo ra thành TextGeneration.py. Bạn cũng có thể xóa bỏ bất kỳ tệp không cần thiết nào. 
  3. Mở TextGeneration.py và thay thế mã tạm bằng mã sau:

import json

import boto3

import os

import logging

from botocore.exceptions import ClientError

LOG = logging.getLogger()

LOG.setLevel(logging.INFO)

region_name = os.getenv(“region”, “us-east-1”)

s3_bucket = os.getenv(“bucket”)

model_id = os.getenv(“model_id”, “anthropic.claude-v2”)

# Bedrock client used to interact with APIs around models

bedrock = boto3.client(service_name=”bedrock”, region_name=region_name)

# Bedrock Runtime client used to invoke and question the models

bedrock_runtime = boto3.client(service_name=”bedrock-runtime”, region_name=region_name)

def get_session_attributes(intent_request):

    session_state = intent_request[“sessionState”]

    if “sessionAttributes” in session_state:

        return session_state[“sessionAttributes”]

    return {}

def close(intent_request, session_attributes, fulfillment_state, message):

    intent_request[“sessionState”][“intent”][“state”] = fulfillment_state

    return {

        “sessionState”: {

            “sessionAttributes”: session_attributes,

            “dialogAction”: {“type”: “Close”},

            “intent”: intent_request[“sessionState”][“intent”],

        },

        “messages”: [message],

        “sessionId”: intent_request[“sessionId”],

        “requestAttributes”: intent_request[“requestAttributes”]

        if “requestAttributes” in intent_request

        else None,

    }

def lambda_handler(event, context):

    LOG.info(f”Event is {event}”)

    accept = “application/json”

    content_type = “application/json”

    prompt = event[“inputTranscript”]

    try:

        request = json.dumps(

            {

                “prompt”: “\n\nHuman:” + prompt + “\n\nAssistant:”,

                “max_tokens_to_sample”: 4096,

                “temperature”: 0.5,

                “top_k”: 250,

                “top_p”: 1,

                “stop_sequences”: [“\\n\\nHuman:”],

            }

        )

        response = bedrock_runtime.invoke_model(

            body=request,

            modelId=model_id,

            accept=accept,

            contentType=content_type,

        )

        response_body = json.loads(response.get(“body”).read())

        LOG.info(f”Response body: {response_body}”)

        response_message = {

            “contentType”: “PlainText”,

            “content”: response_body[“completion”],

        }

        session_attributes = get_session_attributes(event)

        fulfillment_state = “Fulfilled”

        return close(event, session_attributes, fulfillment_state, response_message)

    except ClientError as e:

        LOG.error(f”Exception raised while execution and the error is {e}”)

  1. Để triển khai cơ sở hạ tầng, hãy quay lại tiện ích mở rộng App Composer và chọn biểu tượng Sync. Theo các hướng dẫn AWS SAM được hướng dẫn để hoàn tất quá trình triển khai.

Đồng bộ hoá App Composer

Sau khi thông báo SAM Sync thành công, hãy điều hướng tới CloudFormation trong AWS Management Console để xem các tài nguyên mới được tạo. Để tiếp tục xây dựng chatbot, hãy làm theo phần còn lại của tutorial

Kết luận 

Bài viết này trình bày cách CloudFormation do AI tạo ra có thể hợp lý hóa quy trình làm việc của bạn trong Application Composer, nâng cao hiểu biết của bạn về cấu hình tài nguyên và tăng tốc quá trình phát triển. Như mọi khi, hãy tuân thủ AWS Responsible AI Policy khi sử dụng các tính năng này.

Leave a comment