Google Cloud Buildとは
Googleが提供するクラウドコンピューティングサービス。
本記事では、nodeアプリケーションをGoogle App Engine (GAE)にデプロイするためのパイプラインをGoogle Cloud Buildで構築する
手順
リポジトリ作成
事前にgithubのリポジトリを用意しておくこと。また、Google App Engine (GAE)のプロジェクト作成の方法はこちらの記事を参考されたし
Cloud Build
トリガー作成
GCPのコンソールから、Cloud Buildを選択し、トリガーを作成をクリック
名前、リージョン、イベントを入力。イベントは今回、ブランチにpushするを選択
リポジトリの項目で、新しいリポジトリに接続をクリック
プロバイダはGithubを選択。認証が完了したら、リポジトリを選択し、接続。ブランチを指定。
構成で、形式は自動検出もしくはCloud Build構成ファイルを選択し、ロケーションはリポジトリを選択。最後に選択をクリック
Cloud Build サービスアカウントに権限追加
トリガーの設定でサービスアカウントを特に指定しなかった場合、Cloud Build サービス アカウント ( xxxxx@cloudbuild.gserviceaccount.com )で処理が実行されるが、このアカウントには、AppEngineへのデプロイに必要なロールを追加する必要がある。(必要なロールが付与されていない場合は以下のようなエラーが出る)
ERROR: (gcloud.app.deploy) Permissions error fetching application [apps/projectid]. Please make sure that you have permission to view applications on the project and that XXXXXXXXXX@cloudbuild.gserviceaccount.com has the App Engine Deployer (roles/appengine.deployer) role.
AppEngineへのデプロイに必要なロールはこちらに書いてあるので、App Engine Admin API を有効化した上で、設定から「App Engine管理者」と「サービスアカウントユーザー」を有効化
必要なファイルを用意
今回はcloud-build-testというディレクトリの中にapp.yamlとcloudbuild.yaml、app.jsとpackage.jsonを作成して配置した
cloudbuild.yaml
steps:
- name: 'node:18'
entrypoint: 'npm'
args: ['install']
- name: 'gcr.io/cloud-builders/gcloud'
args: ['app', 'deploy', 'app.yaml', '--project', 'your projectId']
app.yaml
runtime: nodejs
service: sample-node-app
entrypoint: npm start
env: flex
runtime_config:
operating_system: ubuntu22
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
app.js
'use strict';
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.status(200).send('Hello, world!').end();
});
const PORT = parseInt(process.env.PORT) || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
module.exports = app;
package.json
{
"name": "appengine-hello-world",
"description": "Simple Hello World Node.js sample for Google App Engine Flexible Environment.",
"version": "0.0.2",
"private": true,
"license": "Apache-2.0",
"author": "Google Inc.",
"repository": {
"type": "git",
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
},
"engines": {
"node": ">=16.0.0"
},
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.17.1"
}
}
これで対象のリポジトリにpushするとビルドが走り、AppEngineにデプロイされる。ちなみに、Cloud Buildのトリガーから「実行」をクリックすると手動で実行させることも可能
おまけ
app.yamlのシークレット値
Cloud BuildでデプロイするリソースがAppEngineで、かつapp.yamlにシークレット値が含まれている場合、うまく取り扱う必要がある(app.yaml上からシークレットマネージャーにアクセスする機能がないため ※2024/1/7時点)
これを実現するためにかなり調べたが、現状は以下の2通りのいずれかの方法になると思われる
- app.yamlのシークレット値は仮の値を設定しておき、CI/CD時に、シークレットマネージャーから値を取得し、app.yamlの該当の箇所を置換してデプロイする
- シークレット値は別のapp.env.ymlなどに出力し、CI/CD時に、app.yamlのincludesを使用して、app.env.ymlをapp.yamlに取り込む
色々検討し、1つ目の方法を使うことにしたので、その際の設定値のサンプルを示しておく
cloudbuild.yaml
# gcloud app deploy前にapp.yamlの該当の箇所を置換する
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
id: "Deploy"
entrypoint: '/bin/bash'
args:
- -c
- |
sed -i "s|%SERVICE_ACCOUNT_PRIVATE_KEY%|$$SERVICE_ACCOUNT_PRIVATE_KEY|g" ${_APP_YAML_FILE}
gcloud app deploy --project=${_PROJECT_ID} ${_APP_YAML_FILE}
secretEnv: ['SERVICE_ACCOUNT_PRIVATE_KEY']
# シークレットマネージャーから値を取得する
availableSecrets:
secretManager:
- versionName: ${_SERVICE_ACCOUNT_PRIVATE_KEY_SECRET_VERSION_NAME}
env: SERVICE_ACCOUNT_PRIVATE_KEY
app.yaml
env_variables:
SERVICE_ACCOUNT_PRIVATE_KEY: "%SERVICE_ACCOUNT_PRIVATE_KEY%"
まとめ
いかがでしたでしょうか。本記事では、Google Cloud Buildを使用してCI/CDパイプラインをサクッと構築するための手順について紹介しました。ぜひ参考にしてみて下さい。