Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@su_aska

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

はじめに

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
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
7
Help us understand the problem. What are the problem?