ElasticBeanstalkでDrone.ioを試してみる

Jenkinsに嫌気がさしてきたので代わりを探し中でDrone.ioのOSS版さわってみた。

現状ソースの管理にBitbucket使っていてCIでDockerもバリバリ使いたい。
でも、Bitbucketに対応したDockerコンテナが扱えるCIのSaaSはあまりない印象。
Bitbucket Pipelineも出てきたがDocker in Dockerが無理そうでDockerのビルドや複数コンテナのrunが出来なさそう。

Drone.ioのSaaS版はPrivateリポジトリを扱おうとすると有料だが、そんなところにOSS版があるのを知って触ってみた。

# Drone.ioについて

[Drone.ioのご紹介](http://www.slideshare.net/udzura/droneio) がわかりやすかった。

# Drone.io環境の構築

基本的に[Overview · Drone](http://readme.drone.io/setup/overview/)の通りでいけた。

### BitbucketのOAuth設定

Bitbucketの設定の「OAuth」で[Bitbucket Cloud · Drone](http://readme.drone.io/setup/remotes/bitbucket/#bitbucket-registration:217ff7ed75501b6aa8d4f1057fed857c)に従って設定。
クライアントIDと鍵とシークレットをメモしておく。

* Callback URLに[drone環境のURL]/authorize
* 権限は以下の通りに設定

```
    Account:Email
    Account:Read
    Team Membership:Read
    Repositories:Read
    Webhooks:Read and Write
```

### RDSの作成

 * mysqlのRDSインスタンスを作成。
 * [Database · Drone](http://readme.drone.io/setup/database/#mysql:1e080c892326e5bba749587eba8bcf9e)にある通りdroneデータベースも作成しておく。

```bash
$ mysql -u [DBユーザ名] -p -h [RDSエンドポイント] -e 'create database if not exists drone;'
```

### ElasticBeanstalk環境の構築

マルチコンテナ環境を作って以下のアプリをデプロイ。

* Dockerrun.aws.json

```json
{
  "AWSEBDockerrunVersion": "2",
  "volumes": [
    {
      "name": "drone",
      "host": {
        "sourcePath": "/var/lib/drone"
      }
    },
    {
      "name": "docker",
      "host": {
        "sourcePath": "/var/run/docker.sock"
      }
    }
  ],
  "containerDefinitions": [
    {
      "name": "drone",
      "image": "drone/drone",
      "memory": 128,
      "essential" : true,
      "environment": [
        {
          "name": "REMOTE_DRIVER",
          "value": "bitbucket"
        },
        {
          "name": "REMOTE_CONFIG",
          "value": "https://bitbucket.org?client_id=[OAuthの鍵]&client_secret=[OAuthのシークレット]"
        },
        {
          "name": "DATABASE_DRIVER",
          "value": "mysql"
        },
        {
          "name": "DATABASE_CONFIG",
          "value": "[DBユーザ]:[DBパスワード]@tcp([RDSエンドポイント]:3306)/drone?parseTime=true"
        },
        {
          "name": "DRONE_ADMIN_ALL",
          "value": "true"
        }
      ],
      "mountPoints": [
        {
          "sourceVolume": "drone",
          "containerPath": "/var/lib/drone"
        },
        {
          "sourceVolume": "docker",
          "containerPath": "/var/run/docker.sock"
        }
      ],
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 8000
        }
      ]
    }
  ]
}
```

### ELBのアクセス制限

ELBのアクセス制限をする場合は、BitbucketのWebHookを受け取るために以下のIPからのアクセスを許可しておく。
[What are the Bitbucket Cloud IP addresses I should use to configure my corporate firewall - Atlassian Documentation](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html)

2016/07/07時点で以下

```
104.192.143.192/28
104.192.143.208/28
```

### リポジトリのActivate

Drone.ioにログインしてAvailable Repositoriesから連携したいリポジトリをActivateする。

### BitbucketへのSSHキーの登録

Drone.ioでActivateしてActiveになったリポジトリのSETTINGSからPublic Keyの値をコピーしてBitbucketの設定の「SSHキー」に登録する。

### Trustedオプションの設定

Drone.ioで該当リポジトリのSETTINGSのTrustedオプションをオンにする。
※ オンにしないと.drone.ymlでvolumesやprivilegedオプションなどが使えない([参照](http://readme.drone.io/usage/build_test/))。
※ Adminユーザでないと設定変更できないのでDockerrun.aws.jsonでDRONE_ADMIN_ALLをtrueにしている(全ユーザAdmin扱い)。

# WebHookを試してみる

以下のファイルとDockerfileをリポジトリに配置してコミット&プッシュ。
=> Drone.ioでのビルド成功

* .drone.yml

```yaml
build:                                                                  
  image: docker:latest
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  commands:
    - docker build -t test .
```

# 環境構築でハマったこと

### Drone.ioのSETTINGSの変更

* 現象：Drone.ioで該当リポジトリのSETTINGSを変更しても反映されない。
* 原因：SETTINGSの変更はPATCHメソッドで実行されていたがプロキシが対応しておらず400でエラーになっていた(ブラウザのネットワークの通信を見てわかった)。
* 対応：一時的に外部からのアクセスを許可してプロキシを利用しないで設定変更、、、

### その他

* ElasticBeanstalkのEC2ロールの不備で環境作成失敗
* Bitbucketからのアクセスを許可していないくてWebHookが実行されない

# 試してみた感想

まだディープに触ってないがいい感じ。
公式のドキュメントがあってdockerコンテナで構築しやすいところが良い。