WerckerでIP制限をかけたs3のバケットからkeystoreを取得しassembleReleaseを実行する

この記事は[AndroidのCI環境をCircleCIからWerckerにした話](https://speakerdeck.com/horie1024/androidfalsecihuan-jing-wocirclecikarawerckernisitahua)に関連した投稿です。

AndroidアプリのCI/CDをどう行うのかを考えるとkeystoreやkey.p12などのファイルを何処に置くか？が問題になることがあります。Androidプロジェクトのリポジトリに含めてしまう事もできますが、セキュリティの観点からできるだけ避けたいです。

今回試してみたのは、keystoreなどのファイルをIP制限をかけたs3のバケットに置き、それを[Wercker](http://wercker.com/)から取得する方法です。

keystoreをs3から取得し`./gradlew assembleRelease`を実行するwercker.ymlを作成してAndroidプロジェクトのビルドを実行してみます。

# s3のバケットにIP制限をかける
IP制限のかけかたは[こちら](http://qiita.com/you_matz/items/b3885891e576f5604323)の記事が参考になります。実際にAWS Policy Generatorで作成したポリシーは以下のようになり、IPアドレス`192.168.1.1`からのアクセスのみを受けつけます。

```json
{
	"Version": "2012-10-17",
	"Id": "Policy***********",
	"Statement": [
		{
			"Sid": "Stmt**********",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::android/*",
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": [
						"192.168.1.1"
					]
				}
			}
		}
	]
}
```

# Werckerが使用するIPアドレスをWhitelistとして登録

Werckerのコンテナが使用するIPのリストは以下のページから確認できます。

* https://devcenter.wercker.com/supplementary-information/faqs/what-ip-to-whitelist/

IPリストは以下のファイルを参照することで確認できます。WerckerがDockerコンテナを利用位してる関係上、このドキュメントに記載されているIPアドレスは予告なしに変更される可能性があります。

* https://s3.amazonaws.com/status.wercker.com/worker_ips/production/public
* https://s3.amazonaws.com/status.wercker.com/worker_ips/production/public.json

このIPリストをポリシーに追加し、バケットのバケットポリシーの編集をクリックすると開くバケットポリシーエディタに貼り付けて保存します。

```json
{
	"Version": "2012-10-17",
	"Id": "Policy***********",
	"Statement": [
		{
			"Sid": "Stmt**********",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::android/*",
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": [
						"54.197.9.30",
						"54.82.165.74",
						"54.175.16.217",
						"52.91.36.246",
						"52.23.225.139",
						"54.174.181.26",
						"54.174.253.237",
						"52.90.118.64",
						"54.89.129.133",
						"52.90.236.213",
						"52.23.211.102",
						"54.236.255.39",
						"54.237.192.172",
						"54.173.172.47",
						"52.87.170.39"
					]
				}
			}
		}
	]
}
```

# s3からkeystoreを取得しassembleReleaseを実行するwercker.ymlの作成

これでIP制限をかけたs3にkeystoreを置いておけばWerckerのビルド環境から取得することができます。実際にkeystoreを取得してビルドすることが可能か確認するために以下のようなwercker.ymlを用意します。kestoreのパスはWerckerの環境変数に登録しておきます。boxにはAndroidのビルドが可能なDocker Imageとして予め用意した[horie1024/wercker-android-build](https://hub.docker.com/r/horie1024/wercker-android-build/)を使用しています。

```yaml
box: horie1024/wercker-android-build:0.1
build:
  steps:
    - script:
        name: fetch file from s3
        code: |
          wget <s3に配置したkeystoreのパス> -P app/
    - script:
        name: assembleRelese
        code: |
          ./gradlew assembleRelease
```

このwercker.ymlで定義した処理の流れは以下のようになります。

1. wgetでs3からkeystoreを取得
2. assembleReleaseを実行

アプリ側のbuild.gradleには署名の設定を以下のように設定しておきます。

```
android {
    signingConfigs {
        release {
            storeFile file('keystore')
            storePassword YOUR_STORE_PASSWORD
            keyAlias YOUR_KEY_ALIAS
            keyPassword YOUR_KEY_PASSWORD
        }
    }
}
```

# Androidプロジェクトのビルド
wercker.yamlをAndroidプロジェクトのトップに置きGitHubにプッシュするとWerckerでビルドが開始されます。そして以下のようにkeystoreがs3からダウンロード後Androidプロジェクトに配置され、`./gradlew assembleRelease`でのビルドも問題なく実行できました。

![wercker_android_1.png](https://qiita-image-store.s3.amazonaws.com/0/43438/eff2fc71-ec8f-8483-4216-d0e9c7cf6924.png "wercker_android_1.png")