📚

TerraformによるFirebase Remote Configの管理

に公開

モバイルアプリに掲載されるバナー広告の画像やリンク先がFirebase Remote Configで管理されているのですが、それらをエンジニア以外のスタッフ(マーケティングチーム等)が編集したいという話がありました。

バナー広告 Remote Configパラメータ

開発環境のFirebaseプロジェクトであればスタッフに適切な権限を付与して、コンソールから変更してもらうこともできますが、本番環境のFirebaseプロジェクトの場合はきちんとレビューを通したいところです。

そこでTerraform+AtlantisでRemote Configを管理することを思いつきました。


Atlantisは以前紹介しましたが、Pull Request上でTerraformのplan・applyを行うツールで、レビュー後にatlantis applyとコメントすることで変更内容を適用することができます。Pull Request上のやり取りで作業が完了するので特別な権限やツールは不要です。
また、GitHubではブラウザからファイルを編集できるので、手元にgit cloneできなくてもPull Requestを作成することができます。

問題はFirebase Remote ConfigのTerraform Providerが存在しないことです。FirebaseのProviderはあるのですが、Remote Configは管理対象に含まれていません。

https://firebase.google.com/docs/projects/terraform/get-started?hl=ja

Firebase Remote Config APIは公開されておりGoのライブラリもあったので、Providerを自作してみることにしました。


Firebase Remote ConfigのAPI自体は単純で数も少なく実装の手間はそれほどかかりません。しかしgoogle-api-go-clientに含まれるfirebaseremoteconfig-api.jsonは8年前から更新されておらずParameterValueTypeが未実装の状態。

Issueによると https://www.googleapis.com/discovery/v1/apisfirebaseremoteconfigが含まれない状態が続いているとのこと。

https://github.com/googleapis/google-api-go-client/issues/2274

The Go firebaseremoteconfig has not been generated from a new discovery doc in many years it seems. We only regenerate libraries for things that show up in the public listing of APIs, which this one no longer does it seems: https://www.googleapis.com/discovery/v1/apis.

Firebase Admin Go SDKにも機能追加の要望が上がっていましたが、こちらは2021年から更新がありません。

https://github.com/firebase/firebase-admin-go/issues/391

Firebase Admin Go SDKにAPI追加のPull Requestを投げるのが正攻法だと思います。しかしIssueの放置具合からマージに時間がかかりそうな気配を感じました。また、google-api-go-clientに至っては今後、Remote Configまわりが更新される可能性は非常に低いでしょう。

公式ライブラリをforkするのはあまり好ましくないのですが、今回は時間がなかったのでgoogle-api-go-clientをforkして、自前でParameterValueTypeを追加しました。

https://github.com/winebarrel/google-api-go-client/pull/1/commits/4e9bab43592b9914666c741bd519fa7e16a1616b


ということで作ったのがterraform-provider-firebaseremoteconfigです。

https://github.com/winebarrel/terraform-provider-firebaseremoteconfig

Remote Config全体を管理したいというより一部だけ編集したい要望だったので1パラメータをリソースとしました。

resource "firebaseremoteconfig_parameter" "foo" {
  key        = "foo"
  value_type = "JSON"

  default_value = {
    value = jsonencode({
      foo = "bar"
      zoo = 100
    })
  }
}

変更が必要なパラメータが出てきたら都度都度インポートするようにしています。

Remote ConfigのterraformingによりPull Request上で変更のレビューが行えるようになり、安全にリリースできるようになったと思います。


余談

パラメータのJSON値にはテキストではなくTerraformのjsonencode関数を使ってhclで定義しているのですが、この関数には<>&がUnicodeエスケープシーケンスに変換される仕様があります。

> jsonencode({ url = "https://example.com/?foo=bar&zoo=baz" })
"{\"url\":\"https://example.com/?foo=bar\\u0026zoo=baz\"}"
                                      # ^^^^^^^

replace関数を使って置換すればいいのですが、冗長な記述になってしまうため専用のユーザー定義関数を作成しました。

https://github.com/winebarrel/terraform-provider-multireplace

> provider::multireplace::jsonunescape(jsonencode({ url = "https://example.com/?foo=bar&zoo=baz" }))
"{\"url\":\"https://example.com/?foo=bar&zoo=baz\"}"
                                      # ^

余談2

jsonunescape関数は複数文字列置換用のmultireplace関数の特殊系として作ったのですが、multireplaceと同様のユーザー定義関数を提供するProviderはすでにありました

https://github.com/random-things/terraform-provider-string-functions

こちらは文字列に関する便利関数をいくつも提供しており、なかなか便利そうです。

株式会社カンム

Discussion