CircleCIからGoogleの Cloud Source Repositories へのpush手順です
Google Cloud Source Repositoriesへpushする事前準備
GCPのサービスアカウントからサービスキーを取得
CircleCIからGCPのCloud Source Repositoryにpushするために、CircleCIのコンテナ内でGCPの認証を行う必要があります。
そのために必要なのが、外部サービス用のサービスアカウントキーです。
サービスアカウント、サービスアカウントキーについてはGCPのドキュメントを参照しました
サービスアカウントとは
サービスアカウントは、アプリケーションや仮想マシンの間で使用する特別なアカウントのことです。
GCPのプロジェクト内のアプリケーションはサービスアカウントに毎日発行されるサービスアカウントキーを使用して、ユーザーの直接の認証を必要とせずにGCPの各種APIを呼び出すことができます。
CircleCIから、GCPのプロジェクトへデプロイやリポジトリへのpushを行う場合は、外部用のサービスアカウントキーを発行します。
サービスアカウントキーを安全に管理する方法については、下記のブログに詳しく掲載されていますが、個人でのサービス開発であれば、ここまでする必要はないかもしれません。
CircleCIのcontextに設定しておく
作成した外部サービスアカウントキーを、CircleCIのcontextに保存しておきます。
contextの名前をここではgcpとしています。workflow内のジョブ内でcontext: gcp
のように呼び出すと、そのジョブ内でgcp context内で定義した値を参照することができます。
定義しておくと便利はcontextの定数
その他にも、context内で定義しておくと便利な定数があります
GOOGLE_COMPUTE_ZONE = 任意のインスタンスのリージョン
GOOGLE_PROJECT_ID = gcp内のprojectID
とくに、gcpのプロジェクトIDはgithubにpushせずに、context内に置いておいて参照すべきだと思います。
設定ファイル
workflowの設定
workflowでは、jobs以下で定義したジョブの順番やジョブ間の従属関係を定義することができます
# circleci/config.yml内のworkflow
workflows:
version: 2
build:
jobs:
- build
- deploy:
context: gcp
requires:
- build
filters:
branches:
only: master
workflowの流れは以下の通り
- buildする(jobs以下のbuildジョブ)
- buildが成功したらdeployジョブを開始(
requires: build
) -
context: gcp
でcontext内で定義した値をジョブ内で参照できる -
filters
で条件を指定できる - masterブランチのみdeployジョブを実行する(
only: master
)
deployジョブ
deployジョブに使用する docker image
deploy用のdocker imageはgoogleが提供しているgoogle/cloud-sdk利用します(あらかじめDockerfileでcloud-sdkのインストールと設定をしてくれます)
前回のジョブから引き継いだwork spaceをattachする
前回のジョブ(build)の最後で、persist_to_workspace
と設定するとジョブ間でディレクトリを引き継ぐことができます。
引き継ぐことで、src/
以下にビルドしたgoのバイナリを次のジョブでそのまま使用することができます。
# src/以下をrootに保存しておく
- persist_to_workspace:
root: .
paths:
- src/
deployジョブ内でattachしてsrc/
以下を引き継ぐ
# deployジョブ内でattachする
- attach_workspace:
at: .
contextからサービスアカウントキーをjsonファイルに書き出す
- run:
name: Service Account Key
command: echo ${GCLOUD_SERVICE_KEY} > ${HOME}/gcloud-service-key.json
gcloudコマンドのセットアップ
contextからGOOGLE_PROJECT_ID
とGOOGLE_COMPUTE_ZONE
を参照しています
- run:
name: Set gcloud command
command: |
cloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json
gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
gitアカウントの設定
- run:
name: setting git account
command: |
git config user.name circle
git config user.email circle@example.com
Googleの Cloud Source Repositoriesへpush
- run:
name: deploy
command: |
gcloud init && git config --global credential.https://source.developers.google.com.helper gcloud.sh
git remote add google https://source.developers.google.com/p/${GOOGLE_PROJECT_ID}/r/${GOOGLE_PROJECT_REPOSITORY}
git add -f src/app
git commit -m "deploy code"
git push google master -f
circleci/config.yml
version: 2
jobs:
build:
working_directory: /go/src/github.com/tanden/go-echo-with-mysql/
docker:
- image: circleci/golang:1.10
steps:
- checkout
- restore_cache:
keys:
- v1-vendor-{{ .Branch }}-{{ checksum "src/Gopkg.lock" }}
- v1-vendor-{{ .Branch }}
- v1-vendor
- v1-dep
- run:
name: dep ensure
command: |
cd src/
if [ ! -d vendor ]; then
if ! type dep >/dev/null 2>&1; then
go get -u github.com/golang/dep/cmd/dep
fi
dep ensure
fi
- save_cache:
key: v1-vendor-{{ .Branch }}-{{ checksum "src/Gopkg.lock" }}
paths:
- src/vendor
- save_cache:
key: v1-dep
paths:
- /go/bin/dep
- run:
name: go build
command: |
go build -v -o src/app src/server.go
- persist_to_workspace:
root: .
paths:
- src/
deploy:
working_directory: /go/src/github.com/tanden/go-echo-with-mysql/
docker:
- image: google/cloud-sdk
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Service Account Key
command: echo ${GCLOUD_SERVICE_KEY} > ${HOME}/gcloud-service-key.json
- run:
name: Set gcloud command
command: |
gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json
gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
- run:
name: setting git account
command: |
git config user.name circle
git config user.email circle@example.com
- run:
name: deploy
command: |
gcloud init && git config --global credential.https://source.developers.google.com.helper gcloud.sh
git remote add google https://source.developers.google.com/p/${GOOGLE_PROJECT_ID}/r/${GOOGLE_PROJECT_REPOSITORY}
git add -f src/app
git commit -m "deploy code"
git push google master -f
workflows:
version: 2
build:
jobs:
- build
- deploy:
context: gcp
requires:
- build
filters:
branches:
only: master