🗂
GithubActions上のコンテナ内でGCPのクレデンシャルの認証
背景
業務でCI上のコンテナでGCPのクレデンシャルの認証でつまずいたので、共有できればと思いました。
つまずいた部分
CI環境でGCSクライアント初期化時のクレデンシャルの認証でつまずいた。コンテナ起動時にmain.go
でGCSクライアントの初期化を行う場合クレデンシャルで認証を行う必要がある。しかし、CI上ではリポジトリにクレデンシャルを置いてないので、このままでは認証することができない。
func main() {
cfg, err := env.New()
if err != nil {
panic(err)
}
gc, err := gcs.storage.NewClient(context.Background())
if err != nil {
panic(err)
}
db, err := postgres.Open(cfg.Database.URI())
if err != nil {
panic(err)
}
defer db.Close()
}
解決方法
- GithubActions上にクレデンシャルを設置する。
- GCPから有効期限付きのクレデンシャルを発行する。
このどちらかの方法で用意したクレデンシャルをマウントしてコンテナ内で使えるようにする。
1つ目の方法は、セキュリティの観点からあまり好まれない。なので、一般的には2つ目の方法が使われることが多い、今回は2つ目の方法で実装した。
手順
- CI上でクレデンシャルの発行をできるようにGCPの設定をする。
- CIのyamlファイルにクレデンシャルを発行するステップを追加する。
- CIを起動して有効期限付きのクレデンシャルを発行する。発行すると下記の画像のように環境変数にクレデンシャルの情報が追加されます。
- docker-compose.yamlの
GOOGLE_APPLICATION_CREDENTIALS
に設定しているコンテナ内のパスにクレデンシャルを設置する。そのためにはCI上でクレデンシャルをマウントできるように、ローカル環境と同じようにクレデンシャルファイルを置く必要がある。例えば、コンテナ内のクレデンシャルのパスが以下のように設定したとする。
//コンテナ内のクレデンシャルのパス
GOOGLE_APPLICATION_CREDENTIALS: /go/src/backend/secrets/cloud_run_service_account.json
そうするとCI上のディレクトリで以下のコマンド操作が必要になる。
・ backend
配下にsecrets
ディレクトリを作成する。
・ secrets
ディレクトリ配下にcloud_run_service_account.json
を作成する。
・ クレデンシャルの情報をcloud_run_service_account.json
にコピーする。(上記の手順でステップを作成するとenvにクレデンシャルの情報が追加される。詳しくはecho
などで出力してみてください。)
mkdir /home/runner/work/project/backend/secrets
touch /home/runner/work/project/backend/secrets/cloud_run_service_account.json
cp ${{ env.GOOGLE_GHA_CREDS_PATH }} /home/runner/work/project/backend/secrets/cloud_run_service_account.json
- コンテナを立ち上げる。ここで1つ注意することがある。それはステップ間の操作は引き継ぐことができないことである。例えば、ファイルを操作するステップとコンテナを立ち上げるステップを別々に記述すると、コンテナを立ち上げるときにファイルの操作内容が引き継がれない。なので、以下のようにコマンドをまとめるとよい。
- name: Compose up
shell: bash
run: |
mkdir /home/runner/work/project/backend/secrets
touch /home/runner/work/project/backend/secrets/cloud_run_service_account.json
cp ${{ env.GOOGLE_GHA_CREDS_PATH }} /home/runner/work/project/backend/secrets/cloud_run_service_account.json
docker compose up
Discussion