概要
APIの量産が必要になったものの、複数人でAPIを量産しているとSwaggerのPRも量産されてく。
Swaggerのレビューはyamlを見てレビューするわけだけど、わざわざSwaggerのプレビューをするためにブランチにチェックアウトしてpullしてサーバー立てるのはしんどい・・・。
なんで、SwaggerリポジトリにPull Requestが立つ毎(& Commit毎)にGAEにデプロイさせて、GAEでSwaggerを確認できるようにしてレビューのフローを改善させるのがモチベーション
なんでGAE
- GAE/SEは安い。
- リクエスト毎にインスタンスが起動され、リクエストが来なくなれば一瞬で落ちる。
- 無料枠もある
- 開発メンバーで行うSwaggerのレビューレベルであれば実質タダ
- IP制限
- Cloud Storageだと制限がかけられない問題
- プロジェクトがGCPではなくAWSだったらS3使ってた案件。
- 複数PRのプレビューを用意することが可能
- GAEのバージョン機能は古いバージョンもURLを知っていればアクセス可能。
- このURLは予測可能なURLが取得できる
- e.g. https://<バージョン番号>-dot-<サービス名>-dot-<GCPプロジェクト名>.appspot.com
- バージョン番号は任意の文字列を設定可能
- バージョン番号をPR番号にすることで他のPRと競合せずに公開可能!GAEすごい!
- GAEのバージョン機能は古いバージョンもURLを知っていればアクセス可能。
やったこと
1. SwaggerリポジトリをGitHub Pagesに対応させる
- Swagger専用リポジトリが無ければ作成& Swaggerの定義ファイルをリポジトリへ配置
"gh-pages"
ブランチを作成&チェックアウト- Swagger UIリポジトリから静的ファイルを取得してルートに配置
- 追加したindex.html で Swaggerの定義ファイルをリポジトリに対応させたパスへ変更
- https://github.com/swagger-api/swagger-ui/blob/dc7d7054bfde0003334b755f26cbc31d36fa6cfb/dev-helpers/index.html#L46
- e.g.
url: "swagger/merged.yml",
- pushしてGitHub Pagesが見れることを確認
2. GCPでサービスアカウントの作成
GCPのGAEデプロイ権限のついたアクセストークンを発行してキーファイルをダウンロード。
権限はだいたいこんな感じで通った。たぶん最小。
- App Engine コード閲覧者
- App Engine サービス管理者
- App Engine デプロイ担当者
- ストレージオブジェクト閲覧者
- ストレージのオブジェクト作成者
3. CircleCIのリポジトリ登録と環境変数の設定
- CircleCIへリポジトリの登録
- サイドバーの「ADD PROJECT」からSwaggerリポジトリをフォロー
- CircleCIのフックをPRのみに限定
- サイドバーの「SETTING」 > 「Projects」 > 「<Swaggerリポジトリ>」の右端の歯車マーク > 「Advanced Setting」 > 「Only build pull requests」をOnに設定
- 環境変数の設定
- サイドバーの「SETTING」 > 「Projects」 > 「<Swaggerリポジトリ>」の右端の歯車マーク > 「Advanced Setting」 > 「Environment Variables」 > 「ADd Variable」
CircleCIの環境変数
環境変数名 | 説明 |
---|---|
GCP_PROJECT | GCPのプロジェクト名を入力 |
SWAGGER_SERVICE_ACCOUNT_CREDENTIAL | サービスアカウントのキーファイルをbase64したものを登録 |
GITHUB_TOKEN | GitHubのトークン。リポジトリ閲覧権限とコメント権限がついたものを作成して渡す |
4. GCPデプロイ用Dockerの作成
CircleCI上でGAEのデプロイを行うためのDocker。
やってることは、
- googleの各種コマンド入りDockerイメージを使う。
- (Swaggerリポジトリの)ファイルをDocker内へコピー
- CMDで認証からデプロイまでを行う(環境変数を使いたい&シェルスク用意したくないためCMDで無理やり行った。
- サービスアカウントの秘密鍵JSONを復元
echo $SERVICE_ACCOUNT_CREDENTIAL | base64 --decode > /tmp/service-account.json
- 秘密鍵JSONをもとに認証
gcloud auth activate-service-account --key-file /tmp/service-account.json --project $PROJECT
- GAEへデプロイ
yes Y | gcloud app deploy --version $GAE_VERSION
- サービスアカウントの秘密鍵JSONを復元
Dockerfileの作成
FROM google/cloud-sdk:slim WORKDIR /app COPY . /app CMD bash -c "echo $SERVICE_ACCOUNT_CREDENTIAL | base64 --decode > /tmp/service-account.json && gcloud auth activate-service-account --key-file /tmp/service-account.json --project $PROJECT && yes Y | gcloud app deploy --version $GAE_VERSION"
5. GAEデプロイコンフィグの作成
php5.5が楽そうだったのでphp5.5を採用
app.yaml
の作成後、Swaggerリポジトリの直下へ配置
やってることは簡単で以下の3つだけ。
1. GAE/SEのphp5.5を指定
2. swagger用サービスを作成
- GAEの名前空間的なもの。
3. 各種パスでどのファイルにルーティングするかの設定
- 静的ファイルっぽいのをわちゃわちゃ書いておく。
- swaggerの定義ファイルはyaml。yamlを追加するの大事。
app.yamlの作成
runtime: php55 service: swagger handlers: - url: / static_files: index.html upload: index.html - url: /(.+\.(html|css|js|gif|png|jpg|map|yaml|yml|))$ static_files: \1 upload: (.+\.(html|css|js|gif|png|jpg|map|yaml|yml|))$
6. CircleCIコンフィグの作成
雑に解説すると...
- CircleCIをVMで起動
- 環境変数からPRの番号を取り出す
- デプロイ用Dockerのビルド
- Dockerを走らせ、GAEへデプロイ
- 1~4 のJobの完了後、PRへGAEのURLを通知
config.ymlを眺める
version: 2 jobs: deploy: machine: true steps: - checkout - run: name: set up environment variables command: | cat <<EOS > envs.txt export PR_NUM=`echo $CI_PULL_REQUEST | sed -r 's/.*\/([0-9].*)$/\1/'` export GAE_URL=https://`echo $CI_PULL_REQUEST | sed -r 's/.*\/([0-9].*)$/\1/'`-dot-swagger-dot-${GCP_PROJECT}.appspot.com/ EOS - run: name: docker build command: docker build -t swagger . - run: name: gcloud deploy command: | source envs.txt docker run -e GAE_VERSION=$PR_NUM -e SERVICE_ACCOUNT_CREDENTIAL=$SWAGGER_SERVICE_ACCOUNT_CREDENTIAL -e PROJECT=$GCP_PROJECT swagger - run: name: comment GAE URL to Pull Request command: | source envs.txt curl -v -X POST https://api.github.com/repos/${CIRCLE_PR_USERNAME}/${CIRCLE_PR_REPONAME}/issues/${PR_NUM}/comments \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"body\":\"$GAE_URL\"}" workflows: version: 2 build_and_test: jobs: - deploy
所感
GAEのサービスとバージョニング機能でURLが生成できて、なおかつ無料枠とIP制限が良い感じにマッチして良い