Cloud Run 関数 で Artifact Registry の Python プライベートリポジトリからパッケージをインストールする
はじめに
Cloud Run 関数 (Cloud Run functions(英名) / Cloud Functions (旧名)) は、Cloud Storage へのオブジェクト保存といった Google Cloud 上のイベントや HTTPS によるアクセスといったイベントをトリガーとして関数を実行するサービスです。
サーバやコンテナイメージを用意することなく、コードや必要な依存関係の情報のみを準備するだけで関数の実行が可能となります。例えば、Python 環境で実行する関数の場合、main.py
と requirements.txt
を準備し、ランタイム環境として Python を指定することで実行可能な関数がデプロイされます。
このとき、requirements.txt
で指定した依存関係は pip install
によって PyPI といった外部リポジトリを参照してインストールしますが、プライベートリポジトリを参照させたいケースがあるかと思います。
本ブログでは Python プライベートリポジトリを Artifact Registry で構築し、Cloud Run 関数 から参照する方法を試してみます。
やってみる
以下の手順で検証してみます。
- Artifact Registry プライベートリポジトリ の構築
- 検証用の関数を作ってみる
- 必要なパッケージの準備
- Artifact Registry プライベートリポジトリにパッケージをアップロード
- 関数の準備と requirements.txt の更新
- Cloud Run 関数 に関数をデプロイする
- Cloud Run 関数 の動作確認
なお、本検証はオーナー権限にて実施しています。
1. Artifact Registry プライベートリポジトリ の構築
以下をブログを参照して Artifact Registry に Python のプライベートリポジトリを構築します。「Artifact Registry でリポジトリを作成する」の章までを実行し、リポジトリ https://asia-northeast1-python.pkg.dev/<Project ID>/private-python-package-repo
が作成されている状態とします。
今回は Cloud Shell に必要なパッケージを集め、Artifact Registry にアップロードしようと思います。そのため、Cloud Shell に Twine (Python パッケージを PyPI などのリポジトリにアップロードすることができるツール) をインストールします。
pip install twine
2. 検証用の関数を作ってみる
幾つかの依存関係が必要な簡易的なコードを用意してみます。今回は、Cloud Storage のバケット一覧を取得し、その情報をPandas の DataFrame に変換して、HTML 形式で表示する簡単な関数を作成してみました。
import functions_framework
from google.cloud import storage
import pandas as pd
@functions_framework.http
def buckets_to_dataframe(request):
storage_client = storage.Client()
try:
# バケットの一覧を取得
buckets = list(storage_client.list_buckets())
# バケット情報をDataFrameに変換
df = pd.DataFrame([
{
'name': bucket.name,
'created': bucket.time_created,
'updated': bucket.updated,
'storage_class': bucket.storage_class,
'location': bucket.location
} for bucket in buckets
])
# DataFrameの内容をHTML形式で表示
result_html = df.to_html(index=False)
return f"""
<h1>GCS Buckets DataFrame</h1>
{result_html}
"""
except Exception as e:
return f"An error occurred: {str(e)}", 500
3. 必要なパッケージの準備
今回は検証のため、Artifact Registry にアップロードするパッケージは、外部リポジトリから Cloud Shell にダウンロード → Cloud Shell から Artifact Registry にアップロード という手順で準備します。
まずは必要な依存関係を requirements.txt
に記述します。
functions-framework==3.*
google-cloud-storage>=1.36.1
pandas>=2.2
Cloud Shell にて packages
ディレクトリを作成し、requirements.txt
を配置します。
$ ls packages
requirements.txt
pip download
で必要なパッケージを packages
ディレクトリにダウンロードします。
$ pip download -r ./packages/requirements.txt --dest ./packages
$ ls packages
blinker-1.9.0-py3-none-any.whl jinja2-3.1.4-py3-none-any.whl
cachetools-5.5.0-py3-none-any.whl MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
certifi-2024.8.30-py3-none-any.whl numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl packaging-24.2-py3-none-any.whl
click-8.1.7-py3-none-any.whl pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
cloudevents-1.11.0-py3-none-any.whl protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl
deprecation-2.1.0-py2.py3-none-any.whl proto_plus-1.25.0-py3-none-any.whl
flask-3.0.3-py3-none-any.whl pyasn1-0.6.1-py3-none-any.whl
functions_framework-3.8.1-py3-none-any.whl pyasn1_modules-0.4.1-py3-none-any.whl
google_api_core-2.22.0-py3-none-any.whl python_dateutil-2.9.0.post0-py2.py3-none-any.whl
googleapis_common_protos-1.65.0-py2.py3-none-any.whl pytz-2024.2-py2.py3-none-any.whl
google_auth-2.36.0-py2.py3-none-any.whl requests-2.32.3-py3-none-any.whl
google_cloud_core-2.4.1-py2.py3-none-any.whl rsa-4.9-py3-none-any.whl
google_cloud_storage-2.18.2-py2.py3-none-any.whl six-1.16.0-py2.py3-none-any.whl
google_crc32c-1.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl tzdata-2024.2-py2.py3-none-any.whl
google_resumable_media-2.7.2-py2.py3-none-any.whl urllib3-2.2.3-py3-none-any.whl
gunicorn-23.0.0-py3-none-any.whl watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl
idna-3.10-py3-none-any.whl werkzeug-3.1.3-py3-none-any.whl
itsdangerous-2.2.0-py3-none-any.whl
依存関係も含め複数のパッケージが準備できました。
4. Artifact Registry プライベートリポジトリにパッケージをアップロード
ダウンロードしたパッケージを Artifact Registry プライベートリポジトリにアップロードします。
Cloud Console から [Artifact Registry] -> [リポジトリ] を選択し、パッケージアップロード先のリポジトリ名をクリックします。上部にあるディレクトリ名の横にあるコピーマークをクリックし、リポジトリの URL を取得します。
Cloud Shell に戻り、上記でコピーした URL を含めた以下コマンドを実行します。
python3 -m twine upload --repository-url <Repository URL> ./packages/*.whl
Cloud Console から [Artifact Registry] -> [リポジトリ] を選択しリポジトリ名をクリックすると、以下のようにパッケージがアップロードされていることがわかります。
5. 関数の準備と requirements.txt の更新
main.py
と requirements.txt
を private-repo-func
ディレクトリに配置します。
$ ls private-repo-func/
main.py requirements.txt
Cloud Run 関数 のランタイム環境に pip install
するパッケージの参照先を Artifact Regsitry プライベートリポジトリとするため、 requirements.txt
を以下のように修正します。--index-url
に前章の手順でコピーしたリポジトリの URL を記述しますが、URL に /simple
を記述するのを忘れないようにしてください。
--index-url <Repository URL>/simple
functions-framework==3.*
google-cloud-storage>=1.36.1
pandas>=2.2
Cloud Run 関数でプライベート依存関係を使用する手順の詳細は以下を参照しています。
6. Cloud Run 関数 に関数をデプロイする
main.py
と requirements.txt
を Cloud Run 関数にデプロイしていきます。
最初に、Cloud Run 関数から Cloud Storage のバケット情報を読み取るための権限を付与する function-exec@<PROJECT_ID>.iam.gserviceaccount.com
というサービスアカウントを作成します。
$ gcloud iam service-accounts create function-exec \
--display-name="cloud run functions test"
作成したサービスアカウントに Google Cloud Storage バケットを参照する権限(ストレージ管理者 roles/storage.admin
)を付与します。
gcloud projects add-iam-policy-binding <Project ID> \
--member="serviceAccount:function-exec@<Project ID>.iam.gserviceaccount.com" \
--role="roles/storage.admin" \
--condition=None
Cloud Run 関数 に関数をデプロイします。関数名は private-repo-func
とし、ランタイムを Python 3.12 、イベントのトリガーを HTTPS とします。なお、--entry-point
には、イベントによるトリガーで実行される main.py
ソースコード内の関数名を指定します(今回の場合はbuckets_to_dataframe
)。
gcloud functions deploy private-repo-func \
--gen2 \
--region=asia-northeast1 \
--runtime=python312 \
--source=./private-repo-func \
--entry-point=buckets_to_dataframe \
--trigger-http \
--service-account=function-exec@<Project ID>.iam.gserviceaccount.com
7. Cloud Run 関数 の動作確認
Cloud Shell でのデプロイ後に表示される URL にアクセスすると以下のようなページが表示され、ランタイム環境にインストールしたパッケージを利用した関数が問題なく実行ができていることがわかります。
では、ランタイム環境にインストールしたパッケージは、外部リポジトリではなく Artifact Registry プライベートレジストリを参照してインストールしたのかを確認してみます。
Cloud Run 関数 で関数をデプロイするとランタイム環境のビルドが裏側で動きますが、ビルド処理には Cloud Build が利用されています。Cloud Logging から Cloud Build のビルドログを確認してみると以下のようなログが確認できました。
Artifact Registry プライベートリポジトリを参照してパッケージをダウンロードしているようです。
おわりに
Cloud Run 関数 の依存関係インストールに Artifact Registry プライベートリポジトリを利用する方法を解説しました。この方法を使用することで、外部に公開されていないパッケージや、組織内で管理されているカスタムパッケージを安全に利用できるようになります。
Google Cloud 上でのプライベートパッケージ管理と Cloud Run 関数 からの参照をご検討される方々の一助となれば幸いです。