AWS LambdaでRubyコンテナを動かす

re:InventでAWS Lambdaがコンテナをサポートしたようなので、
aws-lambda-rubyコンテナを使った動作確認をしてみました.

corrupt952/aws-lambda-container-ruby-sampleにファイルを置いてきます.

TL; DR

  • コンテナがサポートされたことにより関数を実行するランタイムの柔軟さが向上した(ように思える)

  • Lambdaで実行しづらかった一部のユースケースが利用可能になる程度で、ECSなどで実行されているような処理が置き換え可能になるわけではなさそう

Lambda Functionを作成する

コンテナを使ったLambda Functionを作成手順は、以下のような流れになります.

  1. Lambdaで利用するためのECRリポジトリを作成

  2. Rubyランタイムで実行可能なコードを作成

  3. Lambdaで実行するためのDockerfileを作成

  4. コンテナイメージをビルド

  5. コンテナイメージを1で作成したECRリポジトリにプッシュ

  6. Lambda Functionを作る時に5で指定したコンテナイメージのURIを指定

それぞれについて少しだけ詳細に書いておきます.

1. Lambdaで利用するためのECRリポジトリを作成

特筆して書くことはないですが、コンテナイメージをプッシュするためにECRリポジトリを作成しておきます.

2. Rubyランタイムで実行可能なコードを作成

Ruby の AWS Lambda 関数ハンドラーを参考にRubyランタイムで実行可能なコードを作っておきます.

今回はapp.rbというファイル名でwww.khasegawa.netへリクエストするだけのコードを作成しておきます.

# app.rb
require 'faraday'

module LambdaFunction
  class Handler
    def self.process(event:, context:)
      response = Faraday.get 'https://www.khasegawa.net'
      puts response.body
    end
  end
end

3. Lambdaで実行するためのDockerfileを作成

Lambda Runtime API どんなコンテナでも動作するというわけではなくLambda Runtime APIが実装されているコンテナである必要があります.
実装するのは面倒なのでamazon/aws-lambda-rubyを使ってコンテナイメージを作成します.

FROM amazon/aws-lambda-ruby:2.7
COPY Gemfile Gemfile.lock $LAMBDA_TASK_ROOT
# vendor/bundleにインストールしないと参照できないので注意
RUN bundle install --path vendor/bundle
COPY app.rb $LAMBDA_TASK_ROOT
CMD ["app.LambdaFunction::Handler.process"]

4. コンテナイメージをビルド

docker build -t xxx.dkr.ecr.ap-northeast-1.amazonaws.com/hasegawa-sandbox-lambda:latest .

5. コンテナイメージを1で作成したECRリポジトリにプッシュ

ビルドしたコンテナイメージをECRにプッシュします.

aws ecr get-login-password | docker login --username AWS --password-stdin xxx.dkr.ecr.ap-northeast-1.amazonaws.com
docker push xxx.dkr.ecr.ap-northeast-1.amazonaws.com/hasegawa-sandbox-lambda:latest

6. Lambda Functionを作る時に5で指定したコンテナイメージのURIを指定

以下のように、コンテナイメージを選択した上で、ECR上にあるコンテナイメージのURIを指定して関数を作成します.

f:id:corrupt952:20210127074603j:plain

実行

実際に実行した結果としては以下のようになります.(見づらい)

f:id:corrupt952:20210127074625j:plain

さいごに

Lambdaでコンテナがサポートされたころにより、今までよりもランタイムが柔軟になり、
利用するハードルやコンテナイメージの作成自体のハードルも低く、とても魅力的に感じました.
他にもyumなどのパッケージマネージャ経由でパッケージをインストールして、それらを利用することも可能ですし、
非常に可能性を感じました.

とはいえ、実際に使ってみた感想としてはランタイムの柔軟性が増しただけのような気もするので、
ユースケースによってはマッチしない可能性はありそうですね.