Cloud BuildでPATを使ったgitサブモジュールの利用方法
要約
クラウドエースの北野です。
Google CloudのCloud BuildでGitHubのプライベートリポジトリをサブモジュールとして使う方法を紹介します。本記事では、プライベートリポジトリの認証にGitHubのPersonal Access Token (PAT)を使います。
Google CloudでのPATの管理方法、Cloud Buildで認証情報の持たせ方と認証情報の内容は以下となります。
- PATの管理方法: Secret Managerで管理
- Cloud Buildでの認証方法の持たせ方:
~/.git-credentials
に定義
~/.git-credentials
の情報を読み込ませるコマンドは以下の通りです。
git config --global credential.helper store --file
Cloud Buildでgitサブモジュールを取得するビルド構成ファイルは以下の通りです。
steps:
- id: "create git-credentials"
name: 'gcr.io/cloud-builders/git'
secretEnv:
- 'PAT'
entrypoint: bash
args:
- -c
- |
cat << EOF > ~/.git-credentials
https://<GitHub アカウント名>:$$PAT@github.com/<GitHub アカウント名>/<サブモジュールリポジトリ>
EOF
- id: "git credential config"
name: 'gcr.io/cloud-builders/git'
entrypoint: bash
args:
- -c
- |
git config --global credential.helper store --file
- id: 'git submodule update'
name: 'gcr.io/cloud-builders/git'
entrypoint: bash
args:
- -c
- |
git submodule update --init --recursive
availableSecrets:
secretManager:
- versionName: projects/${PROJECT_ID}/secrets/<Secret Manager名>/versions/latest
env: 'PAT'
背景
アプリケーション開発などにおいて、他のリポジトリを参照させたいことがあると思います。参照先がパブリックリポジトリであれば、認証情報を設定せずに参照させられます。しかし、参照先が社内のプライベートリポジトリなどであれば、認証情報が必要となります。ローカルでの開発の場合であれば、開発者の認証情報でアクセスできますが、CI/CDツールでビルドするとき、CI/CDエージェントに認証情報を持たせる必要があります。
そこで、本記事では、Google CloudのCI/CDプラットフォームであるCloud BuildでGitのサブモジュールにプライベートリポジトリを使う方法を紹介します。
GitHubの認証方法
GitHubの認証は、以下の3つの方法があります。
- 2要素認証のユーザー名とパスワード
- SSHキー
- Personal access token (PAT)
2要素認証は認証時にワンタイムパスワードを求められるため、CIツールの認証に活用するのは適しません。また、SSHキーはリポジトリごとに認証させるSSH鍵を分けたりするなど細かな認証・認可の制御ができません。PATはリポジトリごとに発行させたり、PATごとにリポジトリに対して操作できる機能を制限するなど、認証と認可を細かに設定できます。そのため、PATを使うとより安全にプライベートリポジトリへアクセスさせることできます。
本記事では、Cloud BuildのビルドステップからPATを使い認証させる方法を紹介します。
秘匿情報の管理とCloud Buildによるアクセス
PATの情報は認証情報であり、漏洩すると意図しないエンドポイントからのアクセスが可能となるので、セキュアに管理する必要があります。ここでは、Google CloudでPATの情報などの秘匿情報をSecret Managerによりセキュアに管理する方法と、Secret Managerで管理されているデータをCloud Buildから取得する方法を紹介します。
Google Cloudでの秘匿情報の管理
Secret Managerは、機密データを保存するための安全で便利なストレージです。IAMによりデータへのアクセスを制限し、アクセスの監査ができるマネージドサービスです。
ここでは、以下の内容でSecret Managerを作成します。
- シークレット名: sample
- シークレット値: private repository git submodule
- レプリケーションポリシー: このシークレットのロケーションを手動で管理する
- ロケーション: 東京 (asia-northeast1)
- その他の設定: デフォルト
シークレット値が、Secret Managerで管理される秘匿情報となります。
Secret Managerに保存されたシークレット値は、以下のコマンドで取得できます。
gcloud secrets versions access latest --secret="sample"
上記のlatest
は、Secret Managerのsample
のバージョンの値です。latest
は最新のバージョンの指定となっています。特定のバージョンへのアクセスはバージョン数を指定してください。Secret Managerに格納されたデータへののアクセスには Secret Managerのシークレットアクセサー(roles/secretmanager.secretAccessor)
のIAMロールが必要となります。当該IAMロールは、個々のSecret Managerに付与ができます。
参考文献: Secret Manager IAMを使用したアクセス制限
Cloud BuildのビルドからSecret Managerのデータへアクセスする方法
Cloud BuildのビルドからSecret Managerのデータを取得する方法を紹介します。
アクセスには、以下が必要になります。
- 実行するビルド環境のサービスアカウントへの
roles/secretmanager.secretAccessor
ロールの付与 - ビルド構成ファイルにデータを取得するSecret Managerの情報の定義
ビルド環境のサービスアカウントはトリガー作成時にサービスアカウントを指定しないと、<プロジェクト ナンバー>@cloudbuild.gserviceaccount.com
となります。本記事では、当該Cloud Buildのデフォルトのサービスアカウントを使うこととします。
Cloud コンソールのIAMのページからCloud Buildのデフォルトサービスアカウントにプロジェクレベルで Secret Managerのシークレットアクセサー
の権限を付与します。
ビルド構成ファイルでの参照するSecret Managerの定義は、steps
の後にavailableSecrets.secretManager
フィールドを記載します。
availableSecrets.secretManager
には、以下の2つを定義します。
-
versionName
: Secret Manager名と参照するデータのバージョン (例:projects/${PROJECT_ID}/secrets/<Secret Manager名>/versions/<バージョン数>
) -
env
: ビルドで呼び出すときの変数名
ステップでの参照は、secretEnv
フィールドに参照するSecret Managerのenv
の値を定義し、args
内で$$
を先頭に付けて呼び出します。
以下は、先程作成したSecret Managerのsample
の値をechoコマンドで表示するビルド構成ファイルです。Secret Managerのsample
のバージョン数は、latest
として最新のバージョンを指定しています。
steps:
- name: 'ubuntu'
entrypoint: 'bash'
args:
- -c
- |
echo $$SECRET
secretEnv:
- SECRET
availableSecrets:
secretManager:
- versionName: projects/$PROJECT_ID/secrets/sample/versions/latest
env: SECRET
上記ファイルを任意のパスにcloudbuild.yaml
という名前で保存し、下記コマンドでビルドを実行させます。
gcloud builds submit --region=asia-northeast1 --config cloudbuild.yaml --no-source
当該コマンドで実行した結果をCloud コンソールから結果を確認すると、以下のようにSecret Managerに登録したシークレット値(private repository git submodule
の文字列)が表示されます。
参照URL: Cloud BuildでのSecret Managerのシークレットを使用
Cloud Buildでgitサブモジュールを使う方法
認証にPATを使いCloud Buildでプライベートリポジトリをサブモジュールとして使う方法を紹介します。本記事では、2022年10月18日に公開されたFine-grained personal access tokensを使います。 2023年4月時点では、Betaとなっているので本番運用などについては、考慮のうえ活用ください。また、PATは決して、GitHubのリポジトリに登録しないでください。
まず、PATを発行をします。PATの発行は、GitHubの個人設定画面の Developer settings
から作成をおこないます。
Personal access tokens
の Fine-grained tokens
の Generate new token
からPATを作成します。
ユーザー認証が求められるので、ユーザーの認証情報を入力します。PATの作成画面では必要な情報を入力します。このときRepository accessのOnly select repositories
を選択し、アクセスするプライベートリポジトリを選択します。
また、Repository Permissions
のContents
のAccessをRead-only
とします。(Contents
をRead-only
とすると、自動的にMetadata
もRead-only
となります。)すると、PATにプライベートリポジトリのコンテンツへのリード権限のみ付与されるので、PATが漏洩したとしても被害を最小限にできます。
作成が完了すると、以下のようにPATが表示されます。
得られたPATをSecret Managerに登録し、Cloud Buildから呼び出します。ここでは、以下の内容でSecret Managerを作成し、PATを登録します。
- シークレット名: github-pat
- シークレット値: GitHubで生成されたPAT
- レプリケーションポリシー: このシークレットのロケーションを手動で管理する
- ロケーション: 東京 (asia-northeast1)
- その他の設定: デフォルト
Cloud Buildからプライベートリポジトリへの認証は、gitの認証情報の保存機能によりおこないます。認証の方法は以下の通りです。
-
~/.git-credentials
の認証ファイルの作成 -
git config
コマンドで認証情報の読み込み
~/.git-credentials
の内容は、https://<GitHub Account>:<PAT>@github.com/<GitHub アカウント名>/<Repository>
となります。当該ファイルはCloud Buildのビルド内で生成し、リポジトリで管理しません。
~/.git-credentials
の認証情報を読み込むコマンドは以下となります。
git config --global credential.helper store --file
ここからは以下の2つのプライベートリポジトリを使い、Cloud Buildからプライベートリポジトリをサブモジュールで呼び出します。
- サブモジュールのリポジトリ:
private-submodule-repo
- サブモジュールを呼び出すリポジトリ(Cloud Buildから実行させるリポジトリ):
call-git-submodule
private-submodule-repo
のリポジトリ構造は、以下の通りです。
.
├── README.md
└── src
└── hello.sh
hello.sh
の中身は、以下となっています。
#!/bin/bash
echo "このスクリプトはサブモジュールで参照しているプライベートリポジトリです"
call-git-submodule
のリポジトリ構造は以下の通りです。
.
├── README.md
├── cloudbuild
│ └── cloudbuild.yaml
├── src
│ └── main.sh
└── submodule
├── README.md
└── src
└── hello.sh
submodule
ディレクトリ以下が、gitサブモジュールで、private-submodule-repo
を参照しています。参照させるコマンドは以下となっています。
git submodule add https://github.com/<GitHub アカウント名>/private-submodule-repo.git submodule
cloudbuildディレクトリ配下のcloudbuild.yaml
が、Cloud Buildで実行するビルドを定義しているビルド構成ファイルとなっています。cloudbuild.yaml
の中身は、以下のようになっています。
steps:
- id: "create git-credentials"
name: 'gcr.io/cloud-builders/git'
entrypoint: bash
args:
- -c
- |
cat << EOF > ~/.git-credentials
https://<GitHub アカウント名>:$$PAT@github.com/<GitHub アカウント名>/private-submodule-repo.git
EOF
- id: "git credential config"
name: 'gcr.io/cloud-builders/git'
entrypoint: bash
args:
- -c
- |
git config --global credential.helper store --file
- id: 'git submodule update'
name: 'gcr.io/cloud-builders/git'
entrypoint: bash
args:
- -c
- |
git submodule update --init --recursive
- id: "bash submodule"
name: 'ubuntu'
entrypoint: bash
dir: src
args:
- -c
- |
bash main.sh
availableSecrets:
secretManager:
- versionName: projects/${PROJECT_ID}/secrets/github-pat/versions/latest
env: 'PAT'
ビルドのステップで実行する src/main.sh
の中身は、以下の通りでサブモジュールのhello.sh
を実行するスクリプトとなっています。
#!/bin/bash
bash ../submodule/src/hello.sh
call-git-submodule
のリポジトリを接続し、Cloud Buildトリガーを以下の設定で作成します。
- トリガー名: private-submodule-sample
- リージョン: 東京 (asia-northeast1)
- イベント: なし
- 呼び出し: 手動呼び出し
- ソース: 第1世代
- リポジトリ: call-git-submodule(GitHubアプリ)
- リビジョン: ^main$
- 形式: Cloud Build構成ファイル
- ロケーション: リポジトリ
- Cloud Build構成ファイルの場所: cloudbuild/cloudbuild.yaml
- サービスアカウント: 指定なし (デフォルトサービスアカウント)
実際に手動トリガーの一覧画面からprivate-submodule-sample
の実行
ボタンからビルドを実行させます。
実行結果を確認すると、プライベートリポジトリを参照できていることが分かります。
まとめ
当該記事では、Cloud BuildでGitHubのプライベートリポジトリの参照をPATによりおこなう方法を紹介しました。プライベートリポジトリの参照はgitのサブモジュールを一例として紹介しましたが、サブモジュール以外の方法においても同様の方法で参照が可能となるので、参考にしてください。
Discussion