Shogo's Blog

Nov 30, 2018 - 2 minute read - perl aws lambda

PerlをAWS Lambdaで動かす

AWS Lambda で Custom Runtime が発表されました!

Custom Runtime により好きなプログラミング言語でLambda関数を書くことができ、 いくつかの言語についてはAWSおよびパートナーから bootstrap が提供されます。

提供される言語にCOBOLが入って話題になっていますが、 当然ながら(?)Perlはありません。

Custom Runtimeは shell script でも書ける簡単なものなので、Perlでも書いてみました。

Perl in AWS Lambda

以下のスクリプトを bootstrap という名前で保存します。

#!/usr/bin/env perl
use utf8;
use warnings;
use strict;
use lib "$ENV{LAMBDA_TASK_ROOT}/local/lib/perl5";
use Furl;
use JSON;
 
my $furl = Furl->new;
my ($handler, $function) = split /\./, $ENV{_HANDLER}, 2;
require "$ENV{LAMBDA_TASK_ROOT}/$handler.pl";
my $func = \&$function;

while(1) {
    my $res = $furl->get("http://$ENV{AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next");
    die $res->status_line unless $res->is_success;
    my $req_id = $res->header("Lambda-Runtime-Aws-Request-Id");
    my $event = decode_json($res->content);
    my $result = $func->($event);
    $furl->post(
        "http://$ENV{AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$req_id/response",
        [],
        encode_json($result),
    );
}

1;

handler.pl に Lambda 関数の本体を書きます。 とりあえず、エコーしてみます。

use utf8;
use warnings;
use strict;

sub function {
    my $event = shift;
    return $event;
}

1;

FurlとJSONに依存しているので、これらのパッケージをzipファイルに同梱します。 cpanfile に以下のような依存関係を定義

requires 'Furl';
requires 'JSON';

パッケージのビルドスクリプト(install.sh)を用意します。

#!/bin/sh
yum install -y perl-App-cpanminus gcc
cpanm -l local --notest --installdeps .

XSのビルドに困らないようlambci/docker-lambdaを使用して、依存パッケージをビルド。 まとめてzipファイルに圧縮します。

docker run --rm -v "$PWD":/var/task lambci/lambda-base ./install.sh
zip -r ../dist.zip

ランタイムに「独自のランタイムを使用する」、ハンドラに handler.function を指定して、テスト実行!

まとめ

すでに AWS Lambda Custom Runtime芸人 が大量に湧いていた。

追記:

追記その2:

moznion先生が AWS Lambda Layer 書いてくれました。

参考