この記事は公開されてから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がお好きな方は是非本格的に試してみてはいかがでしょうか。