2023.07.10

AWS LambdaでYii2 Consoleの検証

結論

  • al2をベースにして独自にビルドしたDockerイメージをAmazon ECRに追加することでLambda上でPHPを実行できる
  • Yii2 Consoleを実行するためにDockerイメージにPHPとYii2 アドバンスト・アプリケーション構成をインストールする

はじめに

こんにちは。次世代システム研究室のT.Tです。

現在開発運用に携わっているサービスのAWSへの移行を検討しています。現在は自社のクラウドプラットフォーム上でCentOS 7上にRKEで構築したKubernetes/Docker環境でサービスが稼働しています。来年6月にCentOS 7がEOLになるのに伴いKubernetes基盤の移行が必要になっていることが背景にあります。

その一環としてAWSの技術調査やコスト見積を進めている段階で、コスト削減の観点から現在VM上でcronで稼働しているバッチジョブのサーバーレスへの置き換えを検討しています。今回はPHPフレームワークであるYii2で稼働するバッチをLambda上で稼働させるために調査した内容についてご紹介します。

1.現在のバッチジョブの構成

現在のバッチジョブはCentOS 7のVM上でcronで定期実行しており、cronからDockerコンテナを起動する形で実行しています。DockerコンテナはalpineにPHPの実行環境をインストールしたものを利用していて、Yii2のアドバンスト・アプリケーション構成とサービス用に開発したConsoleアプリケーションのソースコードをホストOSからマウントしてコンテナ内で実行しています。

バッチ内の処理ではDBの参照更新、ユーザーへのメールの送信、社内のSlackへの通知、外部サービスのAPIの実行等を行っています。

2.Lambda実行環境の準備

PHPアプリケーションをLambda環境で実行するにあたって、コンテナ利用者に捧げるAWS Lambdaの新しい開発方式!の連載記事を参考にしました。独自にコンテナイメージをビルドしてAmazon ECRに登録することでLambda上でPHPのアプリケーションを稼働できるようです。

今回の検証ではVagrantにCentOS 7を立ち上げてAWS CLIを使ってLambda環境を構築しました。事前に以下のツールのインストールや設定を行います。

3.Lambda上でのPHPアプリケーションの実行

環境の準備が出来たら、コンテナ利用者に捧げるAWS Lambdaの新しい開発方式! 〜 第3回 〜にLambdaでコンテナイメージを利用してPHPアプリケーションを実行する方法が説明されているので、この内容に沿ってDockerfileを作成ビルドしてローカル環境でのテスト実行まで進めます。

その後、以下のようにDockerイメージをデプロイしてLambda上で実行してみました。

$ aws ecr create-repository --repository-name phplambda
$ aws ecr get-login-password | docker login --username AWS --password-stdin ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com

$ docker tag phplambda:latest \
    ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/phplambda:latest
$ docker push ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/phplambda:latest

$ DIGEST=$(aws ecr list-images --repository-name phplambda --out text --query 'imageIds[?imageTag==`latest`].imageDigest')
$ aws lambda create-function \
    --function-name phplambda-container \
    --package-type Image \
    --code ImageUri=${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/phplambda@${DIGEST} \
    --role arn:aws:iam::${ACCOUNTID}:role/lambda-ex
$ aws lambda invoke \
    --function-name phplambda-container \
    --invocation-type RequestResponse \
    --cli-binary-format raw-in-base64-out \
    --payload '{"queryStringParameters":{"foo":"bar"}}' output; \
    cat output
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{"statusCode":200,"headers":{"Content-Type":"application\/json"},"body":"queryStringParameters, {\"foo\":\"bar\"}"}

4.Lambda上でのYii2 Consoleの実行

Lambda上でのYii2 Consoleの実行を検証するために、PHP 7.4とYii2のアドバンスト・アプリケーションをインストールしたDockerfileを作成します。
Dockerfile

FROM public.ecr.aws/lambda/provided:al2

RUN yum clean all && \
    yum install -y libcurl-devel
                   
RUN yum install -y php-cli && \
    yum install -y php-xml

RUN curl -sS https://getcomposer.org/installer | /usr/bin/php -- --install-dir=/opt/ --filename=composer

COPY runtime/bootstrap /var/runtime/
RUN chmod 0755 /var/runtime/bootstrap
RUN cd /var/task/ && \
    /usr/bin/php /opt/composer create-project --ignore-platform-req=ext-dom --prefer-dist yiisoft/yii2-app-advanced lambda
COPY lambda/app.php /var/task/lambda/

CMD [ "app.handler" ]

lambda/app.php

 200,
    ]);
}

runtime/bootstrap

#!/usr/bin/env php
 'app-console',
    'basePath' => dirname(__DIR__),
];

$application = new \yii\console\Application($config);
$exitCode = $application->run();

ローカル環境でDockerfileをビルドしてコンテナを実行してみます。

$ docker build . -t yii2-console:latest
$ docker run -p 9000:8080 yii2-console:latest
09 Jul 2023 22:14:25,857 [INFO] (rapid) exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)

リクエストを投げるとYii2 Consoleのアプリケーションが実行されることが確認できます。

$ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations"
...
This is Yii version 2.0.48.1.

The following commands are available:
...

Yii2 Consoleを実行できていることが確認できたので、今度はLambda上にデプロイして実行してみます。

$ aws ecr create-repository --repository-name yii2-console

$ docker tag yii2-console:latest \
    ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/yii2-console:latest
$ docker push ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/yii2-console:latest

$ DIGEST=$(aws ecr list-images --repository-name yii2-console --out text --query 'imageIds[?imageTag==`latest`].imageDigest')
$ aws lambda create-function \
    --function-name yii2-console-container \
    --package-type Image \
    --code ImageUri=${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/yii2-console@${DIGEST} \
    --role arn:aws:iam::${ACCOUNTID}:role/lambda-ex
$ aws lambda invoke \
    --function-name yii2-console-container output
{
    "StatusCode": 200,
}

Lambda上でもYii2 Consoleを実行できていることが確認できました。

5.まとめ

DockerコンテナにPHPの実行環境とYii2のソースコードを梱包することでAWS Lambda上でYii2 Consoleを実行することができました。今回はConsoleの実行だけ検証しましたが、ConsoleをLambdaに移行するためにはDBの参照更新、ユーザーへのメールの送信、Consoleコンフィグの設定等も利用できるようにする必要があります。アプリケーションとして稼働できるように引き続き検証を進めていきたいと思います。

次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。

皆さんのご応募をお待ちしています。

  • Twitter
  • Facebook
  • はてなブックマークに追加

グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。

 
  • AI研究開発室
  • 大阪研究開発グループ

関連記事