はじまり

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

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

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

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'
えーと、確かにランタイム環境変数は設定したはずですが・・・
はて?
デプロイ後に再度テストをしてみる
エラーになってしまいましたが、意に介さずにデプロイしてみます。

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

実行すると、今回は特にエラーも起きず、ちゃんとレスポンスが返ってきます。
右下を見ると、環境変数を取得した事が分かるログも出力されていますね。

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


そして、その環境変数のドキュメントに、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などを噛ませれば、デプロイ直前にシークレットを使ったテストが出来るんでしょうけど。
まあ、それが面倒だからランタイム環境変数に設定しているのであって、この仕様には疑問でした・・・。
プログラミングのお供に
PFU キーボード HHKB Professional HYBRID 日本語配列/墨
【Amazon.co.jp限定】 Logicool G ゲーミングキーボード G515 TKL 薄型 有線 テンキーレス キーボード G515-LNBK リニア 赤軸 静かなタイピング 日本語配列 LIGHTSYNC RGB ゲーミング メカニカルキーボード PC window mac chrome ブラック 国内正規品
ZENAIM KEYBOARD ゼンエイムキーボード【MOTION HACK機能(ラピッドトリガー機能)搭載/0.05mm単位のアクチュエーション可変/温度補正機能による誤動作防止/磁気検知式ロープロファイルキーボード/TKLサイズ/日本語配列/脱着式Type-Cケーブル/安心の国内サポート】
おしまい

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

環境変数ってよく使うんだけどな。
以上になります!
コメント