Serverless Frameworkならすぐ出来るよね AWSでサーバーレス（API+Lambda[java]を簡単セットアップ）


# はじめに
* [Serverless Conf Tokyo](http://tokyo.serverlessconf.io/)の[自分の登壇の中](http://www.slideshare.net/ukitiyan/iotgps-2)でも触れてますが、ServerlessでやってるとコードやBuild+Deployの管理がバラバラになり、メンテナンス性が欠如しがちです。
* そこら辺のソリューションをフレームワークとして提供してくれるのが[Serverless Framework](https://github.com/serverless/serverless)です:beer:
* [License](https://github.com/serverless/serverless/blob/master/LICENSE.txt) は、MIT Licenseです。
* 本記事ではセットアップとHello Worldをやってみます。次記事でもう少し深掘りしますので。
* Serverless Frameworkでは、LambdaのTemplateとして、以下が用意されています。今回は弊社内で一番知られているjava-mavenを採用します。
  * aws-nodejs
  * aws-python
  * aws-java-maven
  * aws-java-gradle
  * aws-scala-sbt
  * aws-csharp
* 因みに、Lambdaはjava遅いって思ってる方は以下のスライドを読みましょう。<br>
http://www.slideshare.net/keisuke69/tune-up-aws-lambda

# 環境のセットアップ
![Serverless Framework](https://s3-us-west-2.amazonaws.com/assets.site.serverless.com/images/home_framework_v1_1.png)

## Serverless Frameworkのインストール

* npmから一発です。

```
$ node -v
v5.12.0
$ npm install -g serverless
$ serverless —version
1.5.1
```

## AWS CLIのセットアップ

* AWS CLIを叩くのでインストールします。（インストール済の場合は読み飛ばしてください）

```
$ pip install awscli
```

* 管理者権限のIAMユーザを用意して、ユーザ情報をセットします。

```
$ aws configure
AWS Access Key ID [None]:(Access Key)
AWS Secret Access Key [None]:(Secret Key)
Default region name [None]: ap-northeast-1
Default output format [None]:json
```

# Serverless FrameworkでDeploy

## Serviceの作成

* 以下のコマンドでテンプレートを作成します。

```
$ serverless create --template aws-java-maven --path myService
・
・
Serverless: Successfully generated boilerplate for template: "aws-java-maven"
Serverless: NOTE: Please update the "service" property in serverless.yml with your service name
```

## STS(Eclipse)にインポート

* STSを起動して、Project Explorer -> 右クリック -> Maven -> Existing Maven Projectsで先程作成した「myService」フォルダを選択します。

## serverless.yml の修正 + Build

* serverless.ymlのL20 周辺の設定を以下のように指定します。

```yaml:serverless.yml
provider:
  name: aws
  runtime: java8
  stage: prod
  region: ap-northeast-1
```

* プロジェクトを右クリック -> Run As -> Maven Install でビルドします。
* target配下にhello-dev.jarが出来上がります。

## Deploy その１（Lambdaのみ）

* Serveress Frameworkでは、以下のコマンド一発でLambdaのセットアップ、JarのアップロードをCloudFormationを使って実行してくれます。

```
$ cd myService
$ serverless deploy -v
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (1.98 MB)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - aws-java-maven-prod
・
・
Serverless: Stack update finished...
Service Information
service: aws-java-maven
stage: prod
region: ap-northeast-1
api keys:
  None
endpoints:
  None
functions:
  aws-java-maven-prod-hello: arn:XXXXXXXX
```

* 今までのコンソールでLambdaセットアップして、Jarアップロードしてみたいな作業がががです。

* invokeコマンドでLambdaが反応するか確認します。

```
$ echo '{"key1":"value1","key2":"value2","key3":"value3"}' > event.json
$ serverless invoke --function hello -p event.json
{
    "statusCode": 200,
    "body": "{\"message\":\"Go Serverless v1.x! Your function executed successfully!\",\"input\":{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}}",
    "headers": {
        "X-Powered-By": "AWS Lambda & serverless"
    },
    "isBase64Encoded": false
}
```

## Deploy その２（API Gateway+Lambda）

* 上記では、endpoints が無いのでAPI Gateway+Lambdaとなるよう、設定を変更して、再度Deployします。
* 先程のserverless.ymlのL51 周辺のfunction句のコメントアウトを外します。

```yaml:serverless.yml
functions:
  hello:
    handler: com.serverless.Handler
    events:
      - http:
          path: users/create
          method: get
```

* 再度Deployします。

```
$ serverless deploy -v
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (1.98 MB)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - aws-java-maven-prod
・
・
Service Information
service: aws-java-maven
stage: prod
region: ap-northeast-1
api keys:
  None
endpoints:
  GET - https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/users/create
functions:
  aws-java-maven-prod-hello: arn:XXXXXXXX
```

* endpointに向けてリクエストして、反応するか確認します。

```
$ curl https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/users/create
{"message":"Go Serverless v1.x! Your function executed successfully!","input":{"resource":"/users/create","path":"/users/create","httpMethod":"GET","headers":{"Accept":"*/*","CloudFront-Forwarded-Proto":"https","CloudFront-Is-Desktop-Viewer":"true","CloudFront-Is-Mobile-Viewer":
・
・
```

## Stackの削除

* 以下のコマンドで、上記で作成したCloudFormationのStackごと削除できます。

```
$ serverless remove
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
.....................
Serverless: Stack removal finished...
```


# まとめ
* これで、もっともっとServerlessが楽しくなりそうです。
* 近日中にもう少し深掘りしたネタを投稿する予定です。