【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第1章 〜nodejsのtemplate利用編〜

# 【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第1章 〜nodejsのtemplate編〜

## あらすじ
毎年バレンタインデーの時期になると、スギ花粉で体調が絶不調になります。
痒い目を擦りながら、鼻をかみながら必死でこの投稿をしています。

[会社にジョイン](https://www.wantedly.com/companies/temona/post_articles/41409)してから、もう２年くらい経ちました。
今回からは少し話題になっている「サーバーレスアーキテクチャ」というネタをシリーズで公開したいと思います。

※後々、リクエストに応じて更新することが多いのでストックしておくことをおすすめします。

自分は某社でCTOをしていますが、頭でっかちに理論ばっかり学習するよりは、イメージがなんとなく掴めるように学習し、実践の中で知識を深めていく方が効率的に学習出来ると考えています。

教育スタイルとしては正しい事をきっちりかっちり教えるのではなく、未経験レベルの人がなんとなく掴めるように、資料を構成していきます。

以下のようなシリーズネタで進めます。

|No.|記事|
|:-----------|-----------|
|1|[【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第1章 〜nodejsのtemplate利用編〜](http://qiita.com/devopsCoordinator/items/974a6e1b92a564f25a15)|
|2|[【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第2章 〜API Gateway利用編〜](http://qiita.com/devopsCoordinator/items/46fdce5f0356bcd35a7d)|
|3|[【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第3章 〜DynamoDB利用編〜]|

では、今回もはじめていきましょう！

## はじめに

サーバーレスアーキテクチャとは字の如く、サーバーがないアーキテクチャです。
AWSでいうところのEC2インスタンスすら必要なく、予め用意された機能のサービス(Function-as-a-Service)を組み合わせたアーキテクチャの事を言います。
FaaSなどと言われたりしますが、AWSでもサーバーレス系のサービスが増えていますね。

今回はサーバーレス用フレームワークとして開発が進んでいる[serverless](https://github.com/serverless/serverless)を使って
AWS Lambda、AWS API Gateway, AWS DynamoDBなどを組み合わせたサーバーレスアーキテクチャを体験してみましょう。

## 環境

### Mac環境
```shell-session
10.11.6
```

### node環境

```shell-session
$ nodebrew ls

v0.12.14
```

```shell-session
$ nodebrew install-binary v7.4.0
```

```shell-session
$ nodebrew ls
v0.12.14
v7.4.0
```

### python環境

```shell-session
$ pyenv versions
  system
  2.7.12
```

```shell-session
$ pyenv install -v 3.5.2
```

```shell-session
$ eval "$(pyenv init -)"
```

```shell-session
$ pyenv shell 3.5.2
```

```shell-session
$ python --version
Python 3.5.2
```

### awscli環境
```shell-session
$ pip install awscli
```

```shell-session
$ aws --version
aws-cli/1.11.9 Python/2.7.10 Darwin/15.6.0 botocore/1.4.66
```

### serverless環境

```shell-session
$ npm install serverless -g
```

```shell-session
$ serverless --version
1.5.1
```

## serverless テスト用IAMを作成

### IAMを作成する

ユーザー名: serverlesstest
アクセスの種類: プログラムによるアクセス

![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/3887f315-d5ec-c857-7fbc-6202343e48c8.png)

#### 既存のポリシーを直接アタッチ

![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/76e1bc0b-a8eb-234c-56d1-96830c2860f7.png)

- AWSLambdaFullAccess
- IAMFullAccess
- AmazonS3FullAccess
- AmazonAPIGatewayAdministrator
- AWSCloudFormationReadOnlyAccess

#### 独自のポリシーを作成

ポリシー名:AWSCloudFormationCreateUpdateServiceOnlyAccess
ポリシー概要: サーバーレスを試すために必要なポリシーを設定しています。※本番環境では利用しないでください。

![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/8aa775d6-23ea-1c07-736e-1181862808e3.png)

画像の赤枠の「独自のポリシーを作成」を押下し
以下の文字列をポリシードキュメントへコピーしてください。

```shell-session
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1449904348000",
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:UpdateStack"
            ],
            "Resource": [
                "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxxxxxx:stack/*"
            ]
        }
    ]
}
```

「ポリシー名」、「説明」、「ポリシードキュメント」を入力すると以下の画面のようになります。

![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/676def44-81b7-c692-1617-934f74108acf.png)

ポリシーの作成を押下したら、IAMの作成画面に戻り「更新」を押下し、チェックボックスを選択してください。
※検索をするとタイプがユーザーのよる管理の独自に作ったポリシーが表示されているはずです

![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/6bd62c6b-cce7-5eae-089e-1139dce66ef0.png)


![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/ac5ef34e-a553-827e-a0d6-49fc97b5f8a1.png)

![IAM_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/20fa9cb2-6bb7-ef9a-7549-a0d16906e100.png)

## AWS CLIの新規ユーザーの設定

いちいちcredentialsの中身をコメントイン・コメントアウトするのも面倒なので
自分はAWS CLIをプロファイル毎管理してます。

今回はprofile名「serverlesstest」で作成しましょう。

| ファイル | 備考 |
|:-----------|:------------|
| ~/.aws/config       |    認証情報以外の情報(リージョンやフォーマットなど)     |
| ~/.aws/credentials       |    認証情報     |


### AWS CLIの設定作成

```shell-session
$ aws configure --profile serverlesstest
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
```
**例) ~/.aws/config**

```shell-session
$ cat ~/.aws/config
[profile serverlesstest]
output = json
region = ap-northeast-1
```

**例) ~/.aws/credentials**

```shell-session
$ cat ~/.aws/credentials
[serverlesstest]
aws_access_key_id = XXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXX
```

## serverless templateからプロジェクトを作成
今回はnodejsのテンプレートから作成します。
 
```shell-session
$ serverless create --template aws-nodejs --provider aws --profile serverlesstest --path serverlesstest --verbose
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/xxxxxxxxxxx/Documents/serverlesstest"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.5.1
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"
```

### 生成されるファイル

```shell-session
% ls ./serverlesstest
handler.js
serverless.yml
```

### 設定変更

設定箇所は「profile」、「stage」、「region」です。

```shell-session
$ cd serverlesstest
$ vi serverless.yml
```

#### 変更箇所

```
provider:
  name: aws
  runtime: nodejs4.3
```
⇣⇣⇣⇣⇣ 

```
provider:
  name: aws
  runtime: nodejs4.3
  profile: serverlesstest
  stage: dev
  region: ap-northeast-1
```

## デプロイ

```shell-session
$ serverless deploy --provider aws --profile serverlesstest -v
```

無事に成功すると以下のような画面となる。

![1__noriyukinakano_0031nakano-mac____Documents_02_work_serverlesstest__zsh_.png](https://qiita-image-store.s3.amazonaws.com/0/74153/f31ea7c8-fdf5-19f0-46fa-0d205a70d734.png)

## AWSの各サービス確認


### Lambda

![Lambda_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/af5d5bb2-63e4-5766-a620-fd103d2b9229.png)


![Lambda_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/7edd70cf-aabe-eeef-2116-01d17ed77c6c.png)

### S3

![S3_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/74153/884c40a0-ea5b-25ca-d992-9d0202968af3.png)


## Lambdaの実行

「invoke」コマンドを利用してLambdaの実行してみましょう。
以下のように、helloというファンクションを実行してみます。 

```shell-session
$ serverless invoke --function hello --provider aws --profile serverlesstest
{
    "statusCode": 200,
    "body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":{}}"
}
```

### 処理内容

テンプレートとして、生成された「handler.js」の中身を見てみましょう。
レスポンスとしては、ステータスコードとして200でメッセージの中身を返していますね。

```shell-session
$ cat handler.js
'use strict';

module.exports.hello = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,
    }),
  };

  callback(null, response);

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
};
```

# 編集後記
今回の状態でも、雰囲気はつかめたかなと思います。このままではendpointも公開されておらず、外部から使えないため
次回はAWSのAPI Gatewayを利用してサンプルアプリケーションを少し修正して動かしてみましょう。