Firebase の環境構築を Terraform で自動化する
こんにちは!アルダグラムでエンジニアをしている @sukechannnn です。
SREチームでは、本番でも利用しているECSにデプロイして動作確認できるテスト環境を、用途に応じて増やせる基盤の整備を行い、4月から運用を開始する予定です。
その中で、複数の Firebase プロジェクトを同じ設定で構築する必要があり、手動での構築に課題を感じていました。そこで Terraform で構築・管理できないか?と調べてみたところ、google-beta provider に google_firebase_project resource があり、それを用いることで Firebase プロジェクトを簡単に構築できるようになりました!
この記事ではそのやり方について、サンプルコードと共に説明していきます。
ちなみに、ここで説明する内容は、以下の公式ブログにもまとまっています。
Get started with Terraform and Firebase
Terraform で Firebase プロジェクトを立ち上げる
Firebase のプロジェクトを追加します。
terraform {
required_providers {
google-beta = {
source = "hashicorp/google-beta"
version = "~> 4.0"
}
}
}
provider "google-beta" {
billing_project = "existing_project_id"
user_project_override = true
region = "asia-northeast1"
}
# Firebase プロジェクト用の GCP プロジェクトを立ち上げる
resource "google_project" "default" {
provider = google-beta
# project_id は全世界で一意になる必要がある
project_id = "project_id"
name = "project_name"
org_id = 1234567890
billing_account = "123456-ABCDEF-1A2B3C"
# Firebase のプロジェクトとして表示するために必要
labels = {
"firebase" = "enabled"
}
}
# Firebase のプロジェクトを立ち上げる
resource "google_firebase_project" "default" {
provider = google-beta
project = google_project.default.project_id
depends_on = [
google_project_service.default,
]
}
google-beta provider の billing_project は「すでに作成済みの請求アカウントが紐付けられている firebase アカウント」を設定する必要があるようです(公式ドキュメントの説明が分かりづらいのですが、試したら動いたので合ってそう)。
billing_project を指定した場合は、併せて user_project_override = true
を設定する必要があります。
google_project
resource で Firebase 用の GCP プロジェクトを立ち上げます。この時 billing_account
を渡してあげると、最初から Blaze プランなプロジェクトを立ち上げることができます。べんり!
そして google_firebase_project
で Firebase プロジェクトを立ち上げます。depends_on に注意しながら設定してください。
作成したプロジェクトに設定を追加
上記で作成したプロジェクトに設定を追加していきます。
各種APIを有効化する
例えば Cloud Functions をデプロイするためには CloudBuild API の有効化が必要だったり、Firestore のルールを設定するためには Firestore API が必要だったりします。それらをまとめて有効化するには以下を追加します。
このコードでは、CloudBuild, Firestore に加えて、この後説明する Firebase Authentication を使うための API も有効化しています。
# Firebase プロジェクトが作られてから60秒待つ
resource "time_sleep" "wait_60_seconds" {
depends_on = [google_project.default]
create_duration = "60s"
}
# 各種APIを有効化する
resource "google_project_service" "default" {
provider = google-beta
project = google_project.default.project_id
for_each = toset([
"cloudbuild.googleapis.com",
"firestore.googleapis.com",
"cloudbilling.googleapis.com",
"cloudresourcemanager.googleapis.com",
"serviceusage.googleapis.com",
"identitytoolkit.googleapis.com",
])
service = each.key
disable_on_destroy = false
depends_on = [time_sleep.wait_60_seconds]
}
こういう作業は忘れると地味にハマるポイントなので、コード化できていると嬉しいですね。
ちなみに、Cloud Functions をデプロイするためには追加で権限の設定が必要だったりするので、お気をつけください。
参考: Cloud Functions for Firebase の権限
Firebase Authentication で メール/パスワード認証 を有効にする
以下のコードで Firebase Authentication、メール/パスワード認証 を有効にできます。
# Firebase Authentication を有効化する
resource "google_identity_platform_config" "default" {
provider = google-beta
project = google_project.default.project_id
depends_on = [
google_project_service.default,
]
}
# メール/パスワード認証 を有効にする
resource "google_identity_platform_project_default_config" "default" {
provider = google-beta
project = google_project.default.project_id
sign_in {
allow_duplicate_emails = false
email {
enabled = true
password_required = true
}
}
# email/password の認証を有効化する前に Firebase Authentication が有効化されるのを待つ
depends_on = [
google_identity_platform_config.default
]
}
ちなみに、Google認証 などの ID provider を追加するためには google_identity_platform_default_supported_idp_config を利用するのですが、これを使うためには client_id, client_secret が必要なので、設定が少し面倒でした。Google認証 などは Firebase コンソールからポチッとする方が楽かもしれません…。
Firestore を有効化する
以下のコードで Firestore を有効にできます。
resource "google_app_engine_application" "firebase" {
provider = google-beta
project = google_project.default.project_id
location_id = "asia-northeast1"
database_type = "CLOUD_FIRESTORE"
}
Webアプリを追加する
以下のコードでWebアプリを追加できます。
resource "google_firebase_web_app" "default" {
provider = google-beta
project = google_project.default.project_id
display_name = "web_app"
deletion_policy = "DELETE"
depends_on = [google_firebase_project.default]
}
また、google_firebase_web_app_config の data source を利用することで、firebase SDK を有効化するために使う id や key を output で出力できます。地味にべんりです!
data "google_firebase_web_app_config" "default" {
provider = google-beta
web_app_id = google_firebase_web_app.default.app_id
project = google_firebase_project.default.project
}
output "firebase_project_id" {
value = google_project.default.project_id
}
output "firebase_web_app_api_key" {
value = data.google_firebase_web_app_config.default.api_key
}
output "firebase_web_app_auth_domain" {
value = data.google_firebase_web_app_config.default.auth_domain
}
output "firebase_web_app_id" {
value = data.google_firebase_web_app_config.default.web_app_id
}
output "firebase_web_app_messaging_sender_id" {
value = data.google_firebase_web_app_config.default.messaging_sender_id
}
output "firebase_web_app_storage_bucket" {
value = data.google_firebase_web_app_config.default.storage_bucket
}
Android / iOS を追加する
Android, iOS のアプリも追加できます。
resource "google_firebase_android_app" "default" {
provider = google-beta
project = google_project.default.project_id
display_name = "My Android app"
package_name = "android.package.name"
depends_on = [google_firebase_project.default]
}
resource "google_firebase_apple_app" "default" {
provider = google-beta
project = google_project.default.project_id
display_name = "My Apple app"
bundle_id = "apple.app.12345"
depends_on = [google_firebase_project.default]
}
まとめ
Terraform で Firebase を立ち上げてみました。
私たちは上記コードを以下のような構成で module 化して、環境を簡単に追加できるようにしています。
$ tree .
.
├── README.md
└── gcp
├── environments
│ ├── qa1
│ │ └── main.tf
│ ├── qa2
│ │ └── main.tf
│ └── qa3
│ └── main.tf
└── modules
└── firebase
├── main.tf
├── outputs.tf
└── variables.tf
最初から Terraform 化するメリットはあまりないかもしれませんが、私たちのように多くの Firebase プロジェクトを管理したい場合には非常に便利でした。
参考になれば幸いです!
株式会社アルダグラムのTech Blogです。 世界中のノンデスクワーク業界における現場の生産性アップを実現する現場DXサービス「KANNA」を開発しています。 採用情報はこちら: herp.careers/v1/aldagram0508/
Discussion