functions.configは非推奨になっている
Firebase Cloud Functionsの環境変数
廣瀬製紙株式会社 稼働率向上PJチームのAMです!
Firebase Cloud
Functionsのオフィシャルのドキュメントを見ると、すでにfunctions.configは非推奨扱いになっていますが、まだまだいろんな記事やChatGPTの回答などではこのやり方が提示されることが多いようです。
あらためて、公式としてはどのようなやり方を推奨しているのかをまとめました。
ざっくり言うと下記の2点です。
- ・環境変数を使う際にはfunctions.configではなく.envファイルから読み込みましょう。
- ・というかそもそも秘匿しなければならない情報はSecret Managerに入れましょう。
目次
環境変数とは
私たちが普段使用しているアプリケーションやシステムには、APIキーやデータベースの接続情報など、プログラムの動作に必要な設定値が存在します。これらの値をソースコード内に直接記述してしまうと、GitHubなどで公開した際に重要な情報が漏洩してしまう危険性があります。そこで活用されるのが「環境変数」です。 環境変数とは、プログラムが動作する環境(OS)に用意される変数のことで、プログラムの外部に設定値を保持することができます。これにより、同じプログラムでも開発環境と本番環境で異なる設定値を使い分けたり、機密情報を安全に管理したりすることが可能になります。 Node.jsでは、process.envオブジェクトを通じて環境変数にアクセスできます。例えば以下のように記述します。
// 環境変数「API_KEY」の値を取得
const apiKey = process.env.API_KEY;
一方、Pythonでは、osモジュールを使用して環境変数を扱います。
import os
# 環境変数「API_KEY」の値を取得
api_key = os.environ.get('API_KEY')
環境変数は、開発現場では非常によく使われる仕組みですが、Cloud Functionsにおいては近年、よりセキュアな方法が推奨されるようになってきています。以前は「functions.config」という方法が一般的でしたが、現在はセキュリティ上の観点から非推奨となり、代わりにSecret Managerの使用や、より安全な環境変数の設定方法が推奨されています。 特に機密性の高い情報を扱う場合は、環境変数の設定方法には十分な注意が必要です。例えば、APIキーや認証情報などは、単純な環境変数ではなく、よりセキュアな方法で管理することが望ましいとされています。
functions.configは非推奨
これまでFirebase Cloud FunctionsでAPIキーなどの設定値を扱う際、functions.configを使用するのが一般的だと考えていました。実際、多くの解説記事やチュートリアルでもこの方法が紹介されてきました。 しかし、Firebase Functions バージョン6.0.0からこの方法は非推奨となり、次のメジャーリリースでは完全にサポートが終了することが発表されています。公式ドキュメントでも「functions.configを使用している場合は、環境変数に移行することを強くおすすめします」と明確に記載されています。 具体的には、以下のようなfunctions.configの使用方法は避けるべきとされています:
const functions = require('firebase-functions');
const apiKey = functions.config().service.key;
もし現在もfunctions.configを使用しているプロジェクトがある場合は、できるだけ早い段階で新しい方法への移行を検討したほうがよいでしょう。
最も推奨されるやり方は?
Google Cloud Functionsで環境変数を扱う際、最も推奨される方法はGoogle Secret Managerの使用です。 Secret Managerは、APIキーなどの機密情報を安全に管理できるGoogleの専用サービスです。Cloud Functions公式ドキュメントでも、セキュリティ面を重視する場合の第一選択として推奨されています。 Secret Managerは従量課金制のサービスで、シークレットの保存と取得時に料金が発生します。ただし、料金体系は比較的リーズナブルで、例えば10,000回のアクセスで約0.03ドル程度です。多少のコストは発生するものの、セキュリティ面での利点を考えると十分な投資価値があると言えます。 具体的な利点として以下が挙げられます:
- ・暗号化されたセキュアな保存
- ・アクセス権限の詳細な管理が可能
- ・バージョン管理機能搭載
- ・監査ログの取得が可能
実装も比較的シンプルで、以下のような手順で利用できます:
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager');
const client = new SecretManagerServiceClient();
async function getSecret() {
const name = 'projects/プロジェクトID/secrets/シークレット名/versions/latest';
const [version] = await client.accessSecretVersion({name});
return version.payload.data.toString();
}
Secret Managerは安全性と使いやすさを両立した管理の手法と言えます。特に本番環境での運用や、重要な認証情報の管理には、最適な選択肢といえるでしょう。
次点は、.envファイルからの読み込み
環境変数の管理方法として、Secret Managerに次いで推奨されるのが.envファイルを使用する方法です。 Cloud Functionsでは、/functionsディレクトリに.envファイルを配置するだけで自動的に環境変数として認識されます。これは、dotenvパッケージを使用せずとも利用できる便利な機能です。 たとえば、以下のように環境変数を定義して使用できます:
const { defineInt, defineString } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');
これはエミュレーターでも本番環境でも同様に使えるので、いちいち切り替える必要がない点も便利です。 一点だけ注意点があるとすれば、変数の値を参照する際の`.value()`の扱いです。この`.value()`メソッドは、デプロイ時ではなく実行時に付与する必要があります。デプロイ時に付与してしまうと、正しく動作しない可能性があるためです。
//間違った使い方
// デプロイ時に実行されるコード
const minInstances = defineInt('HELLO_WORLD_MININSTANCES').value();
const message = defineString('WELCOME_MESSAGE').value();
exports.helloWorld = functions.https.onRequest((req, res) => {
res.send(`Message: ${message}, Min Instances: ${minInstances}`);
});
//正しい使い方(実行時に.value()を使う)
exports.helloWorld = functions.https.onRequest((req, res) => {
const minInstances = minInstancesConfig.value(); // 実行時に値を取得
const message = welcomeMessage.value(); // 実行時に値を取得
res.send(`Message: ${message}, Min Instances: ${minInstances}`);
});
なお、APIキーなどの機密情報については、公式ドキュメントではSecret Managerの使用を推奨していますが、必ずしもすべてのAPIキーが機密情報というわけではありませんので、そのあたりはキーを提供している側のドキュメントをよく調べるとよいかと思います(アクセス制限をかけられるなどの場合もある)。 公開しても問題ない設定値や、セキュリティ要件がそれほど厳しくないAPIキーについては、.envファイルでの管理も十分な選択肢となります。 .envファイルを使用する利点として、設定がシンプルで分かりやすく、開発環境と本番環境で異なる値を簡単に切り替えられる点が挙げられます。また、Secret Managerと異なり追加コストがかからないため、小規模なプロジェクトや開発段階では特に有用な選択肢となります。
結論
- ・functions.configは使わない。
- ・すでに使っている場合、.envかSecret Managerに置き換える
- ・秘匿すべき値はSecret Managerを使う