Azure Functionsは、本当に各所で活用できるポテンシャルがあり、すでに多くの実績をグラニで積んでいます。実際グラニでは、プロダクト投入に加えてインフラにおける中心となりつつあります。活躍できるシーンが多く思いつくため、どんどん実装が追加されています。
さて本番投入ということで、検証ステージを超えると気になるのが機微情報(機密情報)です。
「慣れるため、開発中」などいろいろな理由でついついパスワードやTokenなどをコードに埋め込んでしまうことが多いです。
そんな時に、Linuxでは環境変数にexport Hoge="foo"などとしてコードから分離するのが王道ですが、Azure Functionsでどうやってコードと分離するか考えてみましょう。
目標
次のことができるように目指します。
- GitHubやBitbucketをはじめとする、ソースコードのバージョン管理システムに機微情報を含めない
- CIで同一環境にデプロイする (新たにAzure Functionsを作成しなおすということはしない)
- デプロイしたコードから機微情報へアクセスして利用できること
この目標のため、ソースコード内への生埋め込み、app.configなどは利用できません。
AWSでもリソースアクセスはInstance Role *1 で制御が可能ですが、悩ましい問題です。
Azure Functions は Web Apps
Azure Functionsではどうするといいでしょうか? 実体がWeb Apps、ということはつまりApplication Settings (== 環境変数)が利用できます。
Application Settings に機微情報を埋め込む
Web AppsやAzure FunctionsもIaaSではなくPaaSです。とはいえ、Kudu経由でシェルも触れるのですが、環境変数はシェルからは設定しません。PaaSということはインスタンスの実体は隠蔽されており、いつ別インスタンスに変わるかはおまかせだからです。
シェルで設定 = 設定したインスタンスでしか参照できずインスタンスが変わると再設定が必要
そこで利用するのが、App Settingsです。これを利用することで、Web Appsを管理するインスタンスがなにになっても、共通で参照する環境変数を定義し、インスタンスから参照できます。
さっそくAzure Functionsで、App Settingsにアクセスしてみましょう。
Function app settings > Settings > Application settings > App Settings

このApp settingsにKey/Valueで環境変数を設定します。今回は、FooKeyに対してFooKeyです。

App Setting を読み込む
コードからは、App.configを読み込む際と同様に、System.Configuration.ConfigurationManager.AppSettings["<Key>"]で取得が可能です。
1つだけ注意点として、#r "System.Configuration"を追加しておきます。アセンブリが足りないため、#r "System.Configuration"名前空間が参照できないためです。

あとはコードを実行してみます。
https://gist.github.com/guitarrapc/27ca0f4f52391a96832e13acedc8921a
予定どおり、FooKeyに設定したFooKeyが取得出来ていますね。

またApp Settingsは、#load "読み込みたい.csx"で指定した外部 .csxファイルでも読めます。これは、.csxがFunctionのディレクトリではなく、WWWRootにある場合でも問題ありません。
まとめ
今回の外部App Settings参照も、GitHubに追加しておきました。
機微情報をコードから除外できるのは、ソース管理から見るととても大きいです。もちろんAmazon Key Management SystemやAzure Key Vaultで、暗号化、復号化をするのもいいのです。
が、まぁ、App Settingsを使うのが、Azure Functionsでは妥当ではないでしょうか。やりすぎず、必要十分は確実に満たす方法が用意されているのはいいですね。
*1:つまりIAM Role