コンテナイメージで Ruby Lambda 関数をデプロイする
Ruby Lambda 関数のコンテナイメージを構築するには 3 つの方法があります。
-
AWS ベースイメージには、言語ランタイム、Lambda と関数コード間のやり取りを管理するランタイムインターフェースクライアント、ローカルテスト用のランタイムインターフェースエミュレーターがあらかじめロードされています。
-
AWS OS 専用ベースイメージ
には、Amazon Linux ディストリビューションおよびランタイムインターフェイスエミュレータ が含まれています。これらのイメージは、Go や Rust などのコンパイル済み言語や、Lambda がベースイメージを提供していない言語または言語バージョン (Node.js 19 など) のコンテナイメージの作成によく使用されます。OS 専用のベースイメージを使用してカスタムランタイムを実装することもできます。イメージに Lambda との互換性を持たせるには、Ruby のランタイムインターフェイスクライアントをイメージに含める必要があります。 -
Alpine Linux や Debian など、別のコンテナレジストリの代替ベースイメージを使用することができます。組織が作成したカスタムイメージを使用することもできます。イメージに Lambda との互換性を持たせるには、Ruby のランタイムインターフェイスクライアントをイメージに含める必要があります。
ヒント
Lambda コンテナ関数がアクティブになるまでの時間を短縮するには、「Docker ドキュメント」の「マルチステージビルドを使用する
このページでは、Lambda のコンテナイメージを構築、テスト、デプロイする方法について説明します。
Ruby の AWS ベースイメージ
AWS は、Ruby の次のベースイメージを提供します。
タグ | ランタイム | オペレーティングシステム | Dockerfile | 非推奨 |
---|---|---|---|---|
3.3 |
Ruby 3.3 | Amazon Linux 2023 | 「GitHub の Ruby 3.3 用 Dockerfile |
スケジュールされていません |
3.2 |
Ruby 3.2 | Amazon Linux 2 | GitHub の Ruby 3.2 用 Dockerfile |
スケジュールされていません |
Amazon ECR リポジトリ: gallery.ecr.aws/lambda/ruby
Ruby の AWS ベースイメージを使用する
このセクションの手順を完了するには、以下が必要です。
-
Ruby
Ruby のコンテナイメージを作成するには
-
プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。
mkdir example cd example
-
Gemfile
という名前の新しいファイルを作成します。ここでは、アプリケーションに必要な RubyGems パッケージを一覧表示します。AWS SDK for Ruby は RubyGems から入手できます。インストールする特定の AWS サービス gem を選択する必要があります。例えば、Lambda 用 Ruby gemを使用するには、Gemfile は次のようになるはずです。 source 'https://rubygems.org' gem 'aws-sdk-lambda'
あるいは、aws-sdk
gem には利用可能なすべての AWS サービス gem が含まれています。この gem はとても大きいことが特徴です。多くの AWS サービスを利用している場合にのみ使用することを推奨します。 -
バンドルインストール
を使用して、Gemfile で指定された依存関係をインストールします。 bundle install
-
lambda_function.rb
という名前の新しいファイルを作成します。テスト用に次のサンプル関数コードをファイルに追加することも、独自のコードを使用することもできます。例 Ruby 関数
module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
-
新しい Dockerfile を作成します。次に、AWS ベースイメージ を使用した Dockerfile の例を示します。この Dockerfile では次の設定を使用します。
-
ベースイメージの URI に
FROM
プロパティを設定します。 -
COPY コマンドを使用し、関数コードおよびランタイムの依存関係を
{LAMBDA_TASK_ROOT}
(Lambda 定義の環境変数) にコピーします。 -
CMD
引数を Lambda 関数ハンドラーに設定します。
この例の Dockerfile には USER 命令
が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、 USER
命令を指定しなかったときにroot
ユーザーのデフォルトとなる動作のことです。例 Dockerfile
FROM
public.ecr.aws/lambda/ruby:3.2
# Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:2.4.20 && \ bundle config set --local path 'vendor/bundle' && \ bundle install # Copy function code COPYlambda_function.rb
${LAMBDA_TASK_ROOT}/ # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process
" ] -
-
Docker イメージを「Docker の構築
」コマンドで構築します。次の例では、イメージを docker-image
と名付けてtest
タグを付けます。 docker build --platform linux/amd64 -t
docker-image
:test
.注記
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する
--platform linux/amd64
オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに--platform linux/arm64
オプションを使用するようにコマンドを変更してください。
-
docker run コマンドを使用して、Docker イメージを起動します。この例では、
docker-image
はイメージ名、test
はタグです。docker run --platform linux/amd64 -p 9000:8080
docker-image
:test
このコマンドはイメージをコンテナとして実行し、
localhost:9000/2015-03-31/functions/function/invocations
でローカルエンドポイントを作成します。注記
ARM64 命令セットアーキテクチャ用に Docker イメージをビルドした場合は、
--platform linux/
の代わりにamd64
--platform linux/
オプションを使用してください。arm64
-
新しいターミナルウィンドウから、イベントをローカルエンドポイントにポストします。
-
コンテナ ID を取得します。
docker ps
-
「docker kill
」コマンドを使用してコンテナを停止します。このコマンドでは、 3766c4ab331c
を前のステップのコンテナ ID で置き換えます。docker kill
3766c4ab331c
Amazon ECR にイメージをアップロードして Lambda 関数を作成するには
-
「get-login-password
」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。 -
--region
値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。 -
111122223333
を AWS アカウント ID に置き換えます。
aws ecr get-login-password --region
us-east-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
「create-repository
」コマンドを使用して Amazon ECR にリポジトリを作成します。 aws ecr create-repository --repository-name
hello-world
--regionus-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE注記
Amazon ECR リポジトリは Lambda 関数と同じ AWS リージョン に配置されている必要があります。
成功すると、次のようなレスポンスが表示されます。
{ "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
-
前のステップの出力から
repositoryUri
をコピーします。 -
「docker tag
」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで: -
docker-image:test
は、Docker イメージの名前とタグです。これは、 docker build
コマンドに指定したイメージの名前とタグです。 -
<ECRrepositoryUri>
を、コピーしたrepositoryUri
に置き換えます。URI の末尾には必ず:latest
を含めてください。
docker tag docker-image:test
<ECRrepositoryUri>
:latest例:
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
「docker push
」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず :latest
を含めてください。docker push
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
まだ作成済みでない場合、関数に「実行ロールの作成」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。
-
Lambda 関数を作成します。
ImageUri
には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず:latest
を含めてください。aws lambda create-function \ --function-name
hello-world
\ --package-type Image \ --code ImageUri=111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex
注記
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「 Amazon ECR クロスアカウント許可」を参照してください。
-
関数を呼び出します。
aws lambda invoke --function-name
hello-world
response.json次のような結果が表示されます。
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
関数の出力を確認するには、
response.json
ファイルをチェックします。
関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、update-function-code
Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。
新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、update-function-code--publish
オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\ --publish
ランタイムインターフェイスクライアントで代替ベースイメージを使用する
OS 専用ベースイメージまたは代替のベースイメージを使用する場合、イメージにランタイムインターフェイスクライアントを含める必要があります。ランタイムインターフェイスクライアントは、Lambda と関数コード間の相互作用を管理する カスタムランタイムに Lambda ランタイム API を使用する を拡張します。
RubyGems.org パッケージマネージャーを使用して、Ruby 用の Lambda ランタイムインターフェイスクライアント
gem install aws_lambda_ric
Ruby ランタイムインターフェイスクライアント
次の例は、非 AWS ベースイメージを使用して Ruby 用のコンテナイメージを構築する方法を示しています。サンプルの Dockerfile は公式の Ruby ベースイメージを使用しています。Dockerfile には、ランタイムインターフェイスクライアントが含まれています。
このセクションの手順を完了するには、以下が必要です。
-
Ruby
代替のベースイメージを使用して Ruby 用のコンテナイメージを作成するには
-
プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。
mkdir example cd example
-
Gemfile
という名前の新しいファイルを作成します。ここでは、アプリケーションに必要な RubyGems パッケージを一覧表示します。AWS SDK for Ruby は RubyGems から入手できます。インストールする特定の AWS サービス gem を選択する必要があります。例えば、Lambda 用 Ruby gemを使用するには、Gemfile は次のようになるはずです。 source 'https://rubygems.org' gem 'aws-sdk-lambda'
あるいは、aws-sdk
gem には利用可能なすべての AWS サービス gem が含まれています。この gem はとても大きいことが特徴です。多くの AWS サービスを利用している場合にのみ使用することを推奨します。 -
バンドルインストール
を使用して、Gemfile で指定された依存関係をインストールします。 bundle install
-
lambda_function.rb
という名前の新しいファイルを作成します。テスト用に次のサンプル関数コードをファイルに追加することも、独自のコードを使用することもできます。例 Ruby 関数
module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
-
新しい Dockerfile を作成します。次の Dockerfile は、AWS ベースイメージの代わりに Ruby ベースイメージを使用しています。Dockerfile には Ruby 用のランタイムインターフェースクライアントが
含まれており、イメージに Lambda との互換性を持たせています。あるいは、ランタイムインターフェースクライアントをアプリケーションの Gemfile に追加することもできます。 -
FROM
プロパティに Ruby ベースイメージを設定します。 -
関数コードのディレクトリを作成し、そのディレクトリを指す環境変数を作成します。この例では、ディレクトリは
/var/task
であり、Lambda 実行環境をミラーリングします。ただし、Dockerfile は AWS ベースイメージを使用しないため、関数コードには任意のディレクトリを選択できます。 -
ENTRYPOINT
を、Docker コンテナの起動時に実行させるモジュールに設定します。この場合、モジュールはランタイムインターフェイスクライアントです。 -
CMD
引数を Lambda 関数ハンドラーに設定します。
この例の Dockerfile には USER 命令
が含まれていないことに注意してください。コンテナイメージを Lambda にデプロイすると、最小特権のアクセス許可を付与したデフォルトの Linux ユーザーを Lambda が自動的に定義します。これは標準の Docker 動作とは異なります。標準の動作とは、 USER
命令を指定しなかったときにroot
ユーザーのデフォルトとなる動作のことです。例 Dockerfile
FROM
ruby:2.7
# Install the runtime interface client for Ruby RUN gem install aws_lambda_ric # Add the runtime interface client to the PATH ENV PATH="/usr/local/bundle/bin:${PATH}" # Create a directory for the Lambda function ENV LAMBDA_TASK_ROOT=/var/task RUN mkdir -p ${LAMBDA_TASK_ROOT} WORKDIR ${LAMBDA_TASK_ROOT} # Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:2.4.20 && \ bundle config set --local path 'vendor/bundle' && \ bundle install # Copy function code COPYlambda_function.rb
${LAMBDA_TASK_ROOT}/ # Set runtime interface client as default command for the container runtime ENTRYPOINT [ "aws_lambda_ric
" ] # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process" ]
-
-
Docker イメージを「Docker の構築
」コマンドで構築します。次の例では、イメージを docker-image
と名付けてtest
タグを付けます。 docker build --platform linux/amd64 -t
docker-image
:test
.注記
このコマンドは、ビルドマシンのアーキテクチャに関係なく、コンテナが Lambda の実行環境と互換性があることを確認する
--platform linux/amd64
オプションを特定します。ARM64 命令セットアーキテクチャを使用して Lambda 関数を作成する場合は、代わりに--platform linux/arm64
オプションを使用するようにコマンドを変更してください。
ランタイムインターフェイスエミュレーター
ローカルマシンにランタイムインターフェイスエミュレーターをインストールして実行するには
-
プロジェクトディレクトリから次のコマンドを実行して、GitHub からランタイムインターフェイスエミュレーター (x86-64 アーキテクチャ) をダウンロードし、ローカルマシンにインストールします。
-
docker run コマンドを使用して、Docker イメージを起動します。次の点に注意してください:
-
docker-image
はイメージ名、test
はタグです。 -
aws_lambda_ric lambda_function.LambdaFunction::Handler.process
はENTRYPOINT
で、その後に Dockerfile のCMD
が続きます。
このコマンドはイメージをコンテナとして実行し、
localhost:9000/2015-03-31/functions/function/invocations
でローカルエンドポイントを作成します。注記
ARM64 命令セットアーキテクチャ用に Docker イメージをビルドした場合は、
--platform linux/
の代わりにamd64
--platform linux/
オプションを使用してください。arm64
-
-
イベントをローカルエンドポイントにポストします。
-
コンテナ ID を取得します。
docker ps
-
「docker kill
」コマンドを使用してコンテナを停止します。このコマンドでは、 3766c4ab331c
を前のステップのコンテナ ID で置き換えます。docker kill
3766c4ab331c
Amazon ECR にイメージをアップロードして Lambda 関数を作成するには
-
「get-login-password
」コマンドを実行して Amazon ECR レジストリに Docker CLI を認証します。 -
--region
値を Amazon ECR リポジトリを作成する AWS リージョン に設定します。 -
111122223333
を AWS アカウント ID に置き換えます。
aws ecr get-login-password --region
us-east-1
| docker login --username AWS --password-stdin111122223333
.dkr.ecr.us-east-1
.amazonaws.com -
-
「create-repository
」コマンドを使用して Amazon ECR にリポジトリを作成します。 aws ecr create-repository --repository-name
hello-world
--regionus-east-1
--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE注記
Amazon ECR リポジトリは Lambda 関数と同じ AWS リージョン に配置されている必要があります。
成功すると、次のようなレスポンスが表示されます。
{ "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } }
-
前のステップの出力から
repositoryUri
をコピーします。 -
「docker tag
」コマンドを実行して、最新バージョンとしてローカルイメージを Amazon ECR リポジトリにタグ付けします。このコマンドで: -
docker-image:test
は、Docker イメージの名前とタグです。これは、 docker build
コマンドに指定したイメージの名前とタグです。 -
<ECRrepositoryUri>
を、コピーしたrepositoryUri
に置き換えます。URI の末尾には必ず:latest
を含めてください。
docker tag docker-image:test
<ECRrepositoryUri>
:latest例:
docker tag
docker-image
:test
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
-
「docker push
」コマンドを実行して Amazon ECR リポジトリにローカルイメージをデプロイします リポジトリ URI の末尾には必ず :latest
を含めてください。docker push
111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest -
まだ作成済みでない場合、関数に「実行ロールの作成」を実行してください。次のステップではロールの Amazon リソースネーム (ARN) が必要です。
-
Lambda 関数を作成します。
ImageUri
には、先ほど使用したリポジトリ URI を指定します。URI の末尾には必ず:latest
を含めてください。aws lambda create-function \ --function-name
hello-world
\ --package-type Image \ --code ImageUri=111122223333
.dkr.ecr.us-east-1
.amazonaws.com/hello-world
:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex
注記
イメージが Lambda 関数と同じリージョンに配置されていれば、別の AWS アカウントのイメージを使用して関数を作成することができます。詳細については、「 Amazon ECR クロスアカウント許可」を参照してください。
-
関数を呼び出します。
aws lambda invoke --function-name
hello-world
response.json次のような結果が表示されます。
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 }
-
関数の出力を確認するには、
response.json
ファイルをチェックします。
関数コードを更新するには、イメージを再構築し、新しいイメージを Amazon ECR リポジトリにアップロードしてから、update-function-code
Lambda は、イメージタグを特定のイメージダイジェストに解決します。これは、関数のデプロイに使用されたイメージタグを Amazon ECR 内の新しいイメージを指すように変更しても、Lambda は新しいイメージを使用するように自動的に関数を更新しないことを意味します。
新しいイメージを同じ Lambda 関数にデプロイするには、Amazon ECR のイメージタグが同じままであっても、update-function-code--publish
オプションが最新のコンテナイメージを使用して関数の新しいバージョンを作成しています。
aws lambda update-function-code \ --function-name
hello-world
\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
\ --publish