Help us understand the problem. What is going on with this article?

ClojureとAWS LambdaでHello World

More than 5 years have passed since last update.

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で呼び出せるようにした記録はこちらの記事にあります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away