AWS Lambda + PHPを技術調査した

概要

qiita.com

数年前に軽く記事にしていたが、改めて技術調査をしたのでまとめてみる。

TL;DR

  • いろいろなユースケースで使えるくらい充実してきた
  • 思ったよりもすんなり動く
  • ワーカーとか動かすと嬉しそう

実行環境

AWS公式でPHPの実行環境は提供されておらず、動かす場合は下記2つの選択肢があると思われる。

  • PHPのコンテナを動かす
  • brefを利用する

コンテナで動かすのはちょっと難儀したため、今回もbrefを利用していく。

bref

AWS LambdaでPHPを動かすライブラリで、Serverless Frameworkを利用して構成管理できる。

ここ数年でメジャーバージョンになったり、AWSの記事で紹介されるようになった。

aws.amazon.com

公式サイトではAmazon API Gatewayユースケースは勿論、Amazon SQSやAmazon S3のケースも紹介されている。

Typed PHP Lambda handlers

alu.jp

フルスタックフレームワークの例も記載されており、LaravelやSymfonyを動かすことも容易にみえる。

フルスタックフレームワークの例も記載されており、LaravelやSymfonyを動かすことも容易にみえる。

Serverless Laravel applications - Bref

MemcachedImageMagickといったライブラリを動かすカスタムLayerも別リポジトリで用意されている。下記を見る限り、一通りのライブラリが用意されており、本体と合わさって、かなり実用的なライブラリと思った。

https://github.com/brefphp/extra-php-extensions

環境構築

brefを動かすためには、下記の2つが必要

  • PHP
    • Composerを利用するため
  • Node.js
    • Serverless Frameworkを利用するため

自分はよくDockerで環境構築するため、下記のように用意した。

FROM php:8.0-fpm

RUN pecl install xdebug && \
    docker-php-ext-enable xdebug && \
    apt-get update && apt-get install -y zlib1g-dev git zip && \
    docker-php-ext-install pdo_mysql opcache && \
    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
    php composer-setup.php && \
    php -r "unlink('composer-setup.php');" && \
    mv composer.phar /usr/local/bin/composer

# serverless
RUN apt-get install -y nodejs npm && \
    npm install npm@latest -g && \
    npm install -g serverless

あとは公式サイト通りに初期設定を行っていけばOK

serverless config credentials --provider aws --key <key> --secret <secret>
composer require bref/bref
vendor/bin/bref init
serverless deploy

フルスタックフレームワークを乗せる例は、PHPerKaigi2021でちゃちいさんが紹介しているので割愛。

ロギング

Amazon API Gateway + AWS LambdaでAPIを作った際、ログをまとめて調査したい欲求があった。

下記はECSの例だが、ちょっと変更すればAmazon API Gateway + AWS Lambdaの構成でも対応可能だった。

qiita.com

こちらに記載があるように、 LAMBDA_INVOCATION_CONTEXT を参照すれば良いので、フォーマッターを下記のようにすることでグルーピングできた。

/**
 * {@inheritdoc}
 */
public function format(array $record)
{
    $output = [];
    $context = json_decode($_SERVER['LAMBDA_INVOCATION_CONTEXT'], associative: true);
    $output['RequestId'] = $context['awsRequestId'];
    $output['message'] = $record['message'];
    foreach ($record['context'] as $var => $val) {
        $output[$var] = $val;
    }

    return json_encode($output, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
}

所感

意外とすんなり動く

下記構成のアプリケーションを作ってみたが、どれも想定より簡単に動作させることができた。

慣れない言語で四苦八苦した経験があったので、PHPでやってみるのはありなんじゃないかと思えた。

環境構築でPHPとNode.jsの環境が必要な都合上、デプロイパイプラインがServerless Framework単品で使うより手間だが、Workflowを組むことで解決可能だった。

※CircleCIをよく使うので、CircleCIでWorkflowを組んだ。

Serverless Frameworkの資産を使える

brefの公式サイトでも紹介されているが、Serverless Frameworkを使っているので、リソースの管理等もできる。

関係するリソースを一括で管理できるので、ライフサイクル単位で管理できるのは魅力。

最後に

AWS Lambdaのハードリミットがミスマッチで、プロダクション環境で使うことはなかった。だが結構色々調べられたので、知見としてここに残しておく。
あと「いつか使ってやるぞ」という野心も残しておく

参考資料