Google Artifact Registryを使った社内パッケージ管理

ogp

はじめに

こんにちは、enechain でエンジニアをしている choco です

日々の開発の中で、汎用メソッドや設定ファイルなど複数アプリケーションで共用したいパッケージやソースコードがあると思います。

enechain では、それらパッケージの配布方法として Google Artifact Registry を利用しています。

今回の記事では、その導入理由や簡単な利用方法についてご紹介します。

導入背景

enechain では、プロダクト間の UIUX の統一性を目的としたデザインシステムの開発を行なっています。開発初期には、実装したコンポーネント群を各アプリケーションへ配布する方法が定まっていませんでした。

暫定的な配布方法として、インストール時にリポジトリに対して Git Clone を走らせる仕組みをとっていました。

例えば、JS のパッケージの場合は、package.json に下記のようにライブラリの参照先を指定して利用していました。認証は SSH を構成します。

"libraryA": "git+ssh://github.com/xxxxx/libraryA"

これでも動作はするのですが、CI 実行時に SSH キーが必要となり、流出時のセキュリティリスクを抱えていました。 このリスクを避けるため、代替案を検討する必要がありました。

代替の管理方法を検討するにあたり、大枠として以下の 3 つの要件がありました。

  1. 可能な限り各メンバーに直接的な認証情報を渡さないこと
  2. 言語に関わらず共通の仕組みで運用できること(JS/GO)
  3. パッケージ情報を社外に公開しないこと

GAR の導入

上述の要件を満たす、よりセキュアな管理方法として、Google Artifact Registry(以下 GAR)を使った仕組みを導入しました。

GAR には以下のような利点があります。

  1. 短期のアクセストークンを使った認証を利用できる
  2. Google Cloud SDK があれば、認証を構成するコマンドを実行できるため入社したメンバーがすぐに利用開始できる

SSH キーと比較して、ライブラリをインストールする際には、短期のアクセストークンを利用します。有効期限は 1 時間です。

アクセストークンの発行には、gcloud のユーザー情報を利用します。gcloud コマンドが打てる環境があれば認証構成に必要な環境をセットアップすることができます。

image1

Github Package との比較

ビルドしたソースコードの置き場として Github Package も選択肢にありましたが、Personal Access Token(PAT)を認証に使うことから採用を見送りました。

具体的には、

  • 特定の Github アカウントに依存した認証方法になること
  • PAT をメンバーに配布する必要があること
  • 永続性のある認証情報のため、トークンに比べるとインセキュアであること

といった問題が挙げられます。GCP を採用している enechain としては既存の IAM の仕組みで制御する方が簡単に権限管理できると判断しました。

導入方法

具体的な導入手順をご紹介します。ここでは JS のパッケージを例として扱っています。

  • レジストリの作成とパブリッシュ
// レジストリの作成
gcloud artifacts repositories create npm-internal-library \
 --repository-format=npm \
--location=us-central1 \
--description="npm internal lirary"

gcloud config set artifacts/repository npm-internal-library

// 利用したいパッケージのpublish
pnpm publish --access=restricted - no-git-checks
  • ライブラリのインストール

下記の手順でパブリッシュしたライブラリのインストールを行います。package.json にトークン生成用の script を追加します。

"scripts": {
  "artifactregistry-login": "npx google-artifactregistry-auth --credential-config ./.npmrc"
}

レジストリへの接続情報を.npmrcに記載します。

@enechain:registry=https://${registry-name}/${dir_name}/
//https://${registry-name}/${dir_name}/:always-auth=true
// ユーザー情報の取得
gcloud auth login

// トークンの生成
pnpm artifactregistry-login

// インストール
pnpm add @enechain/library-name

トークン管理について

pnpm artifactregistry-login を実行すると.npmrc にトークンが書き込まれます。誤って commit することがないように、以下のような設定を入れて commit から除外するようにしています。

  • .npmrc
//https://${registry-name}/${dir_name}/:_authToken=
  • .gitconfig or projectRoot/.git/config
[filter "ignore-token"]
    smudge = cat
    clean = sed "s/:_authToken="[^@]*"/:_authToken=""/"
  • projectRoot/.gitattributes
.npmrc filter=ignore-token

CI (Github Actions)

enechain では self hosted runner を利用しており、runs-on に GAR へアクセス可能なランナーを指定することで、ランナー内部に存在する gcloud の認証情報を読み取ってトークンを生成しています。

install-package:
  runs-on: [self-hosted, ${self-hosted-runner}]
steps:
 - name: auth google artifact registry
   run: pnpm artifactregistry-login
 - name: package install
   run: pnpm i

GO の共通ライブラリ管理について

本記事では JS の実装例をご紹介しましたが、Go の共通ライブラリの管理も GAR を利用しています。enechain で利用を開始した際は GAR の Go 対応はベータ版でしたが、先日 GA となりました。実装方法概ね同じになっており、gcloud のユーザー認証情報からトークンを生成後、go コマンドで必要なパッケージをインストールします。

参考ドキュメント

最後に

本記事では、社内のパッケージ管理についてご紹介しました。

コマンドベースで手順をご紹介しましたが、実際には Terraform での管理になります。残念ながら Go レジストリの管理は Private Preview となっており Terraform で作成できませんが、今後のサポートに期待したいと思います。

また、社内パッケージ管理を検討するきっかけとなった enechain のデザインシステムについても今後ご紹介したいと思います。

herp.careers

herp.careers

herp.careers