Configure e gerencie projetos e produtos do Firebase via Terraform

1. Introdução

Metas

Você pode usar o Terraform para configurar e gerenciar um projeto do Firebase, incluindo a configuração programática de infraestrutura e produtos do Firebase.

Este codelab descreve primeiro como criar um arquivo de configuração do Terraform para criar um novo projeto do Firebase, seguido de como configurar os aplicativos e produtos do Firebase que você quer usar nesse projeto. Também abordamos os fundamentos da linha de comando do Terraform, como visualizar as alterações a serem feitas e depois implementá-las.

Se você quer aprender como configurar e gerenciar projetos e produtos do Firebase com o Terraform, este codelab é para você!

O que você aprenderá

  • Como criar um arquivo de configuração do Terraform ( *.tf )
  • Como usar comandos Terraform CLI para gerenciar sua infraestrutura
  • Como modificar sua configuração para atualizar seus recursos e serviços
  • Como aplicar sua configuração em um aplicativo web real (chamado Friendly Chat )
  • Como definir configurações paralelas (e sincronizadas) em diferentes ambientes (produção, teste, etc.)

O que você precisará

Para ter sucesso neste codelab, você precisa ter proficiência básica com Terraform e sua terminologia, incluindo os seguintes pré-requisitos:

Este codelab fornece um aplicativo de exemplo real para que você possa testar e interagir com o que provisiona por meio do Terraform. Para fazer isso, você precisará do seguinte:

  • O exemplo de código de um app da Web. Faça download desse código na próxima etapa do codelab
  • O gerenciador de pacotes npm (que normalmente vem com Node.js ) – instale essas ferramentas
  • A CLI do Firebase : instale esta CLI e faça login

2. Obtenha o código inicial

Neste codelab, você pode testar o que provisiona por meio do Terraform com um app da Web real. Recomendamos fazer isso para que você entenda todas as etapas necessárias para usar os recursos provisionados pelo Terraform.

Clone o repositório GitHub do codelab na linha de comando:

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

Alternativamente, se você não tiver o git instalado, poderá baixar o repositório como um arquivo ZIP .

3. Crie uma configuração do Terraform

Configuração do Terraform

  1. Na base de código do aplicativo de amostra baixado, navegue até a raiz do diretório web .
  2. Na raiz desse diretório, crie um arquivo de configuração do Terraform chamado main.tf com a seguinte configuração inicial:

    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
    }
    

Cada um dos provedores google-beta tem um atributo chamado user_project_override que determina como as operações do Terraform serão verificadas por cota. Para provisionar a maioria dos recursos, você deve usar user_project_override = true , o que significa verificar a cota em seu próprio projeto do Firebase. No entanto, para configurar seu novo projeto para que ele possa aceitar verificações de cota, primeiro você precisa usar user_project_override=false . A sintaxe alias do Terraform permite distinguir entre as duas configurações de provedor nas próximas etapas deste codelab.

Inicialize o Terraform no diretório

A criação de uma nova configuração pela primeira vez requer o download do provedor especificado na configuração.

Para fazer esta inicialização, execute o seguinte comando na raiz do mesmo diretório do arquivo de configuração main.tf :

terraform init

4. Crie um projeto Firebase via Terraform

Para “criar um projeto Firebase”, é importante lembrar que cada projeto Firebase é na verdade um projeto Google Cloud, apenas com os serviços Firebase habilitados para ele.

Adicionar blocos para o projeto e APIs subjacentes do Google Cloud

  1. Primeiro, provisione o projeto subjacente do Google Cloud.

    Ao seu arquivo de configuração main.tf , adicione o seguinte bloco de recursos.

    Você precisa especificar o nome do seu próprio projeto (como "Terraform FriendlyChat Codelab" ) e seu próprio ID do projeto (como "terraform-codelab-your-initials" ). Observe que o valor name é usado apenas nas interfaces do Firebase e não é visível para os usuários finais. O valor project_id , entretanto, identifica seu projeto exclusivamente para o Google, portanto, certifique-se de especificar um valor exclusivo. 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. Em seguida, você precisa ativar as APIs subjacentes necessárias: a API Service Usage e a API Firebase Management.

    Essa ativação de API geralmente é tratada nos bastidores quando você usa o console do Firebase para criar um projeto do Firebase, mas o Terraform precisa ser informado explicitamente para fazer essa ativação.

    Ao arquivo de configuração main.tf (logo abaixo do bloco que cria o novo projeto Cloud), adicione o seguinte bloco de recursos:

    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
    }
    
    Ao ativar a API Service Usage, seu novo projeto poderá aceitar verificações de cota! Portanto, para todo o provisionamento de recursos e habilitação de serviços subsequentes, você deve usar o provedor com user_project_override (sem necessidade de alias).

Adicione um bloco para ativar os serviços do Firebase

A última coisa necessária para "criar um projeto Firebase" é ativar os serviços Firebase no projeto.

Continuando em seu arquivo de configuração main.tf , adicione o seguinte bloco de recursos.

Conforme mencionado acima, observe que este bloco de recursos está usando o provedor com user_project_override (não é necessário alias).

principal.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,
  ]
}

No bloco de recursos acima, você pode notar a cláusula depends_on , que diz ao Terraform para aguardar a ativação das APIs subjacentes. Sem esta cláusula, o Terraform não sabe da dependência e pode incorrer em erros ao provisionar recursos em paralelo.

Aplicar a configuração

  1. Para provisionar os novos recursos e ativar as APIs especificadas em seu arquivo de configuração, execute o seguinte comando na raiz do mesmo diretório do arquivo main.tf (que deve ser web ):
    terraform apply
    
  2. No terminal, o Terraform imprime um plano de ações que irá executar.

    Se tudo estiver conforme o esperado, aprove as ações digitando 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 # <----
    

Observe que se você precisar apenas visualizar as alterações sem aplicá-las, poderá usar o comando terraform plan .

Valide as alterações

Depois que o Terraform terminar a execução, você poderá inspecionar o estado de todos os recursos provisionados e serviços habilitados do Terraform executando o seguinte comando:

terraform show

Aqui está um exemplo do que você deve ver impresso. Seu estado conterá valores específicos para seu projeto.

# 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"
}

Como alternativa, você pode verificar se o projeto foi criado visualizando-o no console do Firebase .

The Terraform FriendlyChat Codelab project selected on the Firebase console

5. Registre seu aplicativo Firebase via Terraform

Para usar o Firebase, você precisa registrar cada variante de plataforma do seu aplicativo no seu projeto do Firebase. Neste codelab, você usará um aplicativo real para testar e interagir com o que você provisiona por meio do Terraform. Este aplicativo é um aplicativo da web, então você precisa informar ao Terraform para registrar um Firebase Web App em seu projeto Firebase recém-criado.

Adicione um bloco para registrar o aplicativo da web

Para registrar seu aplicativo da web em seu projeto do Firebase, anexe seu arquivo main.tf ao seguinte bloco de recursos.

Você precisa especificar seu próprio display_name para seu aplicativo da web. Observe que esse nome é usado apenas nas interfaces do Firebase e não é visível para os usuários finais.

principal.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"
}

Aplicar a configuração

  1. Para provisionar o novo recurso, execute o seguinte comando na raiz do mesmo diretório do arquivo main.tf (que deve ser web ).
    terraform apply
    
    Observe que este comando não recriará um novo projeto do Google Cloud. O Terraform detectará que já existe um projeto com o ID de projeto especificado e comparará o estado atual do projeto com o que está no arquivo .tf e fará as alterações que encontrar.
  2. Revise o plano de ações impresso. Se tudo estiver conforme o esperado, digite yes e pressione Enter para aprovar as ações.

Valide as alterações

Você pode inspecionar o estado do recurso recém-provisionado executando o seguinte comando:

terraform show

Como alternativa, você pode verificar se o aplicativo foi registrado com sucesso no seu projeto visualizando-o no console do Firebase. Vá para Configurações do projeto e role para baixo até a seção Seus aplicativos .

6. Configure a autenticação Firebase

A autenticação é uma parte importante de qualquer aplicativo. Para permitir que os usuários finais façam login em seu aplicativo da web com suas contas do Google, você pode ativar o Firebase Authentication e configurar o método de login com o Google.

Observe que neste codelab oferecemos duas opções diferentes para configurar o Firebase Authentication:

  • Opção 1 (recomendada) : configure o Firebase Authentication no console, que não requer GCIP.
    • Usar esta opção significa que você não precisa associar seu novo projeto a uma conta do Cloud Billing.
  • Opção 2 : configurar o Firebase Authentication via Terraform usando APIs do Google Cloud Identity Platform (GCIP).
    • Usar esta opção significa que você precisa associar seu novo projeto a uma conta Cloud Billing, pois o GCIP exige que o projeto esteja no plano de preços Blaze.

Opção 1: configurar a autenticação usando o console do Firebase

Para configurar o Firebase Authentication usando o Firebase console, seu projeto não precisa estar no plano de preços Blaze.

Veja como configurar o Firebase Authentication e fazer login com o Google:

  1. No console do Firebase , localize a seção Build no painel esquerdo.
  2. Clique em Autenticação , clique em Começar e, em seguida, clique na guia Método de login (ou clique aqui para ir diretamente para lá).
  3. Clique em Adicionar novo provedor e, na seção Provedores adicionais , selecione Google .
  4. Ative o botão Ativar .
  5. Defina o nome público do seu aplicativo como algo como FriendlyChat (não precisa ser globalmente exclusivo).
  6. Escolha um e-mail de suporte do projeto no menu suspenso e clique em Salvar . Configuring Firebase Auth on the Firebase console
  7. Você deverá ver o Google como um provedor de login habilitado. Firebase console Authentication page: Google sign-in enabled

Opção 2: configurar a autenticação via Terraform usando APIs Google Cloud Identity Platform (GCIP)

Para configurar o Firebase Authentication via Terraform, você deve usar APIs GCIP, o que significa que o projeto deve estar no plano de preços Blaze. Você atualiza seu projeto do Firebase para usar o plano Blaze associando uma conta do Cloud Billing ao projeto.

Habilite o faturamento via Terraform

  1. Se você ainda não tem uma conta do Cloud Billing, a primeira etapa é criar uma nova conta no Console do Google Cloud . Ao fazer isso, anote o ID da conta de faturamento . O ID da conta de faturamento pode ser localizado na página Faturamento no ID da conta de faturamento associado ao seu projeto. Enabling a billing account using the Google Cloud console
  2. Para ativar o faturamento em seu projeto via Terraform, adicione um atributo billing_account ao recurso google_project existente em seu arquivo main.tf :

    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"
      }
    }
    
    ...
    

Ative o Firebase Authentication e faça login no Google via Terraform

  1. Para provisionar o Firebase Authentication com GCIP, anexe ao arquivo main.tf os seguintes blocos de recursos:

    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. A ativação do login com o Google exige que você tenha um cliente OAuth . Vá para a seção APIs e serviços do Console do Google Cloud para fazer esta configuração.
  3. Como esta é a primeira vez que você cria um ID de cliente para este projeto, você precisa configurar sua tela de consentimento do OAuth.
    1. Abra a página da tela de consentimento do OAuth e selecione o projeto que você acabou de criar.
    2. Defina o Tipo de usuário como Externo e clique em Criar .
    3. Na próxima tela, conclua o seguinte e clique em Salvar e continuar .
      • Defina o nome do aplicativo público do seu aplicativo como algo como FriendlyChat (isso não precisa ser globalmente exclusivo).
      • Escolha um e-mail de suporte ao usuário no menu suspenso.
      • Insira um e-mail para as informações de contato do desenvolvedor .
    4. Nas próximas telas, complete o seguinte:
      • Aceite os padrões na página Escopos e clique em Salvar e continuar .
      • Aceite os padrões na página Testar usuários e clique em Salvar e continuar .
      • Revise o resumo e clique em Voltar ao painel .
      Configuring an OAuth2 client using the Google Cloud console
  4. Configure um cliente OAuth na página Credenciais fazendo o seguinte:
    1. Clique em Criar credenciais e selecione ID do cliente OAuth .
    2. Na lista suspensa Tipo de aplicativo , selecione Aplicativo da Web .
    3. No campo Nome , insira o nome do seu aplicativo, por exemplo FriendlyChat (não precisa ser globalmente exclusivo).
    4. Permita que o URL do seu aplicativo use esse cliente OAuth definindo o seguinte:
      • Em Origens JavaScript autorizadas , clique em Adicionar URI e digite
        https://<PROJECT_ID>.firebaseapp.com , onde <PROJECT_ID> é o ID do projeto que você definiu em main.tf .
      • Em URIs de redirecionamento autorizados , clique em Adicionar URI e digite
        https://<PROJECT_ID>.firebaseapp.com/__/auth/handler , onde <PROJECT_ID> é o ID do projeto que você definiu em main.tf .
    5. Clique em Salvar .
    Obtaining the OAuth2 Client ID and secret from the Google Cloud console Credentials page
  5. Para ativar o login com o Google usando seu ID de cliente OAuth e segredo do cliente, anexe o seguinte bloco ao seu arquivo 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
      ]
    }
    

Aplicar a configuração

  1. Para configurar a autenticação de acordo com sua configuração, execute os seguintes comandos na raiz do mesmo diretório do seu arquivo main.tf (que deve ser web ):
    export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
    
    terraform apply
    
    Observe que a execução terraform apply não recriará um novo projeto do Google Cloud. O Terraform detectará que já existe um projeto com o ID de projeto especificado e comparará o estado atual do projeto com o que está no arquivo .tf . Em seguida, ele fará todas as alterações que encontrar.
  2. Revise o plano de ações impresso. Se tudo estiver conforme o esperado, digite yes e pressione Enter para aprovar as ações.

Valide as alterações

  1. No console do Firebase , localize a seção Build no painel esquerdo.
  2. Clique em Autenticação e, em seguida, clique na guia Método de login (ou clique aqui para ir diretamente para lá).
  3. Você deverá ver o Google como um provedor de login habilitado. Firebase console Authentication page: Google sign-in enabled

7. Configure um banco de dados Firestore e suas regras de segurança

No app da Web deste codelab, você armazenará mensagens entre usuários finais em um banco de dados do Firestore.

  1. Para ativar as APIs necessárias e provisionar a instância do banco de dados, anexe ao arquivo main.tf os seguintes blocos de recursos:

    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. Altere <NAME_OF_DESIRED_REGION> para a região onde deseja que o banco de dados resida.

    Ao desenvolver um aplicativo de produção, você deseja que ele esteja em uma região próxima à maioria dos usuários e em comum com outros serviços do Firebase, como o Cloud Functions. Para este codelab, você pode usar us-east1 (Carolina do Sul) ou a região mais próxima de você (consulte Locais do Cloud Firestore ).
  3. Cada instância de banco de dados do Firestore acessível ao Firebase deve ser protegida pelas regras de segurança do Firebase .

    O código de amostra deste codelab fornece um conjunto de regras seguras do Firestore no arquivo firestore.rules , que você pode encontrar na raiz do diretório web .
  4. Anexe seu arquivo main.tf com os seguintes blocos de recursos para fazer o seguinte:
    • Crie um conjunto de regras de segurança do Firebase a partir do arquivo firestore.rules local.
    • Libere o conjunto de regras para a instância do Firestore.
    Observe que esses blocos de recursos realizam o equivalente a clicar no botão Publicar no console do Firebase ou executar 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. Execute terraform apply para provisionar o banco de dados do Firestore e implantar suas regras de segurança.
  6. Verifique se o banco de dados está provisionado e se suas regras de segurança estão implementadas:
    1. No console do Firebase , localize a seção Build no painel esquerdo.
    2. Vá para a seção Banco de dados do Firestore e clique na guia Regras .
    Verifying Cloud Firestore rules using the Firebase console

8. Configure um bucket do Cloud Storage e suas regras de segurança

No app da Web deste codelab, você armazenará imagens compartilhadas entre usuários finais em um bucket do Cloud Storage.

  1. Para ativar as APIs necessárias e provisionar o intervalo padrão do Cloud Storage, anexe ao arquivo main.tf os seguintes blocos de recursos.

    Observe que o intervalo padrão do Cloud Storage para seu projeto é provisionado por meio do Google App Engine e deve ter o mesmo local do banco de dados do Firestore. Consulte Locais do App Engine para obter mais informações.

    Se você quiser vários buckets no seu projeto, provisione-os usando o recurso google_storage_bucket (não mostrado neste 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. Cada bucket do Cloud Storage acessível ao Firebase deve ser protegido pelas regras de segurança do Firebase .

    O código de amostra deste codelab fornece um conjunto de regras seguras do Firestore no arquivo storage.rules , que você pode encontrar na raiz do diretório web .
  3. Anexe seu arquivo main.tf com os seguintes blocos de recursos para fazer o seguinte:
    • Crie um conjunto de regras de segurança do Firebase a partir do arquivo local.
    • Libere o conjunto de regras para o bucket do Storage.
    Observe que esses blocos de recursos realizam o equivalente a clicar no botão Publicar no console do Firebase ou executar 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. Execute terraform apply para provisionar o bucket padrão do Cloud Storage e implantar suas regras de segurança.
  5. Verifique se o bucket está provisionado e se suas regras de segurança estão implantadas:
    1. No console do Firebase , localize a seção Build no painel esquerdo.
    2. Vá para a seção Armazenamento e clique na guia Regras .
    Verifying security rules using the Firebase console

9. Execute seu aplicativo localmente

Agora você está pronto para executar seu aplicativo web pela primeira vez! Você usará o emulador do Firebase Hosting para veicular seu aplicativo localmente.

  1. Abra uma nova janela de terminal e, no diretório web , execute o seguinte comando Firebase CLI para iniciar o emulador:
    firebase emulators:start --project=<PROJECT_ID>
    
  2. No navegador, abra seu aplicativo Web na URL local retornada pela CLI (geralmente http://localhost:5000 ).

Você deverá ver a interface do usuário do seu aplicativo FriendlyChat, que (ainda!) não está funcionando. O app ainda não está conectado ao Firebase, mas ao concluir as próximas etapas deste codelab, ele estará.

Observe que sempre que você fizer alterações no seu aplicativo da Web (como você fará nas etapas a seguir deste codelab), atualize o navegador para atualizar o URL local com essas alterações.

10. Instale, configure e inicialize o Firebase

Para que um aplicativo funcione com o Firebase, ele precisa do SDK do Firebase e da configuração do Firebase para seu projeto do Firebase.

O código de amostra deste codelab já é um app funcional com todas as dependências e funções necessárias para usar vários produtos do Firebase no app. Você pode consultar web/package.json e web/src/index.js se quiser ver o que já foi feito.

Mesmo que o código de exemplo esteja quase completo, você ainda precisa fazer algumas coisas para colocar seu aplicativo em execução, incluindo: instalar o SDK do Firebase, iniciar sua compilação, adicionar a configuração do Firebase ao seu aplicativo e, finalmente, inicializar o Firebase.

Instale o SDK do Firebase e inicie a construção do seu webpack

Você precisa executar alguns comandos para iniciar a construção do seu aplicativo.

  1. Abra uma nova janela de terminal.
  2. Certifique-se de estar na raiz do diretório web .
  3. Execute npm install para baixar o SDK do Firebase.
  4. Execute npm update para atualizar quaisquer dependências.
  5. Execute npm run start para iniciar o webpack.

No restante do codelab, o webpack reconstruirá continuamente seu código-fonte.

Adicione a configuração do Firebase ao seu aplicativo

Você também precisa adicionar a configuração do Firebase ao seu aplicativo para que os SDKs do Firebase saibam qual projeto do Firebase você deseja que eles usem.

Neste codelab, você tem duas opções diferentes para obter a configuração do Firebase:

  • Opção 1 : obtenha sua configuração do Firebase no console do Firebase.
  • Opção 2 : Obtenha sua configuração do Firebase via Terraform.

Opção 1: obtenha a configuração do console do Firebase e adicione-a à sua base de código

  1. No console do Firebase, acesse as configurações do projeto .
  2. Role para baixo até o cartão Seus aplicativos e selecione seu aplicativo Web.
  3. Selecione Config no painel de snippet do SDK do Firebase e copie o snippet de configuração.
  4. Cole sua configuração no arquivo web/src/firebase-config.js do seu aplicativo, assim:

    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>",
    };
    
    ...
    

Opção 2: Obtenha a configuração via Terraform e adicione-a à sua base de código

Como alternativa, você pode obter a configuração do Firebase por meio do Terraform como um valor de saída na CLI.

  1. No arquivo main.tf , encontre o bloco de recursos google_firebase_web_app (o bloco que registrou um aplicativo da web em seu projeto).
  2. Imediatamente após esse bloco, adicione os seguintes blocos:

    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. Como o bloco data e o bloco output não se destinam de forma alguma a modificar a infraestrutura, você só precisa executar os comandos a seguir.
    1. Para carregar a configuração do Firebase do seu aplicativo da web no estado Terraform do seu diretório, execute este comando:
      terraform refresh
      
    2. Para imprimir os valores de configuração do Firebase, execute este comando:
      terraform output –json
      
      A seguir está um exemplo de saída de uma configuração. Sua saída impressa conterá os valores do seu projeto e do aplicativo.
      {
        "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. Copie os valores do mapa value .
  5. Cole esses valores (sua configuração) no arquivo web/src/firebase-config.js do seu aplicativo, assim:

    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",
    };
    
    ...
    

Inicialize o Firebase no seu aplicativo

Por fim, para inicializar o Firebase, anexe o arquivo web/src/index.js do seu aplicativo com o seguinte:

index.js

...

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

Experimente seu aplicativo

Agora que tudo está configurado para o Firebase, você pode testar seu aplicativo Web funcional.

  1. Atualize o navegador que atende seu aplicativo.
  2. Agora você deve conseguir fazer login no Google e começar a postar mensagens no bate-papo. Se você tiver arquivos de imagem, poderá até carregá-los!

11. Replique sua configuração entre ambientes

O Terraform é excelente no gerenciamento de várias infraestruturas configuradas de forma semelhante (por exemplo, configurar um projeto de teste do Firebase semelhante a um projeto de produção).

Neste codelab, você criará um segundo projeto do Firebase para ser um ambiente de teste.

Para replicar uma configuração existente para criar este projeto temporário, você tem duas opções:

  • Opção 1 : Faça uma cópia da configuração do Terraform.
    Esta opção oferece maior flexibilidade quanto ao quanto o projeto replicado pode diferir do projeto de origem.
  • Opção 2 : Reutilizar configurações com for_each .
    Esta opção oferece mais reutilização de código se cada projeto não diferir significativamente e você desejar propagar as alterações para todos os projetos de uma só vez.

Opção 1: faça uma cópia da configuração do Terraform

Essa opção oferece maior flexibilidade em relação ao quanto o projeto replicado pode diferir do projeto de origem, como ter aplicativos com nomes de exibição e implementações graduais diferentes.

  1. Na raiz do seu diretório web , crie um novo arquivo de configuração do Terraform chamado main_staging.tf .
  2. Copie todos os blocos de recursos do arquivo main.tf (exceto os blocos terraform e provider ) e cole-os no arquivo main_staging.tf .
  3. Em seguida, você precisa modificar cada um dos seus blocos de recursos replicados em main_staging.tf para que eles funcionem com seu projeto de teste:
    • Rótulos de recursos: use um novo nome para evitar conflitos. Por exemplo, renomeie resource "google_project" "default" para resource "google_project" "staging" .
    • Referências de recursos: Atualize cada uma. Por exemplo, atualize google_firebase_project.default.project para google_firebase_project.staging.project .
    Você pode encontrar a configuração completa de um arquivo main_staging.tf no repositório GitHub deste codelab:

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

    Se você quiser usar esta configuração, certifique-se de fazer o seguinte:
    1. Copie a configuração de main_staging-copypaste.tf e cole-a em seu arquivo main_staging.tf .
    2. No seu arquivo main_staging.tf , faça o seguinte:
      • No bloco de recursos google_project , atualize o atributo name , o atributo project-id e (se você configurar a autenticação via Terraform) o atributo billing_account com seus próprios valores.
      • No bloco de recursos google_firebase_web_app , atualize o atributo display_name com seu próprio valor.
      • Nos blocos de recursos google_firestore_database e google_app_engine_application , atualize os atributos location_id com seu próprio valor.
    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. Execute terraform apply para provisionar seu novo projeto de "teste" do Firebase e todos os seus recursos e ativar seus serviços.
  5. Verifique se tudo foi provisionado e ativado conforme esperado, verificando-os no console do Firebase como antes.

Opção 2: reutilizar configurações com for_each

Esta opção oferece mais reutilização de código se cada projeto não diferir significativamente e você desejar propagar as alterações para todos os projetos de uma só vez. Ele usa o meta-argumento for_each na linguagem Terraform.

  1. Abra seu arquivo main.tf
  2. Em cada bloco de recursos que você deseja replicar, adicione um meta-argumento for_each , assim:

    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.
    
    Você pode encontrar a configuração completa de um arquivo main.tf que usa o metaargumento for_each no repositório GitHub deste codelab:

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

    Se você quiser usar esta configuração, certifique-se de fazer o seguinte:
    1. Copie a configuração de main-foreach.tf e cole-a em seu arquivo main.tf
    2. No seu arquivo main.tf , faça o seguinte:
      • No bloco de recursos google_project , atualize o atributo name , o atributo project-id e (se você configurar a autenticação via Terraform) o atributo billing_account com seus próprios valores.
      • No bloco de recursos google_firebase_web_app , atualize o atributo display_name com seu próprio valor.
      • Nos blocos de recursos google_firestore_database e google_app_engine_application , atualize os atributos location_id com seu próprio valor.
  3. Em vez de aplicar essa configuração imediatamente, é importante entender e consertar algumas coisas sobre como a Terraform interpreta essa configuração em comparação com a infraestrutura existente.
    1. No momento, se você aplicou esta configuração que usa for_each , os endereços de recursos seriam os seguintes:
      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"]
      
      , no entanto, o projeto existente que você criou na primeira parte deste codelab é conhecido por Terraform como o seguinte:
      google_project.default
      google_firebase_project.default
      google_firebase_android_app.default
      
    2. Execute terraform plan para ver quais ações a Terraform levaria, dado o estado atual.

      A saída deve mostrar que a Terraform excluiria o projeto que você criou na primeira parte deste código e criaria dois novos projetos. Isso ocorre porque a Terraform não sabe que o projeto no endereço google_project.default foi movido para o novo endereço google_project.default["prod"] .
    3. Para consertar isso, execute o comando terraform state mv :
      terraform state mv "google_project.default" "google_project.default[\"prod\"]"
      
    4. Da mesma forma, para corrigir todos os outros blocos de recursos, execute terraform state mv para google_firebase_project , google_firebase_web_app e todos os outros blocos de recursos no seu arquivo main.tf
    5. Agora, se você executar terraform plan novamente, ele não deve mostrar que a Terraform excluiria o projeto que você criou na primeira parte deste código.
  4. Run terraform apply para provisionar seu novo projeto de "estadiamento" e todos os seus recursos e permitir seus serviços.
  5. Verifique se tudo foi provisionado e ativado conforme o esperado, verificando -os no console do Firebase como antes.

12. Etapa de bônus: implante seus aplicativos de estadiamento e Prod

  1. Na base de código do seu aplicativo, altere o firebase-config.js para usar a configuração do Firebase do seu projeto de estadiamento.

    Para se lembrar de como obter sua configuração de Firebase e adicioná -la ao seu aplicativo, consulte a etapa anterior deste código, adicione sua configuração do Firebase ao seu aplicativo.
  2. Na raiz do seu diretório web , execute o seguinte comando para implantar seu aplicativo para o seu projeto Firebase de Staging.
    firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
    
  3. Abra seu aplicativo de estadiamento no navegador através do URL impresso na saída da firebase deploy . Tente fazer login, enviar mensagens e fazer upload de imagens.

    Quando você implanta um aplicativo em um projeto FireBase, ele usa recursos reais de base de fogo, não recursos emulados. Ao interagir com o seu aplicativo de estadiamento, você deve ver dados e imagens aparecerem no seu projeto de estadiamento no console do Firebase.
  4. Depois de testar seu aplicativo no estadiamento, altere o firebase-config.js de volta ao uso da configuração Firebase do Project (o primeiro projeto que você criou neste código).
  5. Na raiz do seu diretório web , execute o seguinte comando para implantar seu aplicativo para o seu projeto Firebase de produção.
    firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
    
  6. Abra seu aplicativo de produção no navegador através do URL impresso na saída da firebase deploy . Tente fazer login, enviar mensagens e fazer upload de imagens.

    Você deve ver dados e imagens aparecerem em seu projeto de produção no console do Firebase.
  7. Quando terminar de interagir com os dois aplicativos para este código, você pode impedir que o Firebase de servi -los. Execute o seguinte comando para cada um de seus projetos:
    firebase hosting:disable --project=<STAGING_PROJECT_ID>
    
    firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
    

13. Parabéns!

Você usou a Terraform para configurar um aplicativo da web de bate-papo em tempo real! E você seguiu as melhores práticas para ambientes de desenvolvimento, criando projetos de Firebase separados para estadiamento e produto.

O que cobrimos

  • Usando a CLI da Terraform para gerenciar recursos em nuvem
  • Usando a Terraform para configurar os produtos FireBase (autenticação, Firestore, armazenamento em nuvem e regras de segurança)
  • Executando e testando um aplicativo da web localmente usando o Firebase Local Emulator Suite
  • Importando Firebase para um aplicativo da web
  • Usando o Terraform para replicar uma configuração em vários ambientes

Para mais informações sobre Firebase e Terraform, visite nossa documentação . Você pode encontrar uma lista de todos os produtos FireBase com suporte à Terraform, amostra de configurações de Terraform para casos de uso comuns e solução útil de problemas e perguntas frequentes.