GCP: Cloud Build
CLI
push なしで直接 CI を実行
PROJECT_ID="my-project"
gcloud builds --project $PROJECT_ID submit --config cloudbuild.yaml .
ビルドを取得
# ビルドの一覧を表示
gcloud builds list
# QUEUED or WORKINGのビルドのみ表示
gcloud builds list --ongoing
ログを取得
gcloud builds log --stream <build id>
GitHub 連携
https://github.com/apps/google-cloud-build
すべてのリポジトリを選択する。
CI が動く対象のリポジトリをあとから変更したいときは次の URL からRepository access -> Save
をクリックする。
https://github.com/settings/installations/1494878
以降、GitHub リポジトリを push すると自動で CI が動くようになる。
Docker イメージを自動ビルドする
リポジトリにDockerfile
を作成して push するだけ。
gcr.io/<プロジェクトID>/<リポジトリ名>
がイメージ名になる。
Docker ビルドをカスタマイズしたいときは構成ファイルを書く。
images
を指定することでタスク内で生成したイメージを Container Registry に保存できるので、docker push
を書く必要はない。
Docker イメージを Container Regisry に保存するcloudbuild.yaml
の例:
steps:
- name: "gcr.io/cloud-builders/docker"
args: ["build", "-t", "gcr.io/$PROJECT_ID/my-image", "."]
timeout: 600s
images: ["gcr.io/$PROJECT_ID/my-image"]
実際は次のようにイメージのキャッシュを使ったほうが時間の節約にもなって良い。
steps:
- name: "gcr.io/cloud-builders/docker"
entrypoint: "bash"
args:
- "-c"
- |
docker pull gcr.io/$PROJECT_ID/my-image:latest || exit 0
- name: "gcr.io/cloud-builders/docker"
args:
[
"build",
"-t",
"gcr.io/$PROJECT_ID/my-image:latest",
"--cache-from",
"gcr.io/$PROJECT_ID/my-image:latest",
".",
]
images: ["gcr.io/$PROJECT_ID/my-image:latest"]
構成ファイルを書いてビルドする
各タスクを実行するイメージには GCP が提供するイメージ(クラウドビルダー)か、一般公開されているイメージを使用できる。
クラウドビルダー
steps:
- name: "gcr.io/cloud-builders/docker"
args: ["build", "-t", "gcr.io/hako1912-dev/dev", "."]
- name: "gcr.io/cloud-builders/docker"
args: ["push", "gcr.io/my-project/my-image"]
- name: "gcr.io/cloud-builders/kubectl"
args:
[
"set",
"image",
"deployment/my-deployment",
"my-container=gcr.io/my-project/my-image",
]
env:
- "CLOUDSDK_COMPUTE_ZONE=us-east4-b"
- "CLOUDSDK_CONTAINER_CLUSTER=my-cluster"
options:
machineType: "N1_HIGHCPU_8"
timeout: 660s
tags: ["mytag1", "mytag2"]
Ref:
https://cloud.google.com/cloud-build/docs/configuring-builds/create-basic-configuration?hl=ja
シークレット
Ref:
https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials?hl=ja
必要な IAM 権限を設定する
owner
またはcloudkms.admin
が必要。
Ref:
https://cloud.google.com/kms/docs/iam?hl=ja#modifying_iam_permissions
キーを作成する
KeyRing を作成する。
KEYRING_NAME=test-keyrings
gcloud kms keyrings create $KEYRING_NAME --location=global
CryptoKey を作成する。
KEY_NAME=test-key
gcloud kms keys create $KEY_NAME \
--location=global \
--keyring=$KEYRING_NAME \
--purpose=encryption
Cloud Build のサービスアカウントに権限を設定する。
KEY_NAME=test-key
KEYRING_NAME=test-keyrings
gcloud kms keys add-iam-policy-binding \
$KEY_NAME --location=global --keyring=$KEYRING_NAME \
--member=serviceAccount:[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com \
--role=roles/cloudkms.cryptoKeyDecrypter
自身のアカウントにも復号権限を設定する。
USER="hoge@gmail.com"
gcloud kms keys add-iam-policy-binding \
$KEY_NAME --location=global --keyring=$KEYRING_NAME \
--member=user:$USER \
--role=roles/cloudkms.cryptoKeyDecrypter
環境変数を暗号化する
MY_SECRET="my-password"
echo -n $MY_SECRET | gcloud kms encrypt \
--plaintext-file=- \
--ciphertext-file=- \
--location=global \
--keyring=$KEYRING_NAME \
--key=$KEY_NAME | base64 | tr -d '\n'
環境変数を復号する
gcloud kms decrypt \
--location=global \
--keyring=$KEYRING_NAME \
--key=$KEY_NAME \
--ciphertext-file=- \
--plaintext-file=-
動作確認
steps:
- name: "ubuntu"
entrypoint: "bash"
args: ["-c", 'echo "$$APP_NAME HAS A VALUE $$HELLO_WORLD"']
env:
- "APP_NAME=test"
secretEnv:
- "HELLO_WORLD"
secrets:
- kmsKeyName: projects/<PROJECT_ID>/locations/global/keyRings/<KEY_RING_NAME>/cryptoKeys/<KEY_NAME>
secretEnv:
HELLO_WORLD: CiQAIO2k2R4udI/pjuGN+u+ep4EG24pCm5DUkSH0K3Tx+ZdO8x8SKgBew579JJbB7srB0C1wDBxnmzIuoy9T7B4LYZ26huuoVURIYo1G8HqUTg==
Tips
組み込みの環境変数を使用
Asciidoc を HTML 化して GCS にアップロード
docs/index.adoc
をgs://<バケット名>/doc/<ブランチ名>/index.html
に配置する。
https://storage.cloud.google.com/<バケット名>/docs/dev/index.html
で Web ブラウザで表示できる。(プロジェクトの閲覧権限は必要)
steps:
- name: asciidoctor/docker-asciidoctor:1.0.0
entrypoint: sh
# asciidoctor-diagramで生成した画像をimgタグから相対パスで指定すると表示できないので、画像ファイルをbase64にしてhtmlファイルに組み込んでいる
args:
- -c
- |
asciidoctor -r asciidoctor-diagram -D dist/ docs/index.adoc
for FILE in $$(find dist -name "*.png"); do
encoded_image=$$(base64 $$FILE | tr -d '\n')
sed -i -e "s~diag-.*\.png~data:image/png;base64,$${encoded_image}~g" "dist/index.html"
done
- name: gcr.io/cloud-builders/gsutil
args:
- cp
- dist/index.html
- gs://${_GCS_PATH}/${BRANCH_NAME}/
substitutions:
_GCS_PATH: my-bucket/docs