Terraform을 통해 Firebase 프로젝트와 제품 설정 및 관리

1. 소개

목표

Terraform을 사용하여 인프라 및 Firebase 제품의 프로그래매틱 구성을 포함하여 Firebase 프로젝트를 설정하고 관리할 수 있습니다.

이 Codelab에서는 먼저 Terraform 구성 파일을 빌드하여 새 Firebase 프로젝트를 만드는 방법과 해당 프로젝트에서 사용할 앱과 Firebase 제품을 구성하는 방법을 설명합니다. 또한 변경사항을 미리 보고 구현하는 등 Terraform 명령줄의 기본사항에 대해서도 다룹니다.

Terraform으로 Firebase 프로젝트와 제품을 설정하고 관리하는 방법을 배우고 싶다면 이 Codelab이 도움이 될 것입니다.

학습할 내용

  • Terraform 구성 파일 (*.tf)을 만드는 방법
  • Terraform CLI 명령어를 사용하여 인프라를 관리하는 방법
  • 구성을 수정하여 리소스와 서비스를 업데이트하는 방법
  • 실제 웹 앱에 구성을 적용하는 방법 (친절한 채팅이라고 함)
  • 다양한 환경 (프로덕션, 스테이징 등)에서 동시 (및 동기화) 구성을 정의하는 방법

필요한 사항

이 Codelab을 성공적으로 진행하려면 다음 기본 요건을 비롯한 Terraform과 용어에 대한 기본 숙련도가 필요합니다.

이 Codelab은 Terraform을 통해 프로비저닝하는 항목을 테스트하고 상호작용할 수 있도록 실제 샘플 앱을 제공합니다. 그러려면 다음이 필요합니다.

  • 웹 앱의 샘플 코드 - Codelab의 다음 단계에서 이 코드 다운로드
  • 패키지 관리자 npm (일반적으로 Node.js와 함께 제공) - 이러한 도구를 설치합니다.
  • Firebase CLI - 이 CLI를 설치하고 로그인합니다.

2. 시작 코드 가져오기

이 Codelab에서는 실제 웹 앱에서 Terraform을 통해 프로비저닝하는 항목을 테스트할 수 있습니다. Terraform에서 프로비저닝한 리소스를 사용하는 데 필요한 모든 단계를 이해할 수 있도록 이 작업을 수행하는 것이 좋습니다.

명령줄에서 Codelab의 GitHub 저장소를 클론합니다.

git clone https://github.com/firebase/codelab-friendlychat-web

또는 git이 설치되어 있지 않으면 저장소를 ZIP 파일로 다운로드할 수 있습니다.

3. Terraform 구성 만들기

Terraform 설정

  1. 다운로드한 샘플 앱의 코드베이스에서 web 디렉터리의 루트로 이동합니다.
  2. 해당 디렉터리의 루트에서 다음 초기 설정을 사용하여 main.tf라는 Terraform 구성 파일을 만듭니다.

    main.tf
    # Terraform configuration to set up providers by version.
    terraform {
      required_providers {
        google-beta = {
          source  = "hashicorp/google-beta"
          version = "~> 4.0"
        }
      }
    }
    
    # Configure the provider not to use the specified project for quota check.
    # This provider should only be used during project creation and initializing services.
    provider "google-beta" {
      alias                 = "no_user_project_override"
      user_project_override = false
    }
    
    # Configure the provider that uses the new project's quota.
    provider "google-beta" {
      user_project_override = true
    }
    

google-beta 제공업체에는 Terraform 작업의 할당량을 확인하는 방법을 결정하는 user_project_override라는 속성이 있습니다. 대부분의 리소스 프로비저닝은 user_project_override = true를 사용해야 합니다. 즉, 자체 Firebase 프로젝트와 비교하여 할당량을 확인합니다. 그러나 할당량 확인을 허용할 수 있도록 새 프로젝트를 설정하려면 먼저 user_project_override=false를 사용해야 합니다. Terraform alias 구문을 사용하면 이 Codelab의 다음 단계에서 두 제공업체 설정을 구분할 수 있습니다.

디렉터리에서 Terraform 초기화

새 구성을 처음 만들려면 구성에 지정된 제공업체를 다운로드해야 합니다.

초기화하려면 main.tf 구성 파일과 동일한 디렉터리의 루트에서 다음 명령어를 실행합니다.

terraform init

4. Terraform을 통해 Firebase 프로젝트 만들기

'Firebase 프로젝트를 생성'하려면 각 Firebase 프로젝트가 실제로는 Google Cloud 프로젝트이며 Firebase 서비스가 사용 설정되어 있어야 합니다.

기본 Google Cloud 프로젝트 및 API용 블록 추가

  1. 먼저 기본 Google Cloud 프로젝트를 프로비저닝합니다.

    main.tf 구성 파일에 다음 리소스 블록을 추가합니다.

    자체 프로젝트 이름 (예: "Terraform FriendlyChat Codelab")과 자체 프로젝트 ID (예: "terraform-codelab-your-initials")를 지정해야 합니다. name 값은 Firebase 인터페이스 내에서만 사용되며 최종 사용자에게는 표시되지 않습니다. 하지만 project_id 값은 Google에서 프로젝트를 고유하게 식별하므로 고유한 값을 지정해야 합니다. main.tf
    ...
    
    # Create a new Google Cloud project.
    resource "google_project" "default" {
      provider = google-beta.no_user_project_override
    
      name            = "<PROJECT_NAME_OF_YOUR_PROJECT>"
      project_id      = "<PROJECT_ID_OF_YOUR_PROJECT>"
    
      # Required for the project to display in any list of Firebase projects.
      labels = {
        "firebase" = "enabled"
      }
    }
    
  2. 다음으로 필요한 기본 API인 Service Usage API와 Firebase Management API를 사용 설정해야 합니다.

    이 API 사용 설정은 일반적으로 Firebase Console을 사용하여 Firebase 프로젝트를 만들 때 백그라운드에서 처리되지만 Terraform은 명시적으로 사용 설정을 해야 합니다.

    main.tf 구성 파일 (새 Cloud 프로젝트를 만드는 블록 바로 아래에 있음)에 다음 리소스 블록을 추가하여 프로젝트 할당량 확인을 허용합니다.

    main.tf
    ...
    
    # Enable the required underlying Service Usage API.
    resource "google_project_service" "serviceusage" {
      provider = google-beta.no_user_project_override
    
      project = google_project.default.project_id
      service = "serviceusage.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable the required underlying Firebase Management API.
    resource "google_project_service" "firebase" {
      provider = google-beta.no_user_project_override
    
      project = google_project.default.project_id
      service = "firebase.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    따라서 이후의 모든 리소스 프로비저닝 및 서비스 사용 설정 시에는 공급자를 user_project_override 과 함께 사용해야 합니다 (별칭은 필요하지 않음).

블록을 추가하여 Firebase 서비스 사용 설정

'Firebase 프로젝트를 만드는' 데 필요한 마지막 작업은 프로젝트에서 Firebase 서비스를 사용 설정하는 것입니다.

계속 진행하여 main.tf 구성 파일에서 다음 리소스 블록을 추가합니다.

위에서 언급했듯이 이 리소스 블록은 user_project_override (별칭이 필요하지 않음) 와 함께 제공자를 사용합니다.

main.tf

...

# Enable Firebase services for the new project created above.
resource "google_firebase_project" "default" {
  provider = google-beta

  project = google_project.default.project_id

  # Wait until the required APIs are enabled.
  depends_on = [
    google_project_service.firebase,
    google_project_service.serviceusage,
  ]
}

위의 리소스 블록에서는 Terraform에 기본 API가 사용 설정될 때까지 기다리도록 지시하는 depends_on 절을 볼 수 있습니다. 이 절이 없으면 Terraform은 종속 항목을 알지 못하며 리소스를 동시에 프로비저닝할 때 오류가 발생할 수 있습니다.

구성 적용

  1. 새 리소스를 프로비저닝하고 구성 파일에 지정된 API를 사용 설정하려면 main.tf 파일 (web이어야 함)과 동일한 디렉터리의 루트에서 다음 명령어를 실행합니다.
    terraform apply
    
  2. Terraform은 터미널에서 수행할 작업 계획을 출력합니다.

    모든 항목이 예상대로 표시되면 yes를 입력하여 작업을 승인합니다.

    main.tf
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      + create
    
    Terraform will perform the following actions:
    
      # google_firebase_project.default will be created
      + resource "google_firebase_project" "default" {
          + display_name   = (known after apply)
          + id             = (known after apply)
          + project        = "terraform-friendlychat-codelab"
          + project_number = (known after apply)
        }
    
      # google_project.default will be created
      + resource "google_project" "default" {
          + auto_create_network = true
          + id                  = (known after apply)
          + labels              = {
              + "firebase" = "enabled"
            }
          + name                = "Terraform FriendlyChat Codelab"
          + number              = (known after apply)
          + project_id          = "terraform-friendlychat-codelab"
          + skip_delete         = (known after apply)
        }
    
      # google_project_service.firebase will be created
      + resource "google_project_service" "firebase" {
          + disable_on_destroy = false
          + id                 = (known after apply)
          + project            = "terraform-friendlychat-codelab"
          + service            = "firebase.googleapis.com"
        }
    
      # google_project_service.serviceusage will be created
      + resource "google_project_service" "serviceusage" {
          + disable_on_destroy = false
          + id                 = (known after apply)
          + project            = "terraform-friendlychat-codelab"
          + service            = "serviceusage.googleapis.com"
        }
    
    Plan: 4 to add, 0 to change, 0 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes # <----
    

적용하지 않고 변경사항을 미리 보기만 하면 되는 경우 terraform plan 명령어를 대신 사용할 수 있습니다.

변경사항 확인

Terraform 실행이 완료되면 다음 명령어를 실행하여 사용 설정된 모든 Terraform 프로비저닝된 리소스 및 서비스의 상태를 검사할 수 있습니다.

terraform show

다음은 출력되어야 하는 내용의 예입니다. 주/도에는 프로젝트에 해당하는 값이 포함됩니다.

# google_firebase_project.default:
resource "google_firebase_project" "default" {
    display_name   = "Terraform FriendlyChat Codelab"
    id             = "projects/terraform-friendlychat-codelab"
    project        = "terraform-friendlychat-codelab"
    project_number = "000000000"
}

# google_project.default:
resource "google_project" "default" {
    auto_create_network = true
    id                  = "projects/terraform-friendlychat-codelab"
    labels              = {
        "firebase" = "enabled"
    }
    name                = "Terraform FriendlyChat Codelab"
    number              = "000000000"
    project_id          = "terraform-friendlychat-codelab"
}

# google_project_service.firebase:
resource "google_project_service" "firebase" {
    disable_on_destroy = false
    id                 = "terraform-friendlychat-codelab/firebase.googleapis.com"
    project            = "terraform-friendlychat-codelab"
    service            = "firebase.googleapis.com"
}

# google_project_service.serviceusage:
resource "google_project_service" "serviceusage" {
    disable_on_destroy = false
    id                 = "terraform-friendlychat-codelab/serviceusage.googleapis.com"
    project            = "terraform-friendlychat-codelab"
    service            = "serviceusage.googleapis.com"
}

또는 Firebase Console에서 프로젝트를 확인하여 프로젝트가 생성되었는지 확인할 수 있습니다.

Firebase Console에서 선택된 Terraform FriendlyChat Codelab 프로젝트

5. Terraform을 통해 Firebase 앱 등록

Firebase를 사용하려면 Firebase 프로젝트에 앱의 각 플랫폼 변형을 등록해야 합니다. 이 Codelab에서는 실제 앱을 사용하여 Terraform을 통해 프로비저닝하는 항목을 테스트하고 상호작용합니다. 이 앱은 웹 앱이므로 새로 만든 Firebase 프로젝트에 Firebase 웹 앱을 등록하도록 Terraform에 지시해야 합니다.

웹 앱을 등록하는 블록 추가

Firebase 프로젝트에 웹 앱을 등록하려면 main.tf 파일에 다음 리소스 블록을 추가합니다.

웹 앱의 자체 display_name를 지정해야 합니다. 이 이름은 Firebase 인터페이스에서만 사용되며 최종 사용자에게는 표시되지 않습니다.

main.tf

...

# Create a Firebase Web App in the new project created above.
resource "google_firebase_web_app" "default" {
  provider = google-beta

  project      = google_firebase_project.default.project
  display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>"
  deletion_policy = "DELETE"
}

구성 적용

  1. 새 리소스를 프로비저닝하려면 main.tf 파일과 동일한 디렉터리 (web이어야 함)의 루트에서 다음 명령어를 실행합니다.
    terraform apply
    
    이 명령어로는 새 Google Cloud 프로젝트가 다시 생성되지 않습니다. Terraform은 지정된 프로젝트 ID를 사용하는 프로젝트가 이미 있는지 감지하고 프로젝트의 현재 상태를 .tf 파일의 상태와 비교한 후 발견한 사항을 변경합니다.
  2. 인쇄된 작업 계획을 검토합니다. 모든 항목이 예상대로 표시되면 yes를 입력하고 Enter 키를 눌러 작업을 승인합니다.

변경사항 확인

다음 명령어를 실행하여 새로 프로비저닝된 리소스의 상태를 검사할 수 있습니다.

terraform show

또는 Firebase Console에서 앱을 확인하여 앱이 프로젝트에 성공적으로 등록되었는지 확인할 수 있습니다. 프로젝트 설정으로 이동한 다음 내 앱 섹션까지 아래로 스크롤합니다.

6. Firebase 인증 설정

인증은 앱에서 중요한 부분입니다. 최종 사용자가 자신의 Google 계정으로 웹 앱에 로그인할 수 있도록 하려면 Firebase 인증을 사용 설정하고 Google 계정으로 로그인을 설정하면 됩니다.

이 Codelab에서는 Firebase 인증을 설정하는 두 가지 옵션을 제공합니다.

  • 옵션 1 (권장): GCIP가 필요 없는 Console에서 Firebase 인증을 설정합니다.
    • 이 옵션을 사용하면 새 프로젝트를 Cloud Billing 계정과 연결할 필요가 없습니다.
  • 옵션 2: Google Cloud Identity Platform (GCIP) API를 사용하여 Terraform을 통해 Firebase 인증을 설정합니다.
    • GCIP를 사용하려면 프로젝트가 Blaze 요금제를 사용해야 하므로 이 옵션을 사용하면 새 프로젝트를 Cloud Billing 계정과 연결해야 합니다.

옵션 1: Firebase Console을 사용하여 인증 설정

프로젝트에서 Blaze 요금제를 사용하지 않아도 Firebase Console을 사용하여 Firebase 인증을 설정할 수 있습니다.

Firebase 인증을 설정하고 Google 계정으로 로그인하는 방법은 다음과 같습니다.

  1. Firebase Console의 왼쪽 패널에 있는 빌드 섹션을 찾습니다.
  2. 인증을 클릭하고 시작하기를 클릭한 후 로그인 방법 탭을 클릭합니다 (또는 여기를 클릭하여 바로 이동).
  3. 새 제공업체 추가를 클릭하고 추가 제공업체 섹션에서 Google을 선택합니다.
  4. 사용 설정 전환 버튼을 활성화합니다.
  5. 앱의 공개용 이름을 FriendlyChat와 같이 설정합니다 (전역적으로 고유할 필요는 없음).
  6. 드롭다운 메뉴에서 프로젝트 지원 이메일을 선택한 후 저장을 클릭합니다.Firebase Console에서 Firebase 인증 구성
  7. Google이 사용 설정된 로그인 제공업체로 표시되어야 합니다.Firebase Console 인증 페이지: Google 로그인 사용 설정됨

옵션 2: Google Cloud Identity Platform (GCIP) API를 사용하여 Terraform을 통해 인증 설정

Terraform을 통해 Firebase 인증을 설정하려면 GCIP API를 사용해야 합니다. 즉, 프로젝트가 Blaze 요금제를 사용해야 합니다. Cloud Billing 계정을 프로젝트와 연결하여 Blaze 요금제를 사용하도록 Firebase 프로젝트를 업그레이드합니다.

Terraform을 통한 결제 사용 설정

  1. 아직 Cloud Billing 계정이 없는 경우 첫 번째 단계는 Google Cloud 콘솔에서 새 계정을 만드는 것입니다. 이때 결제 계정 ID를 기록해 둡니다. 결제 계정 ID는 결제 페이지의 프로젝트와 연결된 결제 계정 ID에서 확인할 수 있습니다.Google Cloud 콘솔을 사용하여 결제 계정 사용 설정
  2. Terraform을 통해 프로젝트에서 결제를 사용 설정하려면 billing_account 속성을 main.tf 파일의 기존 google_project 리소스에 추가합니다.

    main.tf
    ...
    
    # Create a new Google Cloud project.
    resource "google_project" "default" {
      provider = google-beta.no_user_project_override
    
      name            = "<PROJECT_NAME_OF_YOUR_PROJECT>"
      project_id      = "<PROJECT_ID_OF_YOUR_PROJECT>"
      billing_account = "<YOUR_BILLING_ACCOUNT_ID>" # Add this line with your Cloud Billing account ID
    
      # Required for the project to display in any list of Firebase projects.
      labels = {
        "firebase" = "enabled"
      }
    }
    
    ...
    

Firebase 인증 사용 설정 및 Terraform을 통해 Google로 로그인

  1. GCIP로 Firebase 인증을 프로비저닝하려면 main.tf 파일에 다음 리소스 블록을 추가합니다.

    main.tf
    ...
    
    # Enable the Identity Toolkit API.
    resource "google_project_service" "auth" {
      provider = google-beta
    
      project  = google_firebase_project.default.project
      service =  "identitytoolkit.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Create an Identity Platform config.
    # Also, enable Firebase Authentication using Identity Platform (if Authentication isn't yet enabled).
    resource "google_identity_platform_config" "auth" {
      provider = google-beta
      project  = google_firebase_project.default.project
    
      # For example, you can configure to auto-delete anonymous users.
      autodelete_anonymous_users = true
    
      # Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication.
      depends_on = [
        google_project_service.auth,
      ]
    }
    
  2. Google 계정으로 로그인을 사용 설정하려면 OAuth 클라이언트가 있어야 합니다. 이 설정을 수행하려면 Google Cloud 콘솔의 API 및 서비스 섹션으로 이동합니다.
  3. 이 프로젝트의 클라이언트 ID를 처음 생성하므로 OAuth 동의 화면을 구성해야 합니다.
    1. OAuth 동의 화면 페이지를 열고 방금 만든 프로젝트를 선택합니다.
    2. 사용자 유형외부로 설정한 다음 만들기를 클릭합니다.
    3. 다음 화면에서 다음을 완료하고 저장하고 계속하기를 클릭합니다.
      • 앱의 공개용 앱 이름FriendlyChat와 같은 이름으로 설정합니다 (전역적으로 고유할 필요는 없음).
      • 드롭다운 메뉴에서 사용자 지원 이메일을 선택합니다.
      • 개발자 연락처 정보의 이메일을 입력합니다.
    4. 다음 화면에서 다음을 완료합니다.
      • 범위 페이지에서 기본값을 수락한 다음 저장하고 계속하기를 클릭합니다.
      • 테스트 사용자 페이지에서 기본값을 수락한 다음 저장하고 계속하기를 클릭합니다.
      • 요약을 검토한 다음 대시보드로 돌아가기를 클릭합니다.
      Google Cloud 콘솔을 사용하여 OAuth2 클라이언트 구성
  4. 다음을 수행하여 사용자 인증 정보 페이지에서 OAuth 클라이언트를 설정합니다.
    1. 사용자 인증 정보 만들기를 클릭하고 OAuth 클라이언트 ID를 선택합니다.
    2. 애플리케이션 유형 드롭다운에서 웹 애플리케이션을 선택합니다.
    3. Name 필드에 앱 이름을 입력합니다 (예: FriendlyChat). 전역적으로 고유할 필요는 없습니다.
    4. 다음을 설정하여 앱의 URL에서 이 OAuth 클라이언트를 사용하도록 허용합니다.
      • 승인된 자바스크립트 원본에서 URI 추가를 클릭하고
        https://<PROJECT_ID>.firebaseapp.com을 입력합니다. 여기서 <PROJECT_ID>main.tf에서 설정한 프로젝트 ID입니다.
      • 승인된 리디렉션 URI에서 URI 추가를 클릭하고
        https://<PROJECT_ID>.firebaseapp.com/__/auth/handler를 입력합니다. 여기서 <PROJECT_ID>main.tf에서 설정한 프로젝트 ID입니다.
    5. 저장을 클릭합니다.
    Google Cloud 콘솔 사용자 인증 정보 페이지에서 OAuth2 클라이언트 ID 및 보안 비밀 가져오기
  5. OAuth 클라이언트 ID와 클라이언트 보안 비밀번호를 사용하여 Google 계정으로 로그인을 사용 설정하려면 main.tf 파일에 다음 블록을 추가하세요.

    main.tf
    ...
    
    variable "oauth_client_secret" {
      type = string
    
      description = "OAuth client secret. For this codelab, you can pass in this secret through the environment variable TF_VAR_oauth_client_secret. In a real app, you should use a secret manager service."
    
      sensitive = true
    }
    
    resource "google_identity_platform_default_supported_idp_config" "google_sign_in" {
      provider = google-beta
      project  = google_firebase_project.default.project
    
      enabled       = true
      idp_id        = "google.com"
      client_id     = "<YOUR_OAUTH_CLIENT_ID>"
      client_secret = var.oauth_client_secret
    
      depends_on = [
         google_identity_platform_config.auth
      ]
    }
    

구성 적용

  1. 구성에 따라 인증을 설정하려면 main.tf 파일 (web이어야 함)과 동일한 디렉터리의 루트에서 다음 명령어를 실행합니다.
    export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
    
    terraform apply
    
    terraform apply를 실행해도 새 Google Cloud 프로젝트가 다시 생성되지 않습니다. Terraform은 지정된 프로젝트 ID를 사용하는 프로젝트가 이미 있음을 감지하고 프로젝트의 현재 상태를 .tf 파일에 있는 것과 비교합니다. 그런 다음 확인된 데이터를 변경합니다.
  2. 인쇄된 작업 계획을 검토합니다. 모든 항목이 예상대로 표시되면 yes를 입력하고 Enter 키를 눌러 작업을 승인합니다.

변경사항 확인

  1. Firebase Console의 왼쪽 패널에 있는 빌드 섹션을 찾습니다.
  2. 인증을 클릭한 후 로그인 방법 탭을 클릭합니다 (또는 여기를 클릭하여 바로 이동).
  3. Google이 사용 설정된 로그인 제공업체로 표시되어야 합니다.Firebase Console 인증 페이지: Google 로그인 사용 설정됨

7. Firestore 데이터베이스 및 보안 규칙 설정

이 Codelab의 웹 앱에서는 최종 사용자 간 메시지를 Firestore 데이터베이스에 저장합니다.

  1. 필수 API를 사용 설정하고 데이터베이스 인스턴스를 프로비저닝하려면 main.tf 파일에 다음 리소스 블록을 추가합니다.

    main.tf
    ...
    
    # Enable required APIs for Cloud Firestore.
    resource "google_project_service" "firestore" {
      provider = google-beta
    
      project  = google_firebase_project.default.project
      for_each = toset([
        "firestore.googleapis.com",
        "firebaserules.googleapis.com",
      ])
      service = each.key
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Provision the Firestore database instance.
    resource "google_firestore_database" "default" {
      provider                    = google-beta
    
      project                     = google_firebase_project.default.project
      name                        = "(default)"
      # See available locations:
      # https://firebase.google.com/docs/firestore/locations
      location_id                 = "<NAME_OF_DESIRED_REGION>"
      # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs,
      # authentication, and Firebase Security Rules.
      type                        = "FIRESTORE_NATIVE"
      concurrency_mode            = "OPTIMISTIC"
    
      depends_on = [
        google_project_service.firestore
      ]
    }
    
  2. <NAME_OF_DESIRED_REGION>을 데이터베이스를 배치할 리전으로 변경합니다.

    프로덕션 앱을 개발할 때 사용자 대다수의 사용자에게 가까운 리전에 위치하고 Cloud Functions와 같은 다른 Firebase 서비스와 공통되는 리전이어야 합니다. 이 Codelab에서는 us-east1 (사우스캐롤라이나)을 사용하거나 가장 가까운 리전을 사용할 수 있습니다 (Cloud Firestore 위치 참고).
  3. Firebase에서 액세스할 수 있는 모든 Firestore 데이터베이스 인스턴스는 Firebase 보안 규칙으로 보호되어야 합니다.

    이 Codelab의 샘플 코드는 web 디렉터리의 루트에서 확인할 수 있는 firestore.rules 파일에 보안 Firestore 규칙 집합을 제공합니다.
  4. main.tf 파일에 다음 리소스 블록을 추가하여 다음 작업을 실행합니다.
    • 로컬 firestore.rules 파일에서 Firebase 보안 규칙의 규칙 세트를 만듭니다.
    • Firestore 인스턴스의 규칙 세트를 해제합니다.
    이러한 리소스 블록은 Firebase Console에서 게시 버튼을 클릭하거나 firebase deploy --only firestore:rules.

    main.tf
    ...
    
    # Create a ruleset of Firestore Security Rules from a local file.
    resource "google_firebaserules_ruleset" "firestore" {
      provider = google-beta
    
      project  = google_firebase_project.default.project
      source {
        files {
          name = "firestore.rules"
          # Write security rules in a local file named "firestore.rules".
          # Learn more: https://firebase.google.com/docs/firestore/security/get-started
          content = file("firestore.rules")
        }
      }
    
      # Wait for Firestore to be provisioned before creating this ruleset.
      depends_on = [
        google_firestore_database.default,
      ]
    }
    
    # Release the ruleset for the Firestore instance.
    resource "google_firebaserules_release" "firestore" {
      provider     = google-beta
    
      name         = "cloud.firestore"  # must be cloud.firestore
      ruleset_name = google_firebaserules_ruleset.firestore.name
      project      = google_firebase_project.default.project
    
      # Wait for Firestore to be provisioned before releasing the ruleset.
      depends_on = [
        google_firestore_database.default,
      ]
    
      lifecycle {
        replace_triggered_by = [
          google_firebaserules_ruleset.firestore
        ]
      }
    }
    
    를 실행하는 것과 동일한 결과를 얻습니다.
  5. terraform apply를 실행하여 Firestore 데이터베이스를 프로비저닝하고 보안 규칙을 배포합니다.
  6. 데이터베이스가 프로비저닝되고 보안 규칙이 배포되었는지 확인합니다.
    1. Firebase Console의 왼쪽 패널에 있는 빌드 섹션을 찾습니다.
    2. Firestore 데이터베이스 섹션으로 이동한 다음 규칙 탭을 클릭합니다.
    Firebase Console을 사용하여 Cloud Firestore 규칙 확인

8. Cloud Storage 버킷 및 보안 규칙 설정

이 Codelab의 웹 앱에서는 최종 사용자 간에 공유되는 이미지를 Cloud Storage 버킷에 저장합니다.

  1. 필요한 API를 사용 설정하고 Cloud Storage 기본 버킷을 프로비저닝하려면 main.tf 파일에 다음 리소스 블록을 추가하세요.

    프로젝트의 기본 Cloud Storage 버킷은 Google App Engine을 통해 프로비저닝되며 Firestore 데이터베이스와 동일한 위치에 있어야 합니다. 자세한 내용은 App Engine 위치를 참조하세요.

    프로젝트에 여러 개의 버킷이 필요한 경우 google_storage_bucket 리소스를 사용하여 버킷을 프로비저닝합니다 (이 Codelab에 나오지 않음).

    main.tf
    ...
    
    # Enable required APIs for Cloud Storage for Firebase.
    resource "google_project_service" "storage" {
      provider = google-beta
    
      project  = google_firebase_project.default.project
      for_each = toset([
        "firebasestorage.googleapis.com",
        "storage.googleapis.com",
      ])
      service = each.key
    
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Provision the default Cloud Storage bucket for the project via Google App Engine.
    resource "google_app_engine_application" "default" {
      provider    = google-beta
    
      project     = google_firebase_project.default.project
      # See available locations: https://firebase.google.com/docs/projects/locations#default-cloud-location
      # This will set the location for the default Storage bucket and the App Engine App.
      location_id = "<NAME_OF_DESIRED_REGION_FOR_DEFAULT_BUCKET>"  # Must be in the same location as Firestore (above)
    
      # Wait until Firestore is provisioned first.
      depends_on = [
        google_firestore_database.default
      ]
    }
    
    # Make the default Storage bucket accessible for Firebase SDKs, authentication, and Firebase Security Rules.
    resource "google_firebase_storage_bucket" "default-bucket" {
      provider  = google-beta
    
      project   = google_firebase_project.default.project
      bucket_id = google_app_engine_application.default.default_bucket
    }
    
  2. Firebase에서 액세스할 수 있는 모든 Cloud Storage 버킷은 Firebase 보안 규칙으로 보호해야 합니다.

    이 Codelab의 샘플 코드는 web 디렉터리의 루트에서 확인할 수 있는 storage.rules 파일에 보안 Firestore 규칙 집합을 제공합니다.
  3. main.tf 파일에 다음 리소스 블록을 추가하여 다음 작업을 실행합니다.
    • 로컬 파일에서 Firebase 보안 규칙의 규칙 세트를 만듭니다.
    • Storage 버킷의 규칙 집합을 해제합니다.
    이러한 리소스 블록은 Firebase Console에서 게시 버튼을 클릭하거나 firebase deploy --only storage.

    main.tf
    ...
    
    # Create a ruleset of Cloud Storage Security Rules from a local file.
    resource "google_firebaserules_ruleset" "storage" {
      provider = google-beta
    
      project  = google_firebase_project.default.project
      source {
        files {
          # Write security rules in a local file named "storage.rules".
          # Learn more: https://firebase.google.com/docs/storage/security/get-started
          name    = "storage.rules"
          content = file("storage.rules")
        }
      }
    
      # Wait for the default Storage bucket to be provisioned before creating this ruleset.
      depends_on = [
        google_firebase_storage_bucket.default-bucket,
      ]
    }
    
    # Release the ruleset to the default Storage bucket.
    resource "google_firebaserules_release" "default-bucket" {
      provider     = google-beta
    
      name         = "firebase.storage/${google_app_engine_application.default.default_bucket}"
      ruleset_name = "projects/${google_firebase_project.default.project}/rulesets/${google_firebaserules_ruleset.storage.name}"
      project      = google_firebase_project.default.project
    
      lifecycle {
        replace_triggered_by = [
          google_firebaserules_ruleset.storage
        ]
      }
    }
    
    를 실행하는 것과 동일한 결과를 얻습니다.
  4. terraform apply를 실행하여 기본 Cloud Storage 버킷을 프로비저닝하고 해당 보안 규칙을 배포합니다.
  5. 버킷이 프로비저닝되고 해당 보안 규칙이 배포되었는지 확인합니다.
    1. Firebase Console의 왼쪽 패널에 있는 빌드 섹션을 찾습니다.
    2. 스토리지 섹션으로 이동한 다음 규칙 탭을 클릭합니다.
    Firebase Console을 사용하여 보안 규칙 확인

9. 로컬에서 앱 실행

이제 웹 앱을 처음으로 실행할 준비가 되었습니다. Firebase 호스팅 에뮬레이터를 사용하여 로컬에서 앱을 제공합니다.

  1. 새 터미널 창을 열고 web 디렉터리에서 다음 Firebase CLI 명령어를 실행하여 에뮬레이터를 시작합니다.
    firebase emulators:start --project=<PROJECT_ID>
    
  2. 브라우저에서 CLI가 반환한 로컬 URL (일반적으로 http://localhost:5000)으로 웹 앱을 엽니다.

아직 작동하지 않는 FriendlyChat 앱의 UI가 표시됩니다. 앱이 아직 Firebase에 연결되지 않았지만 이 Codelab의 다음 단계를 완료하면 Firebase에 연결됩니다.

이 Codelab의 다음 단계에서 실행하는 것처럼 웹 앱을 변경할 때마다 브라우저를 새로고침하여 변경사항으로 로컬 URL을 업데이트합니다.

10. Firebase 설치, 구성, 초기화

앱에서 Firebase를 사용하려면 앱에 Firebase SDK 및 Firebase 프로젝트에 대한 Firebase 구성이 필요합니다.

이 Codelab의 샘플 코드는 앱에서 다양한 Firebase 제품을 사용하는 데 필요한 모든 종속 항목과 필수 함수가 포함된 작동 중인 앱입니다. 이미 완료된 작업을 확인하려면 web/package.jsonweb/src/index.js를 살펴보세요.

샘플 코드는 거의 완성되어 있지만 Firebase SDK 설치, 빌드 시작, 앱에 Firebase 구성 추가, Firebase 초기화 등 앱을 실행하려면 몇 가지 작업을 수행해야 합니다.

Firebase SDK 설치 및 webpack 빌드 시작

몇 가지 명령어를 실행하여 앱 빌드를 시작해야 합니다.

  1. 새 터미널 창을 엽니다.
  2. web 디렉터리의 루트에 있는지 확인합니다.
  3. npm install를 실행하여 Firebase SDK를 다운로드합니다.
  4. npm update를 실행하여 종속 항목을 업데이트합니다.
  5. npm run start를 실행하여 webpack을 시작합니다.

이 Codelab의 나머지 부분에서는 이제 webpack이 소스 코드를 지속적으로 다시 빌드합니다.

앱에 Firebase 구성 추가

또한 사용할 Firebase 프로젝트를 Firebase SDK에서 알 수 있도록 앱에 Firebase 구성을 추가해야 합니다.

이 Codelab에서는 Firebase 구성을 가져오는 두 가지 옵션이 있습니다.

  • 옵션 1: Firebase Console에서 Firebase 구성을 가져옵니다.
  • 옵션 2: Terraform을 통해 Firebase 구성을 가져옵니다.

옵션 1: Firebase Console에서 구성을 가져와 코드베이스에 추가

  1. Firebase Console에서 프로젝트 설정으로 이동합니다.
  2. 내 앱 카드까지 아래로 스크롤한 다음 웹 앱을 선택합니다.
  3. Firebase SDK 스니펫 창에서 구성을 선택한 다음 구성 스니펫을 복사합니다.
  4. 다음과 같이 앱의 web/src/firebase-config.js 파일에 구성을 붙여넣습니다.

    firebase-config.js
    ...
    
    const config = {
      apiKey: "<API_KEY>",
      authDomain: "<PROJECT_ID>.firebaseapp.com",
      projectId: "<PROJECT_ID>",
      storageBucket: "<PROJECT_ID>.appspot.com",
      messagingSenderId: "<SENDER_ID>",
      appId: "<APP_ID>",
      measurementId: "<G-MEASUREMENT_ID>",
    };
    
    ...
    

옵션 2: Terraform을 통해 구성을 가져와 코드베이스에 추가

또는 Terraform을 통해 Firebase 구성을 CLI의 출력 값으로 가져올 수 있습니다.

  1. main.tf 파일에서 google_firebase_web_app 리소스 블록 (프로젝트에 웹 앱을 등록한 블록)을 찾습니다.
  2. 이 블록 바로 뒤에 다음 블록을 추가합니다.

    main.tf
    ...
    
    data "google_firebase_web_app_config" "default" {
      provider     = google-beta
      project      = google_firebase_project.default.project
      web_app_id   = google_firebase_web_app.default.app_id
    }
    
    output "friendlychat_web_app_config" {
      value = {
        projectId         = google_firebase_project.default.project
        appId             = google_firebase_web_app.default.app_id
        apiKey            = data.google_firebase_web_app_config.default.api_key
        authDomain        = data.google_firebase_web_app_config.default.auth_domain
        storageBucket     = lookup(data.google_firebase_web_app_config.default, "storage_bucket", "")
        messagingSenderId = lookup(data.google_firebase_web_app_config.default, "messaging_sender_id", "")
        measurementId     = lookup(data.google_firebase_web_app_config.default, "measurement_id", "")
      }
    }
    
    ...
    
  3. data 블록과 output 블록은 어떤 방식으로든 인프라를 수정하기 위한 것이 아니므로 다음 명령어만 실행하면 됩니다.
    1. 웹 앱의 Firebase 구성을 디렉터리의 Terraform 상태로 로드하려면 다음 명령어를 실행합니다.
      terraform refresh
      
    2. Firebase 구성 값을 출력하려면 다음 명령어를 실행하세요.
      terraform output –json
      
      다음은 구성의 출력 예시입니다. 출력된 출력에는 프로젝트와 앱의 값이 포함됩니다.
      {
        "friendlychat_web_app_config": {
          "sensitive": false,
          "type": [
            "object",
            {
              "apiKey": "string",
              "appId": "string",
              "authDomain": "string",
              "measurementId": "string",
              "messagingSenderId": "string",
              "projectId": "string",
              "storageBucket": "string"
            }
          ],
          "value": {
            "apiKey": "<API_KEY>",
            "appId": "<APP_ID>",
            "authDomain": "<PROJECT_ID>.firebaseapp.com",
            "measurementId": "<G-MEASUREMENT_ID>",
            "messagingSenderId": "<SENDER_ID>",
            "projectId": "<PROJECT_ID>",
            "storageBucket": "<PROJECT_ID>.appspot.com"
          }
        }
      }
      
  4. value 맵 내에서 값을 복사합니다.
  5. 이 값 (구성)을 다음과 같이 앱의 web/src/firebase-config.js 파일에 붙여넣습니다.

    firebase-config.js
    ...
    
    const config = {
      apiKey: "<API_KEY>",
      appId: "<APP_ID>",
      authDomain: "<PROJECT_ID>.firebaseapp.com",
      measurementId: "<G-MEASUREMENT_ID>",
      messagingSenderId: "<SENDER_ID>",
      projectId: "<PROJECT_ID>",
      storageBucket: "<PROJECT_ID>.appspot.com",
    };
    
    ...
    

앱에서 Firebase 초기화

마지막으로 Firebase를 초기화하려면 앱의 web/src/index.js 파일에 다음을 추가합니다.

index.js

...

const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);

앱 사용해 보기

이제 Firebase에 대해 모든 것이 구성되었으므로, 제대로 작동하는 웹 앱을 사용해 볼 수 있습니다.

  1. 앱을 제공하는 브라우저를 새로고침합니다.
  2. 이제 Google에 로그인하여 채팅에 메시지를 게시할 수 있습니다. 이미지 파일이 있으면 업로드할 수도 있습니다.

11. 환경 간 구성 복제

Terraform은 유사하게 구성된 다수의 인프라 (예: 프로덕션 프로젝트와 유사한 스테이징 Firebase 프로젝트 설정)를 관리하는 데 탁월합니다.

이 Codelab에서는 스테이징 환경으로 사용할 두 번째 Firebase 프로젝트를 만듭니다.

기존 구성을 복제하여 스테이징 프로젝트를 만드는 방법에는 두 가지가 있습니다.

  • 옵션 1: Terraform 구성의 사본을 만듭니다.
    이 옵션을 사용하면 복제된 프로젝트가 소스 프로젝트와 얼마나 차이가 나는지를 가장 유연하게 관리할 수 있습니다.
  • 옵션 2: for_each로 구성을 재사용합니다.
    이 옵션은 각 프로젝트가 큰 차이가 없어야 하고 변경사항을 모든 프로젝트에 한 번에 전파하려는 경우 더 많은 코드 재사용을 제공합니다.

옵션 1: Terraform 구성 사본 만들기

이 옵션은 복제된 프로젝트가 소스 프로젝트와 다른 정도(예: 다양한 표시 이름 및 단계적 출시의 앱 포함)에 대한 유연성을 제공합니다.

  1. web 디렉터리의 루트에서 main_staging.tf라는 새 Terraform 구성 파일을 만듭니다.
  2. main.tf 파일에서 모든 리소스 블록 (terraformprovider 블록 제외)을 복사하여 main_staging.tf 파일에 붙여넣습니다.
  3. 그런 다음 스테이징 프로젝트에서 작업할 수 있도록 main_staging.tf에서 복제된 각 리소스 블록을 수정해야 합니다.
    • 리소스 라벨: 충돌을 방지하기 위해 새 이름을 사용합니다. 예를 들어 resource "google_project" "default"resource "google_project" "staging"로 바꿉니다.
    • 리소스 참조: 각 리소스를 업데이트합니다. 예를 들어 google_firebase_project.default.projectgoogle_firebase_project.staging.project로 업데이트합니다.
    main_staging.tf 파일의 전체 구성은 이 Codelab의 GitHub 저장소에서 확인할 수 있습니다.

    web/terraform-checkpoints/replicate-config/main_staging-copypaste.tf

    이 구성을 사용하려면 다음을 실행해야 합니다.
    1. main_staging-copypaste.tf에서 구성을 복사하여 main_staging.tf 파일에 붙여넣습니다.
    2. main_staging.tf 파일에서 다음을 수행합니다.
      • google_project 리소스 블록에서 name 속성과 project-id 속성을 업데이트하고 Terraform을 통해 인증을 설정한 경우 billing_account 속성을 자체 값으로 업데이트합니다.
      • google_firebase_web_app 리소스 블록에서 display_name 속성을 자체 값으로 업데이트합니다.
      • google_firestore_databasegoogle_app_engine_application 리소스 블록에서 location_id 속성을 자체 값으로 업데이트합니다.
    main_staging.tf
    # Create a new Google Cloud project.
    resource "google_project" "staging" {
      provider = google-beta.no_user_project_override
    
      name            = "<PROJECT_NAME_OF_STAGING_PROJECT>"
      project_id      = "<PROJECT_ID_OF_STAGING_PROJECT"
      # Required if you want to set up Authentication via Terraform
      billing_account = "<YOUR_BILLING_ACCOUNT_ID>"
    
      # Required for the project to display in any list of Firebase projects.
      labels = {
        "firebase" = "enabled"
      }
    }
    
    # Enable the required underlying Service Usage API.
    resource "google_project_service" "staging_serviceusage" {
      provider = google-beta.no_user_project_override
    
      project = google_project.staging.project_id
      service = "serviceusage.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable the required underlying Firebase Management API.
    resource "google_project_service" "staging_firebase" {
      provider = google-beta.no_user_project_override
    
      project = google_project.staging.project_id
      service = "firebase.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable Firebase services for the new project created above.
    resource "google_firebase_project" "staging" {
      provider = google-beta
    
      project = google_project.staging.project_id
    
      # Wait until the required APIs are enabled.
      depends_on = [
        google_project_service.staging_serviceusage,
        google_project_service.staging_firebase,
      ]
    }
    
    # Create a Firebase Web App in the new project created above.
    resource "google_firebase_web_app" "staging" {
      provider = google-beta
    
      project      = google_firebase_project.staging.project
      display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>"
      deletion_policy = "DELETE"
    }
    
  4. terraform apply를 실행하여 새로운 '스테이징' Firebase 프로젝트와 모든 리소스를 프로비저닝하고 서비스를 사용 설정합니다.
  5. 이전과 같이 Firebase Console에서 항목을 확인하여 모든 항목이 예상대로 프로비저닝되고 사용 설정되었는지 확인합니다.

옵션 2: for_each로 구성 재사용

이 옵션은 각 프로젝트가 큰 차이가 없어야 하고 변경사항을 모든 프로젝트에 한 번에 전파하려는 경우 더 많은 코드 재사용을 제공합니다. Terraform 언어의 for_each 메타 인수를 사용합니다.

  1. main.tf 파일을 엽니다.
  2. 복제할 각 리소스 블록에 다음과 같이 for_each 메타 인수를 추가합니다.

    main.tf
    # Create new Google Cloud projects.
    resource "google_project" "default" {
      provider        = google-beta.no_user_project_override
      name            = each.value
      # Create a unique project ID for each project, with each ID starting with <PROJECT_ID>.
      project_id      = "<PROJECT_ID>-${each.key}"
      # Required if you want to set up Authentication via Terraform
      billing_account = "<YOUR_BILLING_ACCOUNT_ID>"
    
      # Required for the projects to display in any list of Firebase projects.
      labels = {
        "firebase" = "enabled"
      }
    
      for_each = {
        prod    = "<PROJECT_NAME_OF_PROD_PROJECT>"
        staging = "<PROJECT_NAME_OF_STAGING_PROJECT>"
      }
    }
    
    # Enable the required underlying Service Usage API.
    resource "google_project_service" "serviceusage" {
      provider = google-beta.no_user_project_override
      for_each = google_project.default
    
      project = each.value.project_id
      service = "serviceusage.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable the required underlying Firebase Management API.
    resource "google_project_service" "firebase" {
      provider = google-beta.no_user_project_override
      for_each = google_project.default
    
      project = each.value.project_id
      service = "firebase.googleapis.com"
    
      # Don't disable the service if the resource block is removed by accident.
      disable_on_destroy = false
    }
    
    # Enable Firebase services for each of the new projects created above.
    resource "google_firebase_project" "default" {
      provider = google-beta
      for_each = google_project.default
    
      project = each.value.project_id
    
      depends_on = [
        google_project_service.serviceusage,
        google_project_service.firebase,
      ]
    }
    
    # Create a Firebase Web App in each of the new projects created above.
    resource "google_firebase_web_app" "default" {
      provider = google-beta
      for_each = google_firebase_project.default
    
      project      = each.value.project
      # The Firebase Web App created in each project will have the same display name.
      display_name = "<DISPLAY_NAME_OF_YOUR_WEB_APP>"
      deletion_policy = "DELETE"
    }
    
    
    # NOTE: For this codelab, we recommend setting up Firebase Authentication
    # using the Firebase console. However, if you set up Firebase Authentication
    # using Terraform, copy-paste from your main.tf the applicable blocks.
    # Make sure to add the `for_each` meta-argument into each block.
    
    
    # Copy-paste from your main.tf file the applicable resource blocks
    # for setting up Cloud Firestore (including rules) and
    # for setting up Cloud Storage for Firebase (including rules).
    # Make sure to add the `for_each` meta-argument into each block.
    
    이 Codelab의 GitHub 저장소에서 for_each 메타 인수를 사용하는 main.tf 파일의 전체 구성을 확인할 수 있습니다.

    web/terraform-checkpoints/replicate-config/main-foreach.tf

    이 구성을 사용하려면 다음을 실행해야 합니다.
    1. main-foreach.tf에서 구성을 복사하여 main.tf 파일에 붙여넣습니다.
    2. main.tf 파일에서 다음을 수행합니다.
      • google_project 리소스 블록에서 name 속성과 project-id 속성을 업데이트하고 Terraform을 통해 인증을 설정한 경우 billing_account 속성을 자체 값으로 업데이트합니다.
      • google_firebase_web_app 리소스 블록에서 display_name 속성을 자체 값으로 업데이트합니다.
      • google_firestore_databasegoogle_app_engine_application 리소스 블록에서 location_id 속성을 자체 값으로 업데이트합니다.
  3. 이 구성을 바로 적용하기보다는 Terraform이 이 구성을 기존 인프라와 비교하여 어떻게 해석하는지 파악하고 수정하는 것이 중요합니다.
    1. 현재 for_each를 사용하는 이 구성을 적용한 경우 리소스 주소는 다음과 같습니다.
      google_project.default["prod"]
      google_project.default["staging"]
      google_firebase_project.default["prod"]
      google_firebase_project.default["staging"]
      google_firebase_web_app.default["prod"]
      google_firebase_web_app.default["staging"]
      
      하지만 이 Codelab의 첫 번째 부분에서 만든 기존 프로젝트는 Terraform에 다음과 같이 알려져 있습니다.
      google_project.default
      google_firebase_project.default
      google_firebase_android_app.default
      
    2. terraform plan를 실행하여 현재 상태를 고려하여 Terraform이 취할 수 있는 작업을 확인합니다.

      출력에 Terraform이 이 Codelab의 첫 번째 부분에서 만든 프로젝트를 삭제하고 새 프로젝트 2개를 만든다고 표시되어야 합니다. 이는 Terraform에서 google_project.default 주소의 프로젝트가 새 주소(google_project.default["prod"])로 이동되었음을 알지 못하기 때문입니다.
    3. 이 문제를 해결하려면 terraform state mv 명령어를 실행합니다.
      terraform state mv "google_project.default" "google_project.default[\"prod\"]"
      
    4. 마찬가지로 다른 모든 리소스 블록을 수정하려면 main.tf 파일의 google_firebase_project, google_firebase_web_app, 기타 모든 리소스 블록에 terraform state mv를 실행합니다.
    5. 이제 terraform plan를 다시 실행해도 Terraform이 이 Codelab의 첫 번째 부분에서 만든 프로젝트를 삭제한다고 표시되면 안 됩니다.
  4. terraform apply를 실행하여 새로운 '스테이징' Firebase 프로젝트와 모든 리소스를 프로비저닝하고 서비스를 사용 설정합니다.
  5. 이전과 같이 Firebase Console에서 항목을 확인하여 모든 항목이 예상대로 프로비저닝되고 사용 설정되었는지 확인합니다.

12. 보너스 단계: 스테이징 앱 및 프로덕션 앱 배포

  1. 앱의 코드베이스에서 firebase-config.js를 변경하여 스테이징 프로젝트의 Firebase 구성을 대신 사용합니다.

    Firebase 구성을 가져와 앱에 추가하는 방법을 알아보려면 이 Codelab의 이전 단계인 앱에 Firebase 구성 추가를 참조하세요.
  2. web 디렉터리의 루트에서 다음 명령어를 실행하여 스테이징 Firebase 프로젝트에 앱을 배포합니다.
    firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
    
  3. firebase deploy의 출력에 출력된 URL을 통해 브라우저에서 스테이징 앱을 엽니다. 로그인하고 메시지를 보내고 이미지를 업로드해 보세요.

    앱을 Firebase 프로젝트에 배포하면 에뮬레이션된 리소스가 아닌 실제 Firebase 리소스를 사용합니다. 스테이징 앱과 상호작용할 때 Firebase Console의 스테이징 프로젝트에 데이터와 이미지가 표시됩니다.
  4. 스테이징 상태에서 앱을 테스트한 후 firebase-config.js를 다시 프로덕션 프로젝트의 Firebase 구성 (이 Codelab에서 만든 첫 번째 프로젝트)을 사용하도록 변경합니다.
  5. web 디렉터리의 루트에서 다음 명령어를 실행하여 프로덕션 Firebase 프로젝트에 앱을 배포합니다.
    firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
    
  6. firebase deploy의 출력에 인쇄된 URL을 통해 브라우저에서 프로덕션 앱을 엽니다. 로그인하고 메시지를 보내고 이미지를 업로드해 보세요.

    Firebase Console의 프로덕션 프로젝트에 데이터와 이미지가 표시됩니다.
  7. 이 Codelab에서 두 앱과의 상호작용을 마쳤으면 Firebase에서 이를 제공하지 않도록 할 수 있습니다. 프로젝트마다 다음 명령어를 실행합니다.
    firebase hosting:disable --project=<STAGING_PROJECT_ID>
    
    firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
    

13. 수고하셨습니다.

Terraform을 사용하여 실시간 채팅 웹 애플리케이션을 구성했습니다. 스테이징과 프로덕션을 위한 별도의 Firebase 프로젝트를 만들어 개발 환경을 위한 권장사항을 따랐습니다.

학습한 내용

  • Terraform CLI를 사용하여 클라우드 리소스 관리
  • Terraform을 사용하여 Firebase 제품 구성 (인증, Firestore, Cloud Storage, 보안 규칙)
  • Firebase 로컬 에뮬레이터 도구 모음을 사용하여 로컬에서 웹 앱 실행 및 테스트
  • 웹 앱에 Firebase 가져오기
  • Terraform을 사용하여 여러 환경에서 구성 복제

Firebase 및 Terraform에 관한 자세한 내용은 문서를 참조하세요. Terraform을 지원하는 모든 Firebase 제품 목록, 일반적인 사용 사례를 위한 샘플 Terraform 구성, 유용한 문제 해결 및 FAQ를 확인할 수 있습니다.