9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

依存にプライベートレポジトリを含むGAE/Go(go111)をCloud Buildで自動でプロイする

Last updated at Posted at 2019-03-24

はじめに

go111 の登場で、Cloud Build を使えば設定ファイル1つで自動デプロイ出来るようになったはずでした。

cloudbuild.yaml
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 に含まれると必ず失敗します。

oybFJinHqBLJSCyiyIXDKh1IA2Wjpk22ye3YIiuv-QKf2awbcJaf6Y55cUdfgKMQIa1rvQb96VdvsLmu5A1hTNTq1MjBJmOB9XOKAAIa5kJaLt9XKOPJSxv2RdwAWfwU7W00.png

前段でgo mod vendorし、go.modをdeployしない

oybFJinHqBLJSCyiyIXDKh1IA2Wjpk22ye3YIiuv-QKf2awbcJaf6Y55cUdfgKMQIa1rvQb96VdvsLmu5E3Jcfwla9kVeb2McfUINqIi0UwEhX3DoM31n882XPJKWfpyIW00.png

Cloud Build(Trigger) 側で go mod vendor し、更に .gcloudignorego.mod を指定して gcloud app deploy すれば解決します。
vendor ディレクトリごと GCS にアップロードするので、.gcloudignorevendor を含めてはいけません。

まとめ

  1. go111 のプロジェクトを gcloud app deploy すると Cloud Build による deploy が実行される
  2. この際に実行される Cloud Build に対しては何も設定出来ない
  3. go.mod を含む場合、自動で go get し、そこにプライベートレポジトリがあると失敗する
  4. .gcloudignorego.mod を除外指定していれば自動で go get されない
  5. そのかわり、vendor.gcloudignore に指定せず、 go mod vendor 後に gcloud app deploy する
  6. vendor ディレクトリごと Upload され、go get も行われないので deploy は成功する
  7. 一連の作業を Cloud Build で自動化する為の cloudbuild.yaml がこちら
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'

dirmv などで GOPATH に則ったディレクトリ構成にしています。
kmsKeyName に変数埋め込みは利用できないのでべた書きしてください、ご注意を。

.gcloudignore はこんな感じに

.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
9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?