lambda-uploaderを使ってAWS Lambdaをリモートで開発、実行、デプロイする

## 概要
lambdaをリモートマシンで開発、実行、デプロイできるツールのインストール手順と使い方です。
pythonの[lambda-uploader](https://github.com/rackerlabs/lambda-uploader)というpipを使います。

## 環境
- CentOS6.7
- python 2.7.12
- pip lambda-uploader
- pip awscli

## pythonのインストール
こちらを参照
[python(pyenv + virtualenv) + CentOS7インストールメモ](http://qiita.com/Esfahan/items/0dfe70357549f92b23da)


## lambda-uploaderのインストール

```
$ pip install lambda-uploader
```

aws-cliも使うのでインストール

```
$ pip install awscli
```

## 初期設定
AWSの認証情報を下記コマンドで登録します。

```
$  aws configure --profile dev

AWS Access Key ID [None]: {Your Access Key Id}
AWS Secret Access Key [None]: {Your Secret Access Key}
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

## 必要なファイルを用意
下記のデイレクトリ構成でファイルを作成します。

```
|- ~/lambda-uploader/
       |- bin/
          └ lambda-exec
       |- sample-api/ # 名前はなんでも良いlambda関数一つにつき1ディレクトリ
          └ requirements.txt
          └ lambda.json
          └ index.py
          └ event.json
```

別にこの構成でなくても構いませんが、

- requirements.txt
- lambda.json
- index.py
- event.json

この4つのファイルは、1functionにつき必ず必要で、この4つは同じ階層に存在する必要があります。

### ~/lambda-uploader/bin/lambda-exec

リモート環境でlambdaを実行するためのスクリプト。
awsコマンドが長いので、下記の内容で作成し、簡単に実行できるようにします。

```bash
#!/bin/bash

FUNCTION_NAME=$1
EVENT_JSON=$2

echo ${FUNCTION_NAME}
echo ${EVENT_JSON}

aws lambda invoke \
    --invocation-type RequestResponse \
    --function-name ${FUNCTION_NAME} \
    --payload file://${EVENT_JSON} \
    /tmp/lambda_outputfile.txt

echo ''
echo '[result]'
cat /tmp/lambda_outputfile.txt
echo ''
``` 

実行権限を付与

```
$ chmod +x ~/lambda-uploader/bin/lambda-exec
```

PATHを通すため、bash_profileに下記を追記

```bash
$ vi ~/.bash_profile

export PATH=$PATH:"$HOME/lambda-uploader/bin"
```

変更を適用

```
$ source ~/.bash_profile
```

### ~/lambda-uploader/sample-api/requirements.txt

pipモジュールの一覧が書かれたファイル。
下記コマンドで生成します。

```
$ pip freeze > requirements.txt
```

### ~/lambda-uploader/sample-api/lambda.json

lambdaの設定ファイル。ここに関数名などを記載します。

```json
{
  "name": "{lambda functionの名前}",
  "description": "{lambda functionの説明}",
  "region": "ap-northeast-1",
  "handler": "index.lambda_handler",
  "role": "arn:aws:iam::123456789012:role/role-name",
  "timeout": 300,
  "memory": 128
}
```

handlerは、上記の例だと、index.pyのlambda_handler関数が実行されるという意味になります。

roleには、Lambda関数のExecution Roleのarnを定義してください。
事前別途roleの作成が必要です。

参考までに、API Gateway, SQS, SNSと連携するLambdaを作った際は、IAMロールに以下の権限を付与しました。

- AmazonAPIGatewayPushToCloudWatchLogs
- AmazonSNSFullAccess
- AmazonSQSFullAccess
- AWSLambdaFullAccess
- AWSLambdaVPCAccessExecutionRole

### ~/lambda-uploader/sample-api/index.py

Lambda関数を作成。
下記はPOSTリクエストを受け取って返すだけのサンプルです。

```py
# -*- coding:utf-8 -*-

def lambda_handler(event, context):
    text = '%s is %s years old.' %(event['name'], event['age'])
    return text
```

### ~/lambda-uploader/sample-api/event.json

テスト時に投げるPOSTリクエストの内容を定義します。(GETリクエストのテストの場合は空でOK)
※ダブルクォーテーションにしないとエラーになる

```json
{
    "name" : "Michael",
    "age" : "30"
}
```


## Lambdaをデプロイ
lambda関数をAWSにデプロイします。
lambda.json, index.pyなどがあるデイレクトリに移動してデプロイコマンドを実行します。

```
$ cd ~/lambda-uploader/sample-api
```

デプロイコマンド

```
$ lambda-uploader
```

## Lambda関数を実行
リモート環境でlambda関数を実行します。
実行するためには、先にAWSにデプロイされている必要があります。
こちらもlambda.json, index.pyなどがあるデイレクトリに移動して実行します。

```
$ cd ~/lambda-uploader/sample-api
```

下記コマンドで実行
第１引数にLambda関数名、第２引数にevent.jsonファイルを指定します。

```
$ lambda-exec {Lambda関数名} event.json
```

下記のようなresponseが帰ってくれば成功です。

```
sample-api
event.json
{
    "StatusCode": 200
}

[result]
"Michael is 30 years old."
```

以上

## 参考
[AWS Lambda Pythonをlambda-uploaderでデプロイ](http://dev.classmethod.jp/cloud/deploy-aws-lambda-python-with-lambda-uploader/)