Ruby Lambda 함수를 위한 계층 작업
Lambda 계층을 사용하여 여러 함수에서 재사용하려는 코드와 종속성을 패키징합니다. 계층에는 일반적으로 라이브러리 종속 항목, 사용자 지정 런타임 또는 구성 파일이 포함됩니다. 계층을 생성하려면 세 가지 일반적인 단계를 거칩니다.
-
계층 콘텐츠를 패키징합니다. 즉, 함수에 사용하려는 종속성이 포함된 .zip 파일 아카이브를 생성합니다.
-
Lambda에서 계층을 생성합니다.
-
계층을 함수에 추가합니다.
계층 콘텐츠 패키징
계층을 생성하려면 다음 요구 사항을 충족하는 .zip 파일 아카이브로 패키지를 번들링합니다.
-
Lambda 함수에 사용하려는 것과 동일한 Ruby 버전을 사용하여 계층을 생성합니다. 예를 들어 Ruby 3.4용 계층을 생성하는 경우 함수에 Ruby 3.4 런타임을 사용합니다.
-
계층의 .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
을 생성하여 계층에 포함할 순수 Ruby gem을 지정합니다.예 Gemfile
source 'https://rubygems.org' gem 'tzinfo'
-
번들러를 사용하여 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 파일로 압축합니다.
.zip 파일의 디렉터리 구조는 다음과 같아야 합니다.
ruby/ └── gems/ └── 3.4.0/ ├── gems/ │ ├── concurrent-ruby-1.3.5/ │ └──
tzinfo-2.0.6/
├── specifications/ ├── cache/ ├── build_info/ └── (other bundler directories)참고
함수 코드에 각 gem을 개별적으로 불러와야 합니다.
bundler/setup
또는Bundler.require
를 사용할 수 없습니다. 자세한 내용은 함수의 계층에서 gem 사용 섹션을 참조하세요.
널리 사용되는 Ruby gem에는 대상 플랫폼에 대해 컴파일해야 하는 기본 확장(C 코드)이 포함되어 있습니다. 기본 확장이 있는 인기 gem은 nokogiri
기본 확장이 있는 gem을 사용하여 계층을 생성하려면
-
Gemfile
를 만듭니다.예 Gemfile
source 'https://rubygems.org' gem 'nokogiri' gem 'httparty'
-
Docker를 사용하여 Lambda와 호환되는 Linux 환경에서 gem을 빌드합니다. Dockerfile에서 AWS 기본 이미지를 지정합니다.
예 Ruby 3.4용 Dockerfile
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을 개별적으로 불러와야 합니다.
bundler/setup
또는Bundler.require
를 사용할 수 없습니다. 자세한 내용은 함수의 계층에서 gem 사용 섹션을 참조하세요.
자체 코드를 사용하여 계층을 생성하려면 다음을 수행하세요.
-
계층에 필요한 디렉터리 구조를 생성합니다.
mkdir -p ruby/lib
-
ruby/lib
디렉터리에서 Ruby 모듈을 생성합니다. 다음 예시 모듈은 주문에 필수 정보가 포함되어 있는지 확인하여 주문을 검증합니다.예 ruby/lib/order_validator.rb
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 파일로 압축합니다.
.zip 파일의 디렉터리 구조는 다음과 같아야 합니다.
ruby/ └── lib/ └── order_validator.rb
-
함수에서 모듈을 불러와서 사용합니다. 함수 코드에 각 gem을 개별적으로 불러와야 합니다.
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 콘솔을 사용하여 계층을 게시할 수 있습니다.
함수의 계층에서 gem 사용
함수 코드에서 사용하려는 각 gem을 명시적으로 불러와야 합니다. bundler/setup
및 Bundler.require
와 같은 번들러 명령은 지원되지 않습니다. 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
함수에 계층 추가
샘플 애플리케이션
Lambda 계층을 사용하는 방법의 자세한 예는 AWS Lambda Developer Guide GitHub 리포지토리의 layer-ruby