circleciによりgithub flowを使ったプロジェクトのAWSへ自動デプロイまで


# なぜなのか？

いいもの作りたいですよね？
自分が作ろうとしている機能やサービスは、エンドユーザが使うまで、本当に解決しようとしている課題が解決されるだろうか？

残念ながら、自分が想定している使い方とエンドユーザ実際に使うときの使い方にはだいたいギャップが発生してしまいます。バグ対応はもちろんですが、いいもの作りには、そのギャップを素早く検知することです。その発見できるように、エンドユーザが機能・サービスを使ってもらうのが一番。

そこで、安全にスピードを出すため、CI/CDが必須な道具になってきました。

今回は、AWS Lambdaで動作するSlackBotを例にして、[github-flow](https://qiita.com/mint__/items/bfc58589b5b1e0a1856a#github-flow%E3%81%A8%E3%81%AF)に合うcircleciで自動テスト・デプロイできる方法の一つを紹介します。

## 前提条件

- awscli
- AWSアカウント
- envsubst [macos](https://stackoverflow.com/questions/23620827/envsubst-command-not-found-on-mac-os-x-10-8) [ubuntu]()


## SlackBotを用意

今回は、サンプルプロジェクトを用意しました。（フォークして、やってみてください）
[lambda-slackbot-example](https://github.com/monkut/lambda-slackbot-example)

（英語ですが。。。）そこのREADMEにしたがって、初期状態を用意します。

## AWS自動デプロイ準備

自動デプロイまでできるようにAWSの準備が必要になります。
ここからは、すでに、上記のSlackBotを一回デプロイできた前提で進みます。

まず、 準備したいのが、デプロイ用のユーザとそのユーザがでするときに使うロール。

1. ユーザとアクセスキーを作成

```
aws iam create-user --user-name deploy-user
{
    "User": {
        "Path": "/",
        "UserName": "deploy-user",
        "UserId": "{USERID}",
        "Arn": "arn:aws:iam::{ACCOUNT}:user/deploy-user",
        "CreateDate": "2018-12-12T15:36:15Z"
    }
}

aws iam create-access-key --user-name deploy-user
{
    "AccessKey": {
        "UserName": "deploy-test",
        "AccessKeyId": "{ACCESS_KEY_ID}",
        "Status": "Active",
        "SecretAccessKey": "{SECRET_ACCESS_KEY}",
        "CreateDate": "2018-12-12T15:38:01Z"
    }
}
```

2. デプロイ用のロールを作成

    > lambda-slackbot-example にポリシーのテンプレートを置いたので、それをつかって、ロール作成する。

```
# policyを用意
export BUCKET_NAME=tobor-zappa-UNIQUERANDOMSUFFIX
export ACCOUNT_ID=AWS_ACCOUNT_ID_USED
export REGION=REGIONNAME
export FUNCTION_NAME=tobor-dev
export STACK_NAME=STACKNAME_OF_ZAPPA_DEPLOYMENT_STACK
envsubst < ./infrastructure/aws/zappa-deployment-role-policy.json.template > ./zappa-deployment-role-policy.json

# policy 作成
aws iam create-policy --policy-name zappa-deployment-role-policy --policy-document file://./zappa-deployment-role-policy.json

# assume-role-policyを用意
envsubst < ./infrastructure/aws/assume-role-policy.json.template > ./assume-role-policy.json

# role作成
aws iam create-role --role-name zappa-deployment-role --assume-role-policy file://./assume-role-policy.json 

# policyをロールにattach
aws iam attach-role-policy --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/zappa-deployment-role-policy --role-name zappa-deployment-role   
```

## CircleCIの連携

今回の目的は、マスターにマージされたら、自動デプロイがはしります。
そのため、config.yml内には、`workflows`を使っています。`workflows`のなかで、上記の定義に参照している２つ部分があります。

> lambda-slackbot-exampleで[.circleci/config.yml](https://github.com/monkut/lambda-slackbot-example/blob/master/.circleci/config.yml)を参照

- build
- deploy

`build`内で、テスト用の環境を準備して、テストを実行します。

`deploy`内で、実際にAWSへデプロイする定義になります。

マスターのみの場合デプロイというのが、`filters` で制御しています。

```

workflows:
  version: 2
  test-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only:
                - master

```

1.　circleciのプロジェクト上で下記のEnvironment Variablesを設定

- AWS_ACCESS_ROLE_ARN 
- AWS_DEFAULT_REGION
- AWS_PROFILE

これですべてが正しく設定されているとPRができたら、コードチェックとテストが走ります。
PRがマスターにマージしたら、コードチェックとテストが成功すれば、次デプロイが走ります。

## まとめ


今回、[github-flow](https://qiita.com/mint__/items/bfc58589b5b1e0a1856a#github-flow%E3%81%A8%E3%81%AF)を考案したCircleCIの設定を説明しました。

自動デプロイできるまでは、多少の時間がかかるのですが、一回設定しちゃいば、開発者がgithub上でPRのレビューなどに集中ができて、プロジェクトには、新しいAWSリソースを使わない限り、AWSへのログインなどが不要になります。