lamjet を使って AWS Lambda に CoffeeScript で書かれた関数を楽々デプロイする方法


1. 背景と概要

AWS Lambdaはとても便利なサービスです。けれども、使い始めるまでが少し面倒です。
JavaScriptファイルをZIPファイルにアーカイブして、Webコンソール、ないしAPIでデプロイして・・・。
また、CoffeeScriptを使うとコードの記述は楽になりますが、さらにCoffeeScriptからJavaScriptへの変換も必要になります。

そんな面倒を解消してくれるツール「lamjet」(ラムジェット)を作りましたので紹介します。

lamjetの特徴は以下の通りです。

  • コマンド一発でテンプレートを作成する lamjet init
  • コマンド一発でデプロイする gulp deploy
  • Jasmineによるテストに対応
  • CoffeeScriptのみに対応

2. 前提条件

本稿を参照するに当たっての前提条件は以下の通りです。

  • nodeがインストールされていること
  • AWSアカウントを保有していること

3. 準備

3.1. IAMロールの準備

AWS Lambdaの関数(以下「Lambda関数」)を実行するためにはIAM(Identity and Access Management)ロールが必要です。
ここでは詳しく述べませんが、例えばKinesisストリームから起動されるLambda関数の場合、以下の様なIAMポリシーを持つIAMロールを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "kinesis:GetRecords",
                "kinesis:GetShardIterator",
                "kinesis:DescribeStream",
                "kinesis:ListStreams"
            ],
            "Resource": [
                "arn:aws:kinesis:us-east-1:000000000000:stream/name"
            ]
        }
    ]
}

lamjetの設定ファイルにIAMロールのARN(Amazon Resource Name)を記述する必要がありますので、控えておきます。
IAMロールのARNは、例えば以下の様な識別子です。

arn:aws:iam::000000000000:role/name

3.2. lamjetのインストール

lamjetnpm installコマンドで簡単にインストールする事ができます。
lamjetコマンドが必要なので、-gオプションを付与し、グローバル環境にインストールします。

$ npm install -g lamjet

4. Lambda関数の作成、デプロイ

4.1. ディレクトリの作成

Lambda関数を実装するためのディレクトリを準備します。
ディレクトリ名がデフォルトの関数名となりますので、いい感じのディレクトリ名にしておきましょう。

$ cd /your/project/path
$ mkdir your-function-name
$ cd your-function-name

4.2. 初期化

lamjet initコマンドを実行すると、そのディレクトリに必要なファイル一式を生成します。
途中で関数名、メモリサイズなどについて質問されますが、IAMロール以外はデフォルト値のままで構いません。
何も入力せずにEnterキーを押下すると、デフォルト値が使用されます。

$ lamjet init
lamjet v0.3.1
Function name [your-function-name] ?
Version [1.0.0] ?
Description [TODO] ?
Region [us-east-1] ?
Role [arn:aws:iam::ACCOUNTID:role/ROLENAME] ? arn:aws:iam::000000000000:role/name
Memory size in MB [128] ?
Timeout in sec [3] ?
write /your/project/path/your-function-name/package.json
write /your/project/path/your-function-name/aws-lambda-config.js
write /your/project/path/your-function-name/.gitignore
write /your/project/path/your-function-name/gulpfile.coffee
write /your/project/path/your-function-name/src/index.coffee
write /your/project/path/your-function-name/src/index_spec.coffee
initialized

生成されるファイルは以下の通りです。

  • package.json
    • パッケージ情報
    • 関数名、バージョン番号、説明文の情報を含んでいます
  • aws-lambda-config.js
    • AWS Lambdaのデプロイ時に使用される設定値
    • 関数名、説明文、リージョン、IAMロールのARN、メモリサイズ、タイムアウト時間、ランタイム、ハンドラ名の情報を含んでいます
  • .gitignore
    • git用の無視リスト
  • gulpfile.coffee
    • gulpのタスクを定義したスクリプト
    • lamjet標準のタスクをインポートしています
  • index.coffee
    • Lambda関数の本体
  • index_spec.coffee
    • Lambda関数のテストスペック

4.3. パッケージのインストール

lamjetに必要なパッケージをインストールします。

$ npm install

4.4. テスト

デフォルトのテストスペックを実行します。
lamjetではテスティングフレームワークとしてJasmineを使っています。
テストを実行する過程でCoffeeScriptの変換が行われ、outディレクトリにJavaScriptが出力されます。

$ gulp
...
1 spec, 0 failures
Finished in 0 seconds
...

4.5. デプロイ

デプロイを行うためには、AWSの認証情報が必要です。
認証情報の設定方法はAWS CLIと同様、環境変数やファイルが使えます。

$ export AWS_ACCESS_KEY_ID=...
$ export AWS_SECRET_ACCESS_KEY=...

認証情報の設定が終わったら、Lambda関数をデプロイします。

$ gulp deploy

AWS LambdaのWebコンソールを確認し、Lambda関数が追加されていれば成功です。

4.6. 編集→デプロイ

Lambda関数の編集は、スクリプトの修正、テスト、デプロイという流れになります。

$ vim src/index.coffee
$ vim src/index_spec.coffee
$ gulp
$ gulp deploy

5. 最後に

素敵なAWS Lambdaライフを!