【Cloud Functions】デプロイ直前にランタイム環境変数を利用した関数のテストは出来ない、のかもしれない

Code

はじまり

リサちゃん
リサちゃん

あれー? テストがうまく通らないぞー?

135ml
135ml

デプロイ前のテストですね

リサちゃん
リサちゃん

この環境変数を読み取らないと先に進まないんだが・・・

135ml
135ml

Noneになってるね

まず、何が起きてるんだ

最近(2024/04/26ぐらいですかね)、Pythonで書いた関数をGoogle Cloudのコンソールから、Cloud Functionsとしてデプロイしようとした時の話です。

今回の事象は、Python 3.10、Python 3.12およびGo 1.22のランタイムで確認しました。

まあ、コンソールでCloud Functionsを開いて新しい関数を作成し始めると、こんな画面になりますよね。

そしたら、ランタイム環境変数を設定します。

そして、こんな風に関数を打ち込みます。 今回は、テストとして実行するためにこんな記述とします。

import functions_framework
import os

@functions_framework.http
def hello_http(request):
    """HTTP Cloud Function.
    Args:
        request (flask.Request): The request object.
        <https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
    """
    request_json = request.get_json(silent=True)
    request_args = request.args

    vari = os.getenv("TEST_ENV")
    print(vari)
    vari = os.environ.get("TEST_ENV")
    print(vari)
    vari = os.environ["TEST_ENV_2"]
    print(vari)
    

    if request_json and 'name' in request_json:
        name = request_json['name']
    elif request_args and 'name' in request_args:
        name = request_args['name']
    else:
        name = 'World'
    return 'Hello {}!'.format(name)

そして、「関数をテスト」をクリックして、ビルドのち直前のリクエストテストをしますよね・・・あれっ・・・。

すると、こんな感じのエラーメッセージが表示されます。os.environの返り値はdict型なので、環境変数にキーがないとKeyErrorを吐き出します。

Traceback (most recent call last):
  File "/layers/google.python.pip/pip/lib/python3.10/site-packages/flask/app.py", line 1473, in wsgi_app
    response = self.full_dispatch_request()
  
  // ...略

  File "/workspace/main.py", line 22, in hello_http
    vari = os.environ["TEST_ENV_2"]
  File "/layers/google.python.runtime/python/lib/python3.10/os.py", line 680, in __getitem__
    raise KeyError(key) from None
KeyError: 'TEST_ENV_2'

えーと、確かにランタイム環境変数は設定したはずですが・・・

はて?

デプロイ後に再度テストをしてみる

エラーになってしまいましたが、意に介さずにデプロイしてみます。

はい、デプロイが終わったら、もう一度リクエストのテストをしてみます。

実行すると、今回は特にエラーも起きず、ちゃんとレスポンスが返ってきます。

右下を見ると、環境変数を取得した事が分かるログも出力されていますね。

そういう仕様ということだろうか・・・

以下の、コンソールを介して関数をデプロイするドキュメントや、環境変数を設定する部分のドキュメントなどを読んでは見ましたが、デプロイ前に環境変数を取得できないとは書いてないんですね。(ビルドは終わってるんですけどね。)

Google Cloud コンソールを使用して Cloud Functions を作成する  |  Google Cloud Functions に関するドキュメント
Google Cloud コンソールを使用して Cloud Functions(第 2 世代)の HTTP Cloud 関数を作成します。
環境変数を構成する  |  Google Cloud Functions に関するドキュメント

そして、その環境変数のドキュメントに、Cloud Functionsでデフォルトで予約されている環境変数のキーがあるそうなので、その環境変数は取得できないのかどうかも調べてみました。

デフォルトで予約されている環境変数は取得できるのか

2024/04/29時点でCloud Functionsで自動的に設定されるランタイム環境変数のキーは以下のとおりです。

キー説明
FUNCTION_TARGET予約済み: 実行される関数
FUNCTION_SIGNATURE_TYPE予約済み: 関数のタイプ。HTTP 関数の場合は http、イベント ドリブン関数の場合は event です。
K_SERVICE予約済み: 関数リソースの名前
K_REVISION予約済み: 関数のバージョン ID。
PORT予約済み: 関数が呼び出されるポート。

ビルド直後でデプロイ直前にテストをするとこんな感じになります。

FUNCTION_TARGET」、「FUNCTION_SIGNATURE_TYPE」および「PORT」と、3種類のキーは取得できましたが、「K_SERVICE」および「K_REVISION」のキーは取得できませんでした。

デプロイ後にテストをするとこんな感じで、全てのキーが取得できています。

うーん、不思議だ。

まとめ

この記事では、Cloud Functionsのデプロイ前にランタイム環境変数が取得できなかったことについて解説しました。

  • Google Cloud Functionsでユーザーが設定したランタイム環境変数は、デプロイ後にのみ取得可能。
  • 一部の自動的に設定されるランタイム環境変数は取得可能だが、全てではない。

Secret Managerなどを噛ませれば、デプロイ直前にシークレットを使ったテストが出来るんでしょうけど。

まあ、それが面倒だからランタイム環境変数に設定しているのであって、この仕様には疑問でした・・・。

おしまい

リサちゃん
リサちゃん

じゃあ、デプロイ前はテストできないじゃん。

135ml
135ml

環境変数ってよく使うんだけどな。

以上になります!

コメント

タイトルとURLをコピーしました