CircleCI と Serverless ( AWS Lambda ) で低コスト＆ラクラクWeb開発の雛形 Github

## 概要
CircleCI と Serverless を使ったサービスの開発環境の雛形。

## はじめに
新しくサービスを作ることになりまして、 Serverless を使うことにします。
Serverless: https://github.com/serverless/serverless

CircleCI で自動的にテスト、 AWS にデプロイするようにしておきます。
CircleCI: https://circleci.com/

Github で雛形を公開します。
https://github.com/exabugs/circleci

雛形を使って最短でプロジェクトを立ち上げる手順を以下で示します。

## 最短で試すには

1. アカウント作成
    - AWS
    - Github
    - CircleCI
1. Github から ~~clone~~ Fork
    ~~git clone https://github.com/exabugs/circleci~~
    → [間違い] Fork です。自分の Github に Fork してください。

1. CircleCI 設定

    1. 上記 ~~clone~~ Fork したリポジトリを CircleCI の処理対象にする。  
      (プライベートでも可能)

    1. AWS用の以下の環境変数を、「Environment variables」の設定に足す。  
       - AWS_ACCESS_KEY_ID 
       - AWS_SECRET_ACCESS_KEY

    ![スクリーンショット 2016-03-29 19.53.12.png](https://qiita-image-store.s3.amazonaws.com/0/69410/b4644252-8096-8388-2fdc-3af0aef7d1da.png)

1. 関数 1 個 (functions/func1) だけサンプルで入れてます。
関数を追加するには以下のコマンドで

    ```
    sls function create functions/func2
    ```

1. Pushすると、CircleCI が動作して、AWS にデプロイしてくれる。
プルリクなら、マージ前にテストしてくれる。これは便利!!

![スクリーンショット 2016-03-29 23.16.12.png](https://qiita-image-store.s3.amazonaws.com/0/69410/626f5c80-0879-f6d8-efcb-7de544e3a8c4.png)





## コード詳細

- scripts/aws_init
    AWS のクレデンシャル情報を Serverless で使えるようにするスクリプト

    ```
    AWSDIR=~/.aws
    mkdir -p ${AWSDIR}

    cat << EOS > ${AWSDIR}/config
    [default]
    region=${AWS_REGION}
    EOS

    cat << EOS > ${AWSDIR}/credentials
    [${AWS_PROFILE}]
    aws_access_key_id=${AWS_ACCESS_KEY_ID}
    aws_secret_access_key=${AWS_SECRET_ACCESS_KEY}
    EOS
    ```


- scripts/serverless.sh
    Serverless の実行スクリプト
    (初回以外は 「ServerlessError: Stage dev already exists」エラーになるが大丈夫。気にしない。)


    ```
    STAGE=dev
    OPTION="-s $STAGE -r $AWS_REGION"
    sls project init -p $AWS_PROFILE $OPTION
    sls resources deploy $OPTION
    sls function deploy $OPTION
    sls endpoint deploy $OPTION
    ```

- circle.yml

    ```
    machine:
      timezone: Asia/Tokyo

      node:
        version: 4.4.1

      environment:
        AWS_REGION: ap-northeast-1
        AWS_PROFILE: serverless-circleci_dev

      post:
        - bash ${CIRCLE_PROJECT_REPONAME}/scripts/circleci_env
        - bash ${CIRCLE_PROJECT_REPONAME}/scripts/aws_init

    test:
      override:
        - npm test

    deployment:
      production:
        branch: master
        commands:
          - npm run deploy_prod

      staging:
        branch: develop
        commands:
          - npm run deploy_staging
      ```

- s-templates.json
    http://docs.serverless.com/docs/templates-variables#section-templates

    ```
    {
      "apiRequestTemplate": {
        "application/json": {
          "httpMethod": "$context.httpMethod",
          "body": "$input.json('$')",
          "queryParams": "$input.params().querystring",
          "headerParams": "$input.params().header",
          "headerParamNames": "$input.params().header.keySet()",
          "contentTypeValue": "$input.params().header.get('Content-Type')"
        }
      }
    }
    ```

## まとめ
 - Serverless はまだβ版で、頻繁に更新されているので要注意です。
 - サーバレス (Lambda) でサービス全体を作ることができるか分からないが、とにかくチャレンジしてみます。
 - 荒い記事でスイマセン。こなれてきたら更新します。

## 付録

### CircleCI 設定ドキュメント
https://circleci.com/docs/configuration

### CircleCI 実行順序

1. INFRASTRUCTURE
    1. Starting the build
    1. Start container
    1. Enable SSH

1. CHECKOUT
    1. Restore source cache
    1. Checkout using deploy key: 

1. MACHINE
    1. Setting timezone to Asia/Tokyo
    1. Exporting env vars from circle.yml
(【定義】 circle.yml environment: )
( → Github で管理するパラメータ)

        ```
        Exporting AWS_REGION
        Exporting AWS_PROFILE
        ```

    1. Exporting env vars from project settings
(【定義】 CircleCI設定 Tweaks-EnvironmentVariables )
( → Github で管理しないパラメータ)

        ```
        Exporting AWS_ACCESS_KEY_ID
        Exporting AWS_SECRET_ACCESS_KEY
        ```

    1. set node.js version to 4.4.1
    1. Restore cache
    1. post
        1. $ npm run aws_init
        2. $ bash scripts/circleci_env
        3. $ bash scripts/aws_init

1. DEPENDENCIES
    1. Exporting NODE_ENV

        ```
        Exporting NODE_ENV
        ```

    1. Exporting PATH

        ```
        Exporting PATH
        ```

    1. $ npm install

1. DATABASE
    1. Save cache

1. TEST
    1. $ npm test

1. TEARDOWN