Open1

【Google I/O 2023】Manage Firebase projects with Terraform

watabeewatabee

https://www.youtube.com/watch?v=32SKh-jGXI4&list=PLOU2XLYxmsIIwZQkAPhJZg8jaNrrHk1DH&index=68

Infrastructure-as-code (1:37~)

  • Terraform で Firebase のプロジェクトがセットアップできる

Firebase のリソースは google-beta プロバイダによってサポートされている。

terraform {
    required_providers {
        google-beta = {
            source = "hashicorp/google-beta"
            version = "~> 4.0"
        }
    }
}

google-beta プロバイダは user_project_override 属性を持っていて、Terraform からの操作がどのように使用状況をチェックされるかを決めることができる。
Terraform のエイリアスの機能によって、以下のように属性値を分けてプロバイダをセットアップすることができる。

provider "google-beta" {
    alias                 = "no_user_project_override"
    user_project_override = false
}

provider "google-beta" {
    user_project_override = true
}

Firebase のプロジェクトを作成するには、以下のように google_project のリソースに firebase を有効にして設定する。

resource "google_project" "prod" {
    provider        = google-beta.no_user_project_override
    
    name            = "Project Display Name"
    project_id      = "project-id-for-new-project"
    billing_account = "000000-000000-000000"
    
    labels = {
        "firebase" = "enabled"
    }
}

続いて Service Usage API と Firebase Management API を有効にする。
これは Firebase Console を使った場合は裏側で行われている処理となっている。

resource "google_project_service" "prod-init" {
    provider = google-beta.no_user_project_override
    
    project = google_project.prod.project_id
    for_each = toset([
        "serviceusage.googleapis.com",
        "firebase.googleapis.com",
    ])
    service = each.key
    
    disable_on_destroy = false
}

最後に firebase のプロジェクトを作成する。

resource "google_firebase_project" "prod" {
    provider = google-beta
    project  = google_project.prod.project_id
    
    depends_on = [
        google_project_service.prod-init,
    ]
}

Add Firebase Resources (4:13~)

Android、iOS、Web 用にリソースを作る。

resource "google_firebase_android_app" "prod" {
    provider     = google_beta
    project      = google_firebase_project.prod.project
    display_name = "My Android app"
    package_name = "com.example.myandroidapp"
}

resource "google_firebase_apple_app" "prod" {
    provider     = google_beta
    project      = google_firebase_project.prod.project
    display_name = "My Apple app"
    bundle_id    = "com.example.myappleapp"
}

resource "google_firebase_web_app" "prod" {
    provider        = google-beta
    project         = google_firebase_project.prod.project_id
    display_name    = "My Web app"
    deletion_policy = "DELETE"
}

Authenticatin と Firestore を追加する場合の例。
Terraform でリソースを作った際に必要な API が有効になっていなければ、エラーとなって Terraform は必要な API の名前を出力してくれる。

resource "google_project_service" "prod" {
    provider = google-beta
    
    project = google_project.prod.project_id
    for_each = toset([
        "cloudbilling.googleapis.com",
        "firestore.googleapis.com",
        "firebaserules.googleapis.com",
        "identitytoolkit.googleapis.com",
    ])
    service = each.key
    
    disable_on_destroy = false
}

Firestore データベースの作成。

resource "google_firestore_database" "prod" {
    provider         = google-beta
    project          = google_firebase_project.prod.project
    name             = "(default)"
    
    location         = "name-of-region"
    
    type             = "FIRESTORE_NATIVE"
    concurrency_mode = "OPTIMISTIC"
    
    depends_on = [
        google_project_service.prod,
    ]
}

Firestore のセキュリティルールの作成。

resource "google_firebaserules_ruleset" "prod" {
    provider = google-beta
    project  = google_firebase_project.prod.project
    source {
        files {
            name    = "firestore.rules"
            content = file("firestore.rules")
        }
    }
        
    depends_on = [
        google_firestore_database.prod,
    ]
}


resource "google_firebaserules_release" "prod" {
    provider     = google-beta
    name         = "cloud.firestore" 
    ruleset_name = google_firebaserules_ruleset.prod.name
    project      = google_firebase_project.prod.project
}

Authentication の設定。

resource "google_identity_platform_config" "prod" {
    provider = google-beta
    project  = google_firebase_project.prod.project
    
    autodelete_anonymous_users = true

    depends_on = [
        google_project_service.prod,
    ]
}

サインインの方法を設定する。

resource "google_identity_platform_project_default_config" "prod" {
    provider = google-beta
    project  = google_firebase_project.prod.project
    sign_in {
        anonymous {
            enabled = true
        }
        email {
            enabled = true
        }
        phone_number {
            enabled = true
        }
    }
    
    depends_on = [
        google_identity_platform_config.prod,
    ]
}

Terraform CLI (6:23~)

Terraform の主要なコマンドは以下の3つ。

  • terraform init
    • 初期化
  • terraform plan
    • リソースの作成や削除、変更のプレビュー
  • terraform apply
    • リソースの作成や削除、変更を行う

terraform show コマンドでプロジェクトについての詳細を見ることができる。

ステージング環境のプロジェクトを作成する (8:07~)

本番環境のリソースをコピーしてステージング環境用のリソースを作る。

resource "google_project" "staging" { ... }
resource "google_firebase_project" "staging" { ... }
resource "google_project_service" "staging" { ... }

...

もしコピペで作りたくない場合、Terraform には for ループに似た機能があるのでそれを使うとよい。

コピペの場合はステージング環境用に google_project の name や project_id、google_firebase_android_app の display_name などを変えることができる。

Update infrastructure (9:27~)

新しい firestore のルールを適用したいとする。
その場合以下のような感じで変更する。

resource "google_firebaserules_ruleset" "staging-V2" {
    provider = google-beta
    project  = google_firebase_project.staging.project
    source {
        files {
            name    = "firestore.V2.rules"
            content = file("firestore.V2.rules")
        }
    }
        
    depends_on = [
        google_firestore_database.staging,
    ]
}

resource "google_firebaserules_release" "staging" {
    provider     = google-beta
    name         = "cloud.firestore" 
    ruleset_name = google_firebaserules_ruleset.stating-V2.name
    project      = google_firebase_project.staging.project
}