はじめに
go111 の登場で、Cloud Build を使えば設定ファイル1つで自動デプロイ出来るようになったはずでした。
steps:
- name: 'gcr.io/cloud-builders/gcloud'
  args: ['app', 'deploy', '--project=$PROJECT_ID', 'gae/app/app.yaml']
monorepo なら private repository でも上記の設定でデプロイ出来ます。
しかし、manyrepo をやろうと本体と別の private repository を参照するとデプロイ出来なくなります。
我々が Cloud Build のトリガーに設定するプロセス(以下「Cloud Build(Trigger)」)とは別に、gcloud app deploy によって実行される Cloud Build のプロセス(以下「Cloud Build(GAE)」)があり、後者は go.mod を見つけると依存を自動解決します。
非常に素敵なのですが、sshの鍵だったりトークンだったり何も設定できないため、プライベートレポジトリが go.mod に含まれると必ず失敗します。
前段でgo mod vendorし、go.modをdeployしない
Cloud Build(Trigger) 側で go mod vendor し、更に .gcloudignore に go.mod を指定して gcloud app deploy すれば解決します。
vendor ディレクトリごと GCS にアップロードするので、.gcloudignore に vendor を含めてはいけません。
まとめ
- go111 のプロジェクトを gcloud app deployすると Cloud Build による deploy が実行される
- この際に実行される Cloud Build に対しては何も設定出来ない
- 
go.modを含む場合、自動で go get し、そこにプライベートレポジトリがあると失敗する
- 
.gcloudignoreでgo.modを除外指定していれば自動で go get されない
- そのかわり、vendorを.gcloudignoreに指定せず、go mod vendor後にgcloud app deployする
- 
vendorディレクトリごと Upload され、go getも行われないので deploy は成功する
- 一連の作業を Cloud Build で自動化する為の cloudbuild.yamlがこちら
steps:
- name: 'gcr.io/cloud-builders/go:alpine'
  entrypoint: sh
  args:
    - -c
    - |
      mv `find /workspace -maxdepth 1 ! -name go` ./
      git config --global url."https://$$GITHUB_TOKEN:x-oauth-basic@github.com/".insteadOf "https://github.com/"
      go mod vendor
      find /workspace
  dir: 'go/src/github.com/YOUR_ORG/YOUR_PROJECT'
  env:
    - 'GOPATH=/workspace/go'
    - 'GO111MODULE=on'
  secretEnv: ['GITHUB_TOKEN']
- name: 'gcr.io/cloud-builders/gcloud'
  args:
    - 'app'
    - 'deploy'
    - '--project=$PROJECT_ID'
    - 'app/app.yaml'
  dir: 'go/src/github.com/YOUR_ORG/YOUR_PROJECT'
  env:
    - 'GOPATH=/workspace/go'
    - 'GO111MODULE=off'
secrets:
- kmsKeyName: 'projects/YOUR_GCP_PROJECT_ID/locations/global/keyRings/github-tokens/cryptoKeys/github-deploy-token'
  secretEnv:
    GITHUB_TOKEN: 'YOUR_ENCRYPTED_GITHUB_TOKEN'
dir や mv などで GOPATH に則ったディレクトリ構成にしています。
kmsKeyName に変数埋め込みは利用できないのでべた書きしてください、ご注意を。
.gcloudignore はこんな感じに
.gcloudignore
.git
.gitignore
go.mod
go.sum
YOUR_ENCRYPTED_GITHUB_TOKEN の作り方
https://github.com/settings/tokens でトークンを生成し、以下の様に暗号、前述 yaml に貼り付ける
gcloud kms keyrings create github-tokens --location=global --project=YOUR_GCP_PROJECT_ID
gcloud kms keys create github-deploy-token --location=global --project=YOUR_GCP_PROJECT_ID --keyring=github-tokens --purpose=encryption
echo -n $GITHUB_TOKEN | gcloud kms encrypt \
  --plaintext-file=- \
  --ciphertext-file=- \
  --location=global \
  --project=YOUR_GCP_PROJECT_ID \
  --keyring=github-tokens \
  --key=github-deploy-token | base64


