
AWS LambdaをHaskellで実装!aws-lambda-haskell-runtimeを試してみた。
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こちらはAWS Lambda Custom Runtimes芸人 Advent Calendar 2018の22日目の記事です。
こんにちは、かたいなかです。
AWS LambdaのCustom RuntimeでHaskellを動かすためのCustom RuntimeのLayerの実装、およびそのRuntime上でアプリケーションコードを実装するためのTemplate等がtheam/aws-lambda-haskell-runtimeというGitHub上のリポジトリにあり、ビルドされたものがRuntime Layerとして利用できるようになっているのを発見したため、試してみた内容を記事にまとめました。
ローカルでの準備
まず、以下のようなコードを実行し、ローカルに今回使用するコードの展開を行います。
$ stack new <repository名> https://github.com/theam/aws-lambda-haskell-runtime/raw/master/stack-template.hsfiles \
--resolver=lts-12.13 --omit-packages #テンプレートを展開
$ cd <repository名> #作成されたディレクトリに入る
次に、ビルド環境として使用するstack-buildのDockerイメージをPullしておきます。
$ stack docker pull #ビルド環境として使用するDockerイメージをPull
最後に、stack.ymlに上記のような内容を追加します。
packages: - . extra-deps: - aws-lambda-haskell-runtime-1.0.4
ここまでの準備で、Lambdaにアップロードできるbuild/function.zipがmakeコマンドにより作成できるようになっています。
テンプレートから作成されたリポジトリの内容
ここまでの処理で以下のようなファイルが作成されます
- .stack-work - (省略) - app - Main.hs - src - Lib.hs - .gitignore - LISCENCE - Makefile - <repository名>.cabal - package.yaml - README.md - Setup.hs - stack.yaml
src/Lib.hsではハンドラを定義しています。
module Lib where
import GHC.Generics
import Aws.Lambda.Runtime
import Data.Aeson
data Person = Person
{ personName :: String
, personAge :: Int
} deriving (Generic)
instance FromJSON Person
instance ToJSON Person
handler :: Person -> Context -> IO (Either String Person)
handler person context =
if personAge person > 0 then
return (Right person)
else
return (Left "A person's age must be positive")
他の言語のHandler同様にEventとContextを受け取る形で実装されています。
処理の内容としては以下のようなJsonを受け取り、personAgeが正であることを確認したうえで受け取ったJsonと同じものを返すというものです。
{
"personName": "katainaka"
"personAge": 3
}
app/Main.hsは以下のようなコードで、Template Haskellを使用して動的にhandlerにディスパッチする処理を生成しているようです。
module Main where import Aws.Lambda.Configuration import Aws.Lambda.Runtime import qualified Lib configureLambda
動作確認
実際にデプロイしていきます。
リポジトリのルートディレクトリでmakeコマンドを実行します。
$ make
すると、buildディレクトリの下にfunction.zipというファイルが作成されます。
以下のようなコマンドですでに公開されているRuntimeのLayerと合わせてFunctionを作成します。
$ aws lambda create-function --function-name "haskell-lambda" \
--zip-file "fileb://build/function.zip" \
--handler "src/Lib.handler" \
--runtime provided \
--layers arn:aws:lambda:<YOUR REGION>:785355572843:layer:haskell-runtime:<VERSION> ##公開されているRuntimeのLayerのARNです
--role arn:aws:iam::XXXXXXXXXXXX:role/your-lambda-role
Functionを作成したら、コンソール上から試していきます。
以下のようなテストイベントを作成して実行すると

以下のように実行に成功し、正しく結果が返されました!

感想
re:Inventでの発表からそれほど日がたっていないにもかかわらず、すでにHaskellのRuntimeの実装例がRuntime LayerのARNを指定すれば誰でも利用可能な状態になっており、関連したパッケージがCabalに登録されているのには驚きました。
今回はテンプレートから生成されたコードを実行してみただけでしたが、Haskellがお好きな方は是非本格的に試してみてはいかがでしょうか。









