Terraform을 이용한 AWS Bedrock으로 Claude 3.5-Sonnet 서빙 해보기

최근 인공지능(AI) 모델을 활용한 서비스가 늘어나면서, 이를 효과적으로 배포하고 관리할 수 있는 인프라가 중요해지고 있다.
특히 AWS Bedrock을 활용한 AI 모델 서빙은 매우 유용한 방식이다.
이 글에서는 Terraform을 사용하여 AWS API GatewayLambda를 통해 AWS Bedrock의 Claude 3.5 모델을 서빙하는 아키텍처를 구축하는 방법을 설명한다.


 

1. 아키텍처

AWS에서 AI 모델을 서빙하는 인프라는 다양한 구성 요소들이 협력하여 동작한다. 이번 프로젝트에서는 AWS API Gateway, Lambda, 그리고 AWS Bedrock Claude 3.5 모델을 사용하여 AI 서빙 시스템을 구축한다. 아래는 해당 아키텍처의 주요 구성 요소이다.

  • API Gateway: 외부에서 HTTP 요청을 수신하고, 이를 Lambda 함수로 전달하는 역할을 한다.
  • Lambda 함수: API Gateway로부터 전달받은 요청을 처리하고, AWS Bedrock의 Claude 3.5 모델에 예측 요청을 보낸다.
  • AWS Bedrock: Claude 3.5 모델을 사용해 입력된 프롬프트에 대한 예측 결과를 반환한다.
  • CloudWatch Logs: Lambda 함수의 실행 중 발생하는 로그를 저장하여 디버깅 및 모니터링을 가능하게 한다.
  • IAM Role: 각 서비스가 상호작용할 수 있는 권한을 제공하며, 특히 API Gateway와 Lambda 함수, Lambda와 Bedrock 모델 간의 권한을 관리한다.

 

2. 시퀀스 다이어그램

다음은 사용자가 API Gateway에 요청을 보낸 후, AWS Bedrock 모델을 통해 응답을 받는 과정의 시퀀스를 시퀀스 다이어그램으로 표현한 것이다.

시퀀스 설명:

  1. 사용자는 API Gateway에 프롬프트를 포함한 요청을 보낸다.
  2. API Gateway는 해당 요청을 Lambda 함수에 전달한다.
  3. Lambda 함수AWS Bedrock Claude 3.5 모델을 호출하여 AI 예측 요청을 보낸다.
  4. Bedrock 모델은 예측 결과를 Lambda 함수에 반환한다.
  5. Lambda 함수는 실행 중 발생한 로그를 CloudWatch Logs에 기록한다.
  6. Lambda 함수는 최종 예측 결과를 API Gateway로 전달하고, API Gateway는 그 결과를 사용자에게 반환한다.

 

3. 파일 구조

Terraform 프로젝트의 파일 구조는 다음과 같다. 각 디렉토리와 파일은 해당 인프라 구성 요소를 정의하고 관리하는데 사용된다.

.
├── main.tf                     # 서브모듈을 호출하는 루트 모듈
├── modules
│   ├── api_gateway
│   │   ├── main.tf             # API Gateway와 Lambda 통합 설정
│   │   ├── outputs.tf          # API Gateway의 출력값
│   │   └── variables.tf        # API Gateway 모듈의 변수 설정
│   ├── iam
│   │   ├── main.tf             # Lambda를 위한 IAM 역할 및 정책 설정
│   │   ├── outputs.tf          # IAM 역할의 출력값
│   │   └── variables.tf        # IAM 역할 모듈의 변수 설정
│   └── lambda
│       ├── main.tf             # Lambda 함수 정의
│       ├── outputs.tf          # Lambda 함수의 출력값
│       └── variables.tf        # Lambda 모듈의 변수 설정
├── src
│   ├── inference.py             # Lambda 함수 소스 코드
│   └── lambda_function_payload.zip # Lambda 함수로 배포될 압축 파일
└── README.md                   # 프로젝트 설명서

 

4. 각 파일에 대한 코드와 설명

해당 프로젝트의 모든 코드는 여기 에서 확인할 수 있다.

1) root main.tf

루트 모듈에서 IAM Role, Lambda 함수, 그리고 API Gateway 모듈을 각각 호출하고 연결하는 역할을 한다.

provider "aws" {
  region = "ap-northeast-2"
}

# IAM 모듈 호출
module "iam" {
  source = "./modules/iam"
}

# Lambda 모듈 호출 (IAM 역할을 참조)
module "lambda" {
  source        = "./modules/lambda"
  role_arn      = module.iam.lambda_execution_role_arn
  model_id      = "anthropic.claude-3-5-sonnet-20240620-v1:0"
}

# API Gateway 모듈 호출
module "api_gateway" {
  source     = "./modules/api_gateway"
  lambda_arn = module.lambda.lambda_arn
}

# API Gateway 엔드포인트 출력
output "api_endpoint" {
  value = module.api_gateway.api_endpoint
}

2) Lambda 모듈 (modules/lambda/main.tf)

Lambda 함수의 정의와 AWS Bedrock 모델을 호출하는 역할을 한다. Lambda 코드가 포함된 ZIP 파일 경로도 여기서 설정된다.

resource "aws_lambda_function" "llm_inference" {
  function_name = "llm_inference"
  role          = var.role_arn
  handler       = "inference.handler"
  runtime       = "python3.9"
  filename      = "${path.module}/../../src/lambda_function_payload.zip"
  timeout       = 30

  environment {
    variables = {
      MODEL_ID = var.model_id
    }
  }
}

3) IAM 모듈 (modules/iam/main.tf)

API Gateway와 Lambda 함수 간의 권한을 설정하고, Lambda가 Bedrock 모델을 호출할 수 있도록 한다.

resource "aws_iam_role" "lambda_execution_role" {
  name = "lambda_execution_role_jjaegii"
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [{
      Action    = "sts:AssumeRole",
      Effect    = "Allow",
      Principal = {
        Service = "lambda.amazonaws.com"
      }
    }]
  })
}

resource "aws_iam_role_policy" "lambda_policy" {
  role = aws_iam_role.lambda_execution_role.id
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect   = "Allow",
        Action   = [
          "bedrock:InvokeModel",
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ],
        Resource = "*"
      }
    ]
  })
}

 

2) variables.tf 설명

variables.tf 파일은 Terraform 모듈에서 사용되는 입력 변수를 정의한다. 이 변수를 통해 모듈의 동작을 제어할 수 있으며, 각 리소스에 맞는 값을 모듈 호출 시 전달할 수 있다.

  • 목적: 변수 파일은 모듈 내에서 재사용성을 높이고, 환경에 따라 동적으로 값을 변경할 수 있게 한다. 예를 들어, Lambda 함수의 역할(role_arn)이나 Bedrock 모델 ID(model_id) 같은 값들은 프로젝트에 따라 다를 수 있는데, 이를 변수로 정의하면 나중에 쉽게 수정할 수 있다.

예시: Lambda 모듈의 variables.tf

variable "role_arn" {
  description = "IAM 역할의 ARN"
  type        = string
}

variable "model_id" {
  description = "Bedrock 모델 ID"
  type        = string
  default     = "anthropic.claude-3-5-sonnet-20240620-v1:0"  # 기본 모델 ID
}
  • role_arn: Lambda 함수가 사용할 IAM 역할의 ARN을 받는다. 이 값은 iam 모듈에서 생성된 역할 ARN을 참조한다.
  • model_id: AWS Bedrock 모델의 ID로, 기본값으로 Claude 3.5 모델을 사용한다. 이 값은 필요에 따라 다른 Bedrock 모델 ID로 변경할 수 있다.

이 변수들은 Terraform 모듈을 호출할 때 다른 값으로 덮어쓸 수 있다. 예를 들어, 다른 Bedrock 모델을 사용하려면 model_id 값을 변경할 수 있다.

variables.tf의 이점:

  • 유연성: 변수 파일을 통해 코드를 재사용할 수 있고, 다양한 환경에 맞게 빠르게 변경할 수 있다.
  • 가독성: 코드에서 하드코딩된 값을 줄이고, 변수를 통해 가독성을 높인다.
  • 모듈화: 변수 파일은 모듈화된 코드를 쉽게 유지 관리할 수 있도록 돕는다.

 

3) outputs.tf 설명

outputs.tf 파일은 Terraform에서 모듈이 생성한 리소스의 중요한 정보를 외부로 내보내는 역할을 한다. 예를 들어, Lambda 함수의 ARN이나 API Gateway의 엔드포인트 URL을 출력할 수 있다.

  • 목적: 모듈이 생성한 리소스를 다른 모듈이나 외부에서 참조할 수 있도록 중요한 정보를 출력하는 데 사용된다. 또한, Terraform 명령이 완료된 후 출력되는 정보를 통해, 사용자에게 유용한 정보를 제공한다.

예시: Lambda 모듈의 outputs.tf

output "lambda_arn" {
  description = "Lambda 함수의 ARN"
  value       = aws_lambda_function.llm_inference.arn
}
  • lambda_arn: Lambda 함수가 생성된 후, 해당 함수의 ARN(Amazon Resource Name)을 출력한다. 이 값은 다른 모듈(API Gateway 등)에서 Lambda 함수를 참조할 때 사용된다.

예시: API Gateway 모듈의 outputs.tf

output "api_endpoint" {
  description = "API Gateway의 엔드포인트 URL"
  value       = aws_apigatewayv2_api.http_api.api_endpoint
}
  • api_endpoint: API Gateway가 배포된 후, 외부에서 접근할 수 있는 API 엔드포인트 URL을 출력한다. 이 엔드포인트를 통해 사용자는 API에 요청을 보낼 수 있다.

outputs.tf의 이점:

  • 참조 가능성: 출력된 값을 다른 모듈이나 외부에서 참조할 수 있어, 모듈 간의 의존성을 쉽게 관리할 수 있다.
  • 사용자 정보 제공: Terraform 실행 후, 출력된 정보를 통해 사용자는 인프라의 상태나 중요한 리소스 정보(API URL, Lambda ARN 등)를 빠르게 확인할 수 있다.
  • 연동성: 출력된 값은 다른 Terraform 코드나 외부 시스템에서 사용할 수 있어, 모듈 간의 연동을 간소화한다.

 

5. API 테스트

배포가 완료되면 API Gateway 엔드포인트가 출력된다. 이를 통해 Bedrock 모델에 예측 요청을 보낼 수 있다.

테스트 방법

API Gateway URL을 사용하여 POST 요청을 보낼 수 있다. 아래 예시는 curl 명령어를 사용한 테스트 방법이다.

curl -X POST https://{api_endpoint} \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Explain the theory of relativity."}'

이 요청은 상대성 이론에 대한 설명을 요청하는 예제이다. AWS Bedrock의 Claude 3.5 모델이 요청을 처리하고 결과를 반환하게 된다.


 

결론

이번 글에서는 Terraform을 사용하여 AWS API GatewayLambda, AWS Bedrock 모델을 연동하여 AI 예측 시스템을 구축하는 과정을 설명했다. CloudWatch Logs를 통해 각 서비스의 로그를 관리할 수 있으며, IAM Role을 통해 각 리소스 간의 접근 권한을 설정했다.

이 인프라는 AI 기반 서비스를 위한 유연하고 확장 가능한 아키텍처로, 다양한 상황에서 응용될 수 있다. Terraform을 사용하여 인프라를 자동화하고 관리함으로써, 개발자는 보다 쉽게 서비스를 배포하고 관리할 수 있다.