Cloud Run 関数 で Artifact Registry の Python プライベートリポジトリからパッケージをインストールする

Cloud Run 関数 で Artifact Registry の Python プライベートリポジトリからパッケージをインストールする

Cloud Run 関数の依存関係を Artifact Registry のプライベートリポジトリから安全にインストールする方法を解説します。
Clock Icon2024.11.15

はじめに

Cloud Run 関数 (Cloud Run functions(英名) / Cloud Functions (旧名)) は、Cloud Storage へのオブジェクト保存といった Google Cloud 上のイベントや HTTPS によるアクセスといったイベントをトリガーとして関数を実行するサービスです。

サーバやコンテナイメージを用意することなく、コードや必要な依存関係の情報のみを準備するだけで関数の実行が可能となります。例えば、Python 環境で実行する関数の場合、main.pyrequirements.txt を準備し、ランタイム環境として Python を指定することで実行可能な関数がデプロイされます。

このとき、requirements.txt で指定した依存関係は pip install によって PyPI といった外部リポジトリを参照してインストールしますが、プライベートリポジトリを参照させたいケースがあるかと思います。

本ブログでは Python プライベートリポジトリを Artifact Registry で構築し、Cloud Run 関数 から参照する方法を試してみます。

やってみる

以下の手順で検証してみます。

  1. Artifact Registry プライベートリポジトリ の構築
  2. 検証用の関数を作ってみる
  3. 必要なパッケージの準備
  4. Artifact Registry プライベートリポジトリにパッケージをアップロード
  5. 関数の準備と requirements.txt の更新
  6. Cloud Run 関数 に関数をデプロイする
  7. Cloud Run 関数 の動作確認

なお、本検証はオーナー権限にて実施しています。

1. Artifact Registry プライベートリポジトリ の構築

以下をブログを参照して Artifact Registry に Python のプライベートリポジトリを構築します。「Artifact Registry でリポジトリを作成する」の章までを実行し、リポジトリ https://asia-northeast1-python.pkg.dev/<Project ID>/private-python-package-repo が作成されている状態とします。
https://dev.classmethod.jp/articles/artifact-registry-private-repository-python/

今回は Cloud Shell に必要なパッケージを集め、Artifact Registry にアップロードしようと思います。そのため、Cloud Shell に Twine (Python パッケージを PyPI などのリポジトリにアップロードすることができるツール) をインストールします。

pip install twine

2. 検証用の関数を作ってみる

幾つかの依存関係が必要な簡易的なコードを用意してみます。今回は、Cloud Storage のバケット一覧を取得し、その情報をPandas の DataFrame に変換して、HTML 形式で表示する簡単な関数を作成してみました。

main.py
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 に記述します。

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 を取得します。

private-python-package-repo のパッケージ – Artifact Registry – da-test – Google Cloud コンソール

Cloud Shell に戻り、上記でコピーした URL を含めた以下コマンドを実行します。

python3 -m twine upload --repository-url <Repository URL> ./packages/*.whl

Cloud Console から [Artifact Registry] -> [リポジトリ] を選択しリポジトリ名をクリックすると、以下のようにパッケージがアップロードされていることがわかります。

private-python-package-repo のパッケージ – Artifact Registry – da-test – Google Cloud コンソール

5. 関数の準備と requirements.txt の更新

main.pyrequirements.txtprivate-repo-func ディレクトリに配置します。

$ ls private-repo-func/
main.py  requirements.txt

Cloud Run 関数 のランタイム環境に pip install するパッケージの参照先を Artifact Regsitry プライベートリポジトリとするため、 requirements.txt を以下のように修正します。--index-urlに前章の手順でコピーしたリポジトリの URL を記述しますが、URL に /simple を記述するのを忘れないようにしてください。

requirements.txt
--index-url <Repository URL>/simple
functions-framework==3.*
google-cloud-storage>=1.36.1
pandas>=2.2

Cloud Run 関数でプライベート依存関係を使用する手順の詳細は以下を参照しています。
https://cloud.google.com/functions/docs/writing/specifying-dependencies-python?hl=ja#using_private_dependencies

6. Cloud Run 関数 に関数をデプロイする

main.pyrequirements.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 にアクセスすると以下のようなページが表示され、ランタイム環境にインストールしたパッケージを利用した関数が問題なく実行ができていることがわかります。

スクリーンショット 2024-11-06 080917

では、ランタイム環境にインストールしたパッケージは、外部リポジトリではなく Artifact Registry プライベートレジストリを参照してインストールしたのかを確認してみます。
Cloud Run 関数 で関数をデプロイするとランタイム環境のビルドが裏側で動きますが、ビルド処理には Cloud Build が利用されています。Cloud Logging から Cloud Build のビルドログを確認してみると以下のようなログが確認できました。

ログ エクスプローラ – ロギング – da-test – Google Cloud コンソール

Artifact Registry プライベートリポジトリを参照してパッケージをダウンロードしているようです。

おわりに

Cloud Run 関数 の依存関係インストールに Artifact Registry プライベートリポジトリを利用する方法を解説しました。この方法を使用することで、外部に公開されていないパッケージや、組織内で管理されているカスタムパッケージを安全に利用できるようになります。
Google Cloud 上でのプライベートパッケージ管理と Cloud Run 関数 からの参照をご検討される方々の一助となれば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.