백엔드 아키텍처는 모두 구현이 완료되었고, 프론트 및 로그인 시스템은 아직 로컬과 Cognito가 혼용되어 사용되고 있다
본격적으로 온전한 클라우드 아키텍처를 만들기 전에, Bedrock FM 대신 완성된 에이전트를 연결하는 작업을 수행하자.
tarotchat-sendmessage
Bedrock Agent를 사용하도록 sendMessage 함수를 업데이트한다.
model = ChatBedrock(
model_id="anthropic.claude-3-haiku-20240307-v1:0",
streaming=True,
model_kwargs={
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 3000,
"temperature": 0.1
}
)
# (중간 생략: 웰컴 메시지 및 사용자 메시지를 context로 추가)
response = model.invoke(messages)
# Bedrock Agent 호출
agent_response = bedrock_agent_runtime.invoke_agent(
agentId='XXXXXXX', # Agent ID
agentAliasId='XXXXXXXX', # Alias ID
sessionId=session_id,
inputText=user_message
)
Lambda가 이제 FM에 대한 권한 대신 Agent에 대한 권한을 갖도록 InvokeAgent 정책을 추가한다.

이어서 정적 콘텐츠들을 버킷에 업로드하고 CDN으로 Cloudfront를 채택하였다.
퍼블릭 액세스가 가능한 요소를 최소한으로 만들기 위해 버킷을 두 개로 분리하였다.
아이콘 파일에 대해서만 불가피하게 퍼블릭 액세스를 허용하고, 실제 호스팅에 필요한 파일들은 액세스가 차단된 별도의 버킷에 올린 후 버킷 정책을 편집하는 접근을 택했다.
먼저 호스팅을 위한 버킷을 생성하고,버킷에 웹 html, css 파일을 업로드하였다.
이때 각 파일이 올바른 형식으로 인식되는지 반드시 확인하자. 잘못된 형식으로 업로드될 경우 파일이 아예 열리지 않는다.
application/javascripttext/csstext/html
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontOAC",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yihoon-tarotchat-hosting/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::*******:distribution/**********"
}
}
}
]
}
다음으로 이미지들을 제공하기 위한 별도의 퍼블릭 버킷을 만들었다. 해당 버킷에 아이콘들을 업로드하였다.
Cloudfront의 사악한 요금 체계는 익히 들었지만 이 정도 서비스에 트래픽이 그렇게 많을 것 같지도 않고, S3와 연결이 가장 편한 CDN이라고 해서 그대로 채택하였다.
Cloudfront 배포를 다음과 같은 옵션으로 생성하였다:


서비스에 사용한 REST API는 모든 리소스에 대해 프록시 통합이 설정되어 있다. 따라서 응답 포맷은 모두 Lambda에서 컨트롤해야 한다. 연결된 모든 함수에 대해 Cloudfront에서 넘어온 요청만을 처리할 수 있도록 아래와 같이 응답 포맷의 Access Contorl Allow Orign 값을 정리하였다. (기존 값은 포트 3000)
return {
'statusCode': 200,
'body': json.dumps(sessions),
'headers': {
'Access-Control-Allow-Origin': 'https://**********.cloudfront.net',
'Access-Control-Allow-Headers': 이하 생략...
}
}
서비스 호스팅은 사실 특별히 고려할 요소가 많지 않은 반면 로그인 아키텍처를 호스팅하는데는 꽤 많은 노력과 고민이 들어갔다.
해당 내용을 이어서 다뤄 보겠다.