LoginSignup
11

More than 5 years have passed since last update.

ClojureとAWS LambdaでHello World

Last updated at Posted at 2015-11-07

AWSのブログを参考に、Clojureを使って初めてのAWS Lambda functionを作ってみる。

下準備

まずIAM roleを作る。sandbox-lambda-exec-roleという新しいロールを作り、権限の問題でハマりたくないのでとりあえずAWSLambdaFullAccessというポリシーを割り当てた。

IAM userがsandbox-lambda-exec-roleロールでLambda functionを実行できるように、IAM userのインラインポリシーを編集してiam:PassRoleを許可する。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1446873599000",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/*"
            ]
        }
    ]
}

Jarを作成

新しいプロジェクトhelloを作る。

lein new hello

project.cljcom.amazonaws/aws-lambda-java-coreなどを追加。

(defproject hello "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [org.clojure/data.json "0.2.6"]
                 [com.amazonaws/aws-lambda-java-core "1.0.0"]]
  :aot :all)

src/hello/core.cljを編集してハンドラを追加。

(ns hello.core
  (:gen-class
   :methods [^:static [handler [String] String]]))

(defn -handler [s]
  (str "Hello " s "!"))

jarを作成。

$ lein uberjar

Lambda functionを作成&実行

AWS-CLIを使ってLambda function helloを作成する。

aws lambda create-function --function-name hello --handler hello.core::handler --runtime java8 --memory 512 --timeout 10 --role arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/sandbox-lambda-exec-role --zip-file fileb://./target/hello-0.1.0-SNAPSHOT-standalone.jar

実行。

aws lambda invoke --invocation-type RequestResponse --function-name hello --log-type Tail --payload '"Clojure"' output.txt

正常に実行されるとoutput.txtに、

"Hello Clojure!"

と出力される。

RequestStreamHandlerを実装

このあとAPI Gatewayを使ってREST API化にしようとしたのだが、パスに入れたnameパラメータをLambda Functionに渡す方法がぱっと分からないので、冒頭に上げたAWSブログを参考にして、RequestStreamHandlerを実装し、POSTボディからJSONを読んでパラメータを取得するように変更してみた。

(ns hello_lambda.core
  (:gen-class
   :implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler])
  (:require [clojure.data.json :as json]
            [clojure.string :as s]
            [clojure.java.io :as io]))

(defn hello [params]
  {:message (str "Hello " (:name params))})

(defn -handleRequest [this is os context]
  (let [w (io/writer os)]
    (-> (json/read (io/reader is) :key-fn keyword)
        (hello)
        (json/write w))
    (.flush w)))

API Gatewayを使ってこのLambda FunctionをREST APIで呼び出せるようにした記録はこちらの記事にあります。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11