Ruby Lambda 함수용 레이어 작업
Ruby Lambda 함수용 레이어 작업
Lambda 레이어를 사용해 여러 함수에서 재사용하려는 코드와 의존성을 패키징하세요. 레이어에는 보통 라이브러리 의존성, 커스텀 런타임, 구성 파일이 들어 있습니다. 레이어를 만드는 과정은 크게 세 단계입니다.
본문
- 레이어 콘텐츠를 패키징합니다. 즉, 함수에서 사용할 의존성을 담은
.zip파일 아카이브를 만듭니다. - Lambda에서 레이어를 생성합니다.
- 함수에 레이어를 추가합니다.
이 페이지의 내용:
- 레이어 콘텐츠 패키징
- Lambda에서 레이어 생성
- 함수에서 레이어의 gem 사용
- 함수에 레이어 추가
- 샘플 앱
레이어 콘텐츠 패키징
레이어를 만들려면 패키지를 다음 요구 사항을 충족하는 .zip 파일 아카이브로 묶으세요.
- Lambda 함수에 사용할 계획인 것과 같은 Ruby 버전으로 레이어를 만드세요. 예를 들어 Ruby 4.0용으로 레이어를 만든다면 함수에도 Ruby 4.0 런타임을 사용하세요.
- 레이어의
.zip파일은 다음 디렉터리 구조 중 하나를 사용해야 합니다.ruby/gems/x.x.x(x.x.x는 Ruby 버전, 예:3.4.0)ruby/lib- 자세한 내용은 '각 Lambda 런타임의 레이어 경로' 문서를 참고하세요.
- 레이어의 패키지는 Linux와 호환되어야 합니다. Lambda 함수는 Amazon Linux에서 실행됩니다.
서드파티 Ruby gem이나 자체 Ruby 모듈·클래스를 담는 레이어를 만들 수 있습니다. 인기 있는 Ruby gem 상당수에는 Lambda Linux 환경용으로 컴파일해야 하는 네이티브 확장(C 코드)이 들어 있습니다.
순수 Ruby gem은 Ruby 코드만 담고 있어 컴파일이 필요하지 않습니다. 이런 gem은 패키징이 간단하고 여러 플랫폼에서 작동합니다.
레이어에 포함할 순수 Ruby gem을 지정하는 Gemfile을 만듭니다.
source 'https://rubygems.org'
gem 'tzinfo'
Bundler를 사용해 gem을 vendor/bundle 디렉터리에 설치합니다.
bundle config set --local path vendor/bundle
bundle install
설치된 gem을 Lambda가 요구하는 디렉터리 구조(ruby/gems/3.4.0)로 복사합니다.
mkdir -p ruby/gems/3.4.0
cp -r vendor/bundle/ruby/3.4.0*/* ruby/gems/3.4.0/
레이어 콘텐츠를 압축합니다.
zip -r layer.zip ruby/
Compress-Archive -Path .\ruby -DestinationPath .\layer.zip
.zip 파일의 디렉터리 구조는 다음과 같아야 합니다.
ruby/
└── gems/
└── 3.4.0/
├── gems/
│ ├── concurrent-ruby-1.3.5/
│ └── tzinfo-2.0.6/
├── specifications/
├── cache/
├── build_info/
└── (other bundler directories)
함수 코드에서 각 gem을 개별적으로 require 해야 합니다. bundler/setup이나 Bundler.require는 사용할 수 없습니다. 자세한 내용은 '함수에서 레이어의 gem 사용'을 참고하세요.
인기 있는 Ruby gem에는 대상 플랫폼용으로 컴파일해야 하는 네이티브 확장(C 코드)이 들어 있습니다. 네이티브 확장이 있는 인기 gem으로는 nokogiri, pg, mysql2, sqlite3, ffi 등이 있습니다. 이 gem들은 Lambda 런타임과 호환되는 Linux 환경에서 빌드해야 합니다.
Gemfile을 만듭니다.
source 'https://rubygems.org'
gem 'nokogiri'
gem 'httparty'
Docker를 사용해 Lambda와 호환되는 Linux 환경에서 gem을 빌드합니다. Dockerfile에 AWS 베이스 이미지를 지정합니다.
FROM public.ecr.aws/lambda/ruby:3.4
# Copy Gemfile
COPY Gemfile ./
# Install system dependencies for native extensions
RUN dnf update -y && \
dnf install -y gcc gcc-c++ make
# Configure bundler and install gems
RUN bundle config set --local path vendor/bundle && \
bundle install
# Create the layer structure
RUN mkdir -p ruby/gems/3.4.0 && \
cp -r vendor/bundle/ruby/3.4.0*/* ruby/gems/3.4.0/
# Create the layer zip file
RUN zip -r layer.zip ruby/
이미지를 빌드하고 레이어를 추출합니다.
docker build -t ruby-layer-builder .
docker run --rm -v $(pwd):/output --entrypoint cp ruby-layer-builder layer.zip /output/
이렇게 하면 올바른 Linux 환경에서 gem이 빌드되고 layer.zip 파일이 로컬 디렉터리에 복사됩니다. .zip 파일의 디렉터리 구조는 다음과 같아야 합니다.
ruby/
└── gems/
└── 3.4.0/
├── gems/
│ ├── bigdecimal-3.2.2/
│ ├── csv-3.3.5/
│ ├── httparty-0.23.1/
│ ├── mini_mime-1.1.5/
│ ├── multi_xml-0.7.2/
│ ├── nokogiri-1.18.8-x86_64-linux-gnu/
│ └── racc-1.8.1/
├── build_info/
├── cache/
├── specifications/
└── (other bundler directories)
함수 코드에서 각 gem을 개별적으로 require 해야 합니다. bundler/setup이나 Bundler.require는 사용할 수 없습니다. 자세한 내용은 '함수에서 레이어의 gem 사용'을 참고하세요.
레이어에 필요한 디렉터리 구조를 만듭니다.
mkdir -p ruby/lib
ruby/lib 디렉터리에 Ruby 모듈을 만듭니다. 다음 예제 모듈은 주문에 필요한 정보가 포함되었는지 확인해 주문을 검증합니다.
require 'json'
module OrderValidator
class ValidationError < StandardError; end
def self.validate_order(order_data)
# Validates an order and returns formatted data
required_fields = %w[product_id quantity]
# Check required fields
missing_fields = required_fields.reject { |field| order_data.key?(field) }
unless missing_fields.empty?
raise ValidationError, "Missing required fields: #{missing_fields.join(', ')}"
end
# Validate quantity
quantity = order_data['quantity']
unless quantity.is_a?(Integer) && quantity > 0
raise ValidationError, 'Quantity must be a positive integer'
end
# Format and return the validated data
{
'product_id' => order_data['product_id'].to_s,
'quantity' => quantity,
'shipping_priority' => order_data.fetch('priority', 'standard')
}
end
def self.format_response(status_code, body)
# Formats the API response
{
statusCode: status_code,
body: JSON.generate(body)
}
end
end
레이어 콘텐츠를 압축합니다.
zip -r layer.zip ruby/
Compress-Archive -Path .\ruby -DestinationPath .\layer.zip
.zip 파일의 디렉터리 구조는 다음과 같아야 합니다.
ruby/
└── lib/
└── order_validator.rb
함수에서 모듈을 require 해 사용합니다. 함수 코드에서 각 gem을 개별적으로 require 해야 하며 bundler/setup이나 Bundler.require는 사용할 수 없습니다. 자세한 내용은 '함수에서 레이어의 gem 사용'을 참고하세요. 예시:
require 'json'
require 'order_validator'
def lambda_handler(event:, context:)
begin
# Parse the order data from the event body
order_data = JSON.parse(event['body'] || '{}')
# Validate and format the order
validated_order = OrderValidator.validate_order(order_data)
OrderValidator.format_response(200, {
message: 'Order validated successfully',
order: validated_order
})
rescue OrderValidator::ValidationError => e
OrderValidator.format_response(400, {
error: e.message
})
rescue => e
OrderValidator.format_response(500, {
error: 'Internal server error'
})
end
end
다음 테스트 이벤트로 함수를 호출할 수 있습니다.
{
"body": "{\"product_id\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}"
}
기대 응답:
{
"statusCode": 200,
"body": "{\"message\":\"Order validated successfully\",\"order\":{\"product_id\":\"ABC123\",\"quantity\":2,\"shipping_priority\":\"express\"}}"
}
Lambda에서 레이어 생성
AWS CLI 또는 Lambda 콘솔로 레이어를 게시할 수 있습니다.
publish-layer-version AWS CLI 명령을 실행해 Lambda 레이어를 만듭니다.
aws lambda publish-layer-version --layer-name my-layer --zip-file fileb://layer.zip --compatible-runtimes ruby4.0
compatible-runtimes 파라미터는 선택 사항입니다. 지정하면 Lambda가 Lambda 콘솔에서 레이어를 필터링하는 데 이 파라미터를 사용합니다.
Lambda 콘솔의 Layers 페이지를 엽니다.
- Create layer를 선택합니다.
- Upload a .zip file을 선택한 뒤, 앞서 만든
.zip아카이브를 업로드합니다. - (선택) Compatible runtimes에서 레이어를 빌드할 때 쓴 Ruby 버전에 해당하는 Ruby 런타임을 선택합니다.
- Create를 선택합니다.
함수에서 레이어의 gem 사용
함수 코드에서 사용하려는 각 gem을 명시적으로 require 해야 합니다. bundler/setup이나 Bundler.require 같은 Bundler 명령은 지원되지 않습니다. Lambda 함수에서 레이어의 gem을 올바르게 사용하는 방법은 다음과 같습니다.
# Correct: Use explicit requires for each gem
require 'nokogiri'
require 'httparty'
def lambda_handler(event:, context:)
# Use the gems directly
doc = Nokogiri::HTML(event['html'])
response = HTTParty.get(event['url'])
# ... rest of your function
end
# Incorrect: These Bundler commands will not work
# require 'bundler/setup'
# Bundler.require
함수에 레이어 추가
레이어를 함수에 첨부하려면 update-function-configuration AWS CLI 명령을 실행합니다. --layers 파라미터에는 레이어 ARN을 사용합니다. ARN은 버전을 지정해야 합니다(예: arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1). 자세한 내용은 '레이어와 레이어 버전' 문서를 참고하세요.
aws lambda update-function-configuration --function-name my-function --cli-binary-format raw-in-base64-out --layers "arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1"
cli-binary-format 옵션은 AWS CLI 버전 2를 사용한다면 필수입니다. 이 옵션을 기본값으로 만들려면 aws configure set cli-binary-format raw-in-base64-out을 실행하세요. 자세한 내용은 AWS Command Line Interface User Guide for Version 2의 'AWS CLI supported global command line options'을 참고하세요.
Lambda 콘솔의 Functions 페이지를 엽니다.
- 함수를 선택합니다.
- Layers 섹션까지 스크롤한 뒤 Add a layer를 선택합니다.
- Choose a layer 아래에서 Custom layers를 선택한 뒤, 레이어를 선택합니다.
- 레이어를 만들 때 호환 런타임을 추가하지 않았다면 이 목록에 레이어가 나타나지 않습니다. 이 경우 레이어 ARN을 대신 지정할 수 있습니다.
- Add를 선택합니다.
샘플 앱
Lambda 레이어 사용 예제를 더 보려면 AWS Lambda Developer Guide GitHub 저장소의 layer-ruby 샘플 애플리케이션을 참고하세요. 이 애플리케이션에는 tzinfo 라이브러리를 담은 레이어가 포함됩니다. 레이어를 만든 뒤 해당 함수를 배포·호출해 레이어가 예상대로 작동하는지 확인할 수 있습니다.