1. Introdução
Metas
É possível usar o Terraform para configurar e gerenciar um projeto do Firebase, incluindo a configuração programática da infraestrutura e dos produtos do Firebase.
Este codelab primeiro descreve como criar um arquivo de configuração do Terraform para criar um novo projeto do Firebase e, em seguida, como configurar os apps e produtos do Firebase que você quer usar nesse projeto. Também abordamos os conceitos básicos da linha de comando do Terraform, como visualizar as mudanças a serem feitas e implementá-las.
Se você quer aprender a configurar e gerenciar projetos e produtos do Firebase com o Terraform, este codelab é para você.
O que você vai aprender
- Como criar um arquivo de configuração do Terraform (
*.tf
) - Como usar comandos da CLI do Terraform para gerenciar sua infraestrutura
- Como modificar sua configuração para atualizar recursos e serviços
- Como aplicar sua configuração em um app da Web real (chamado Friendly Chat)
- Como definir configurações paralelas (e sincronizadas) em diferentes ambientes (produção, preparo etc.)
Pré-requisitos
- Um terminal/console
- O ambiente de desenvolvimento integrado/editor de texto de sua escolha, como WebStorm, Atom, Sublime ou VS Code
- O navegador da sua escolha, como o Chrome
- A CLI do Google Cloud (gcloud CLI): instale essa CLI e faça login usando uma conta de usuário ou uma conta de serviço.
Para concluir este codelab, você precisa ter proficiência básica com o Terraform e sua terminologia, incluindo os seguintes pré-requisitos:
- Instale o Terraform e leia os tutoriais oficiais dele.
Este codelab oferece um app de exemplo real para que você possa testar e interagir com o que provisiona usando o Terraform. Para isso, você precisa do seguinte:
- O exemplo de código de um app da Web. Faça o download desse código na próxima etapa do codelab.
- O gerenciador de pacotes npm (que geralmente vem com o Node.js): instale essas ferramentas.
- A CLI do Firebase: instale essa CLI e faça login.
2. Fazer o download do código inicial
Neste codelab, você pode testar o que provisiona com o Terraform usando um app da Web real. Recomendamos fazer isso para entender todas as etapas necessárias para usar recursos provisionados pelo Terraform.
Clone o repositório do GitHub (link em inglês) do codelab na linha de comando:
git clone https://github.com/firebase/codelab-friendlychat-web
Se preferir, baixe o repositório como um arquivo ZIP.
3. Criar uma configuração do Terraform
Configuração do Terraform
- Na base de código do app de exemplo baixado, navegue até a raiz do diretório
web
. - 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 em relação à cota. Para provisionar a maioria dos recursos, use user_project_override = true
, o que significa verificar a cota do seu próprio projeto do Firebase. No entanto, para configurar o 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
Para criar uma configuração pela primeira vez, é necessário fazer o download do provedor especificado na configuração.
Para fazer essa inicialização, execute o seguinte comando na raiz do mesmo diretório que o arquivo de configuração main.tf
:
terraform init
4. Criar um projeto do Firebase usando o Terraform
Para "criar um projeto do Firebase", é importante lembrar que cada projeto do Firebase é, na verdade, um projeto do Google Cloud, só que com os serviços do Firebase ativados.
Adicionar blocos para o projeto e as APIs do Google Cloud
- Primeiro, provisione o projeto do Google Cloud subjacente.
Adicione o seguinte bloco de recursos ao arquivo de configuraçãomain.tf
.
É necessário especificar seu próprio nome de projeto (como"Terraform FriendlyChat Codelab"
) e ID do projeto (como"terraform-codelab-your-initials"
). O valorname
é usado apenas nas interfaces do Firebase e não fica visível para os usuários finais. No entanto, o valorproject_id
identifica seu projeto de forma exclusiva para o Google. Portanto, especifique 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" } }
- Em seguida, ative as APIs subjacentes necessárias: a API Service Usage e a API Firebase Management.
Essa ativação de API geralmente é processada nos bastidores quando você usa o console do Firebase para criar um projeto do Firebase, mas o Terraform precisa ser explicitamente instruído a fazer isso.
No arquivo de configuraçãomain.tf
(logo abaixo do bloco que cria o novo projeto do Cloud), adicione o seguinte bloco de recursos:
main.tf Ao ativar a API Service Usage, seu novo projeto poderá aceitar verificações de cota. Portanto, para todo o provisionamento de recursos e ativação de serviços subsequentes, use o provedor com... # 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
(não é necessário um alias).
Adicionar um bloco para ativar os serviços do Firebase
A última coisa necessária para "criar um projeto do Firebase" é ativar os serviços do Firebase nele.
Continuando no arquivo de configuração main.tf
, adicione o seguinte bloco de recursos.
Como mencionado acima, observe que esse bloco de recursos está usando o provedor com user_project_override
(não é necessário um alias).
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,
]
}
No bloco de recursos acima, você pode notar a cláusula depends_on
, que informa ao Terraform para aguardar a ativação das APIs subjacentes. Sem essa cláusula, o Terraform não sabe da dependência e pode encontrar erros ao provisionar recursos em paralelo.
Aplique a configuração
- Para provisionar os novos recursos e ativar as APIs especificadas no arquivo de configuração, execute o seguinte comando na raiz do mesmo diretório do arquivo
main.tf
(que deve serweb
):terraform apply
- No terminal, o Terraform imprime um plano de ações que serão realizadas.
Se tudo estiver conforme o esperado, aprove as ações inserindoyes
.
main.tfTerraform 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 # <----
Se você só precisar visualizar as mudanças sem aplicar, use o comando terraform plan
.
Validar as mudanças
Depois que o Terraform terminar de ser executado, inspecione o estado de todos os recursos e serviços provisionados pelo Terraform executando o seguinte comando:
terraform show
Confira um exemplo de como o texto vai aparecer impresso. Seu estado vai conter valores específicos do 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, verifique se o projeto foi criado no Console do Firebase.
5. Registrar seu app do Firebase usando o Terraform
Para usar o Firebase, é necessário registrar cada variante de plataforma do app no projeto do Firebase. Neste codelab, você vai usar um app real para testar e interagir com o que provisionar usando o Terraform. Como este é um app da Web, você precisa informar ao Terraform para registrar um app da Web do Firebase no projeto recém-criado.
Adicionar um bloco para registrar o app da Web
Para registrar o web app no projeto do Firebase, adicione o seguinte bloco de recursos ao arquivo main.tf
.
Você precisa especificar seu próprio display_name
para o app da Web. Esse nome é usado apenas nas interfaces do Firebase e não fica visível para os usuários finais.
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"
}
Aplique a configuração
- Para provisionar o novo recurso, execute o seguinte comando na raiz do mesmo diretório que o arquivo
main.tf
(que deve serweb
). Esse comando não vai recriar um projeto do Google Cloud. O Terraform vai detectar que já existe um projeto com o ID especificado e vai comparar o estado atual do projeto com o que está no arquivoterraform apply
.tf
, fazendo as mudanças necessárias. - Analise o plano de ações impresso. Se tudo estiver certo, digite
yes
e pressione "Enter" para aprovar as ações.
Validar as mudanças
Para inspecionar o estado do recurso recém-provisionado, execute o seguinte comando:
terraform show
Você também pode verificar se o app foi registrado no projeto acessando o console do Firebase. Acesse Configurações do projeto e role para baixo até a seção Seus apps.
6. Configurar o Firebase Authentication
A autenticação é uma parte importante de qualquer app. Para permitir que os usuários finais façam login no seu app da Web com as Contas do Google, ative o Firebase Authentication e configure o método de login com o Google.
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 exige o GCIP.
- Usar essa opção significa que você não precisa associar seu novo projeto a uma conta do Cloud Billing.
- Opção 2: configure o Firebase Authentication usando o Terraform com as APIs do Google Cloud Identity Platform (GCIP).
- Usar essa opção significa que você precisa associar seu novo projeto a uma conta do Cloud Billing, já que 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 console do Firebase, seu projeto não precisa estar no plano de preços Blaze.
Veja como configurar o Firebase Authentication e fazer login com o Google:
- No Console do Firebase, localize a seção Build no painel esquerdo.
- Clique em Autenticação, em Começar e na guia Método de login (ou clique aqui para acessar diretamente).
- Clique em Adicionar novo provedor e, na seção Provedores adicionais, selecione Google.
- Ative a opção Ativar.
- Defina o nome público do app como algo como
FriendlyChat
(não precisa ser globalmente exclusivo). - Escolha um E-mail de suporte do projeto no menu suspenso e clique em Salvar.
- O Google vai aparecer como um provedor de login ativado.
Opção 2: configurar a autenticação via Terraform usando as APIs do Google Cloud Identity Platform (GCIP)
Para configurar o Firebase Authentication pelo Terraform, é necessário usar as APIs do GCIP, o que significa que o projeto precisa estar no plano de preços Blaze. Para fazer upgrade do projeto do Firebase e usar o plano Blaze, associe uma conta do Cloud Billing ao projeto.
Ativar o faturamento usando o Terraform
- Se você ainda não tiver uma conta do Cloud Billing, a primeira etapa é criar uma no Console do Google Cloud. Ao fazer isso, anote o ID da conta de faturamento. O ID da conta de faturamento pode ser encontrado na página "Faturamento", no ID da conta de faturamento associado ao seu projeto.
- Para ativar o faturamento no seu projeto usando o Terraform, adicione um atributo
billing_account
ao recursogoogle_project
no arquivomain.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" } } ...
Ativar o Firebase Authentication e o login com o Google usando o Terraform
- Para provisionar o Firebase Authentication com o GCIP, adicione 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, ] }
- Para ativar o Login do Google, você precisa ter um cliente OAuth. Acesse a seção APIs e serviços do Console do Google Cloud para fazer essa configuração.
- Como esta é a primeira vez que você cria um ID do cliente para este projeto, é necessário configurar a tela de consentimento do OAuth.
- Abra a página Tela de permissão do OAuth e selecione o projeto que você acabou de criar.
- Defina o Tipo de usuário como Externo e clique em Criar.
- Na próxima tela, preencha o seguinte e clique em Salvar e continuar.
- Defina o Nome do app público como algo parecido com
FriendlyChat
. Não é necessário que ele seja globalmente exclusivo. - Escolha um e-mail de suporte ao usuário no menu suspenso.
- Insira um e-mail nas Informações de contato do desenvolvedor.
- Defina o Nome do app público como algo parecido com
- Nas próximas telas, faça 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.
- Configure um cliente OAuth na página Credenciais fazendo o seguinte:
- Clique em Criar credenciais e selecione ID do cliente do Oauth.
- No menu suspenso Tipo de aplicativo, selecione Aplicativo da Web.
- No campo Nome, insira o nome do app, por exemplo,
FriendlyChat
. Ele não precisa ser globalmente exclusivo. - Permita que o URL do app use esse cliente OAuth definindo o seguinte:
- Em Origens JavaScript autorizadas, clique em Adicionar URI e insira
https://<PROJECT_ID>.firebaseapp.com
, em que<PROJECT_ID>
é o ID do projeto definido emmain.tf
. - Em URIs de redirecionamento autorizados, clique em Adicionar URI e insira
https://<PROJECT_ID>.firebaseapp.com/__/auth/handler
, em que<PROJECT_ID>
é o ID do projeto definido emmain.tf
.
- Em Origens JavaScript autorizadas, clique em Adicionar URI e insira
- Clique em Salvar.
- Para ativar o Login do Google usando o ID do cliente e a chave secreta do cliente OAuth, adicione o seguinte bloco ao 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 ] }
Aplique a configuração
- Para configurar a autenticação de acordo com sua configuração, execute os seguintes comandos na raiz do mesmo diretório do arquivo
main.tf
(que deve serweb
):export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
Executarterraform apply
terraform apply
não vai recriar um projeto do Google Cloud. O Terraform vai detectar que já existe um projeto com o ID especificado e vai comparar o estado atual do projeto com o que está no arquivo.tf
. Em seguida, ele fará as mudanças necessárias. - Analise o plano de ações impresso. Se tudo estiver certo, digite
yes
e pressione "Enter" para aprovar as ações.
Validar as mudanças
- No Console do Firebase, localize a seção Build no painel esquerdo.
- Clique em Autenticação e depois na guia Método de login (ou clique aqui para acessar diretamente).
- O Google vai aparecer como um provedor de login ativado.
7. Configurar um banco de dados do Firestore e as regras de segurança dele
Para o app da Web deste codelab, você vai armazenar mensagens entre usuários finais em um banco de dados do Firestore.
- Para ativar as APIs necessárias e provisionar a instância de banco de dados, adicione 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 ] }
- Mude
<NAME_OF_DESIRED_REGION>
para a região em que você quer que o banco de dados fique.
Ao desenvolver um app de produção, é recomendável 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. Neste codelab, você pode usarus-east1
(Carolina do Sul) ou a região mais próxima de você (consulte Locais do Cloud Firestore). - Todas as instâncias de banco de dados do Firestore acessíveis ao Firebase precisam ser protegidas pelas regras de segurança do Firebase.
O código de exemplo deste codelab fornece um conjunto de regras seguras do Firestore no arquivofirestore.rules
, que pode ser encontrado na raiz do diretórioweb
. - Anexe o arquivo
main.tf
com os seguintes blocos de recursos para fazer o seguinte:- Crie um conjunto de regras de segurança do Firebase no arquivo local
firestore.rules
. - Libere o conjunto de regras para a instância do Firestore.
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 ] } }
- Crie um conjunto de regras de segurança do Firebase no arquivo local
- Execute
terraform apply
para provisionar o banco de dados do Firestore e implantar as regras de segurança dele. - Verifique se o banco de dados foi provisionado e se as regras de segurança dele foram implantadas:
- No Console do Firebase, localize a seção Build no painel à esquerda.
- Vá até a seção Banco de dados do Firestore e clique na guia Regras.
8. Configurar um bucket do Cloud Storage e as regras de segurança dele
Para o web app deste codelab, você vai armazenar imagens compartilhadas entre usuários finais em um bucket do Cloud Storage.
- Para ativar as APIs necessárias e provisionar o bucket padrão do Cloud Storage, adicione ao arquivo
main.tf
os seguintes blocos de recursos.
O bucket padrão do Cloud Storage para seu projeto é provisionado pelo Google App Engine e precisa estar no mesmo local que o banco de dados do Firestore. Consulte Locais do App Engine para mais informações.
Se você quiser vários buckets no projeto, provisione-os usando o recursogoogle_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 }
- Todos os buckets do Cloud Storage acessíveis ao Firebase precisam ser protegidos pelas regras de segurança do Firebase.
O código de exemplo deste codelab fornece um conjunto de regras seguras do Firestore no arquivostorage.rules
, que pode ser encontrado na raiz do diretórioweb
. - Anexe o arquivo
main.tf
com os seguintes blocos de recursos para fazer o seguinte:- Crie um conjunto de regras de segurança do Firebase com base no arquivo local.
- Libere o conjunto de regras do bucket do Storage.
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 ] } }
- Execute
terraform apply
para provisionar o bucket padrão do Cloud Storage e implantar as regras de segurança dele. - Verifique se o bucket foi provisionado e se as regras de segurança foram implantadas:
- No Console do Firebase, localize a seção Build no painel esquerdo.
- Acesse a seção Armazenamento e clique na guia Regras.
9. Execute seu aplicativo localmente
Agora você já pode executar seu app da Web pela primeira vez. Você vai usar o emulador do Firebase Hosting para disponibilizar seu app localmente.
- Abra uma nova janela do terminal e, no diretório
web
, execute o seguinte comando da CLI do Firebase para iniciar o emulador:firebase emulators:start --project=<PROJECT_ID>
- No navegador, abra o app da Web no URL local retornado pela CLI (geralmente
http://localhost:5000
).
Você vai ver a interface do usuário do app FriendlyChat, que (ainda) não está funcionando. O app ainda não está conectado ao Firebase, mas isso vai acontecer quando você concluir as próximas etapas deste codelab.
Sempre que você fizer mudanças no web app (como nas próximas etapas deste codelab), atualize o navegador para atualizar o URL local com essas mudanças.
10. Instalar, configurar e inicializar o Firebase
Para que um app funcione com o Firebase, ele precisa do SDK do Firebase e da configuração do Firebase para seu projeto.
O código de exemplo deste codelab já é um app funcional com todas as dependências e funções necessárias para usar vários produtos do Firebase. Consulte web/package.json
e web/src/index.js
se quiser ver o que já foi feito.
Embora o código de exemplo esteja quase completo, ainda é necessário fazer algumas coisas para executar o app, incluindo: instalar o SDK do Firebase, iniciar o build, adicionar a configuração do Firebase ao app e, por fim, inicializar o Firebase.
Instalar o SDK do Firebase e iniciar o build do webpack
Você precisa executar alguns comandos para iniciar o build do app.
- Abra uma nova janela do terminal.
- Verifique se você está na raiz do diretório
web
. - Execute
npm install
para fazer o download do SDK do Firebase. - Execute
npm update
para atualizar as dependências. - Execute
npm run start
para iniciar o webpack.
No restante do codelab, o webpack vai recriar continuamente seu código-fonte.
Adicionar a configuração do Firebase ao app
Você também precisa adicionar a configuração do Firebase ao seu app para que os SDKs do Firebase saibam qual projeto usar.
Para este codelab, você tem duas opções diferentes para receber sua configuração do Firebase:
- Opção 1: receba a configuração do Firebase no Console do Firebase.
- Opção 2: obtenha a configuração do Firebase usando o Terraform.
Opção 1: extrair a configuração do Console do Firebase e adicioná-la à sua base de código
- No console do Firebase, acesse as Configurações do projeto.
- Role a tela para baixo até o card Seus apps e selecione seu web app.
- Selecione Config no painel de snippets do SDK do Firebase e copie o snippet de configuração.
- Cole a configuração no arquivo
web/src/firebase-config.js
do app, 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: extrair a configuração usando o Terraform e adicioná-la à base de código
Como alternativa, é possível receber a configuração do Firebase via Terraform como um valor de saída na CLI.
- No arquivo
main.tf
, encontre o bloco de recursosgoogle_firebase_web_app
(o bloco que registrou um web app no seu projeto). - 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", "") } } ...
- Como o bloco
data
e o blocooutput
não foram criados para modificar a infraestrutura de forma alguma, basta executar os seguintes comandos.- Para carregar a configuração do Firebase do seu app da Web no estado do Terraform do seu diretório, execute este comando:
terraform refresh
- Para imprimir os valores de configuração do Firebase, execute este comando:
Confira a seguir um exemplo de saída de uma configuração. A saída impressa vai conter os valores do projeto e do app.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" } } }
- Para carregar a configuração do Firebase do seu app da Web no estado do Terraform do seu diretório, execute este comando:
- Copie os valores do mapa
value
. - Cole esses valores (sua configuração) no arquivo
web/src/firebase-config.js
do app, 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", }; ...
Inicializar o Firebase no seu app
Por fim, para inicializar o Firebase, adicione o seguinte ao arquivo web/src/index.js
do app:
...
const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);
Testar o app
Agora que tudo está configurado para o Firebase, você pode testar seu app da Web funcional.
- Atualize o navegador que está veiculando seu app.
- Agora você pode fazer login com o Google e começar a postar mensagens no chat. Se você tiver arquivos de imagem, também poderá fazer upload deles.
11. Replicar sua configuração em vários ambientes
O Terraform é excelente para gerenciar várias infraestruturas configuradas de maneira semelhante (por exemplo, configurar um projeto de teste do Firebase semelhante a um projeto de produção).
Neste codelab, você vai criar um segundo projeto do Firebase para ser um ambiente de staging.
Para replicar uma configuração atual e criar esse projeto de staging, você tem duas opções:
- Opção 1: faça uma cópia da configuração do Terraform.
Essa opção oferece a maior flexibilidade em relação ao quanto o projeto replicado pode ser diferente do projeto de origem. - Opção 2: reutilize configurações com
for_each
.
Essa opção oferece mais reutilização de código se cada projeto não for muito diferente e você quiser propagar as mudanças para todos os projetos de uma só vez.
Opção 1: fazer uma cópia da configuração do Terraform
Essa opção oferece a maior flexibilidade em relação ao quanto o projeto replicado pode diferir do projeto de origem, como ter apps com nomes de exibição diferentes e lançamentos graduais.
- Na raiz do diretório
web
, crie um arquivo de configuração do Terraform chamadomain_staging.tf
. - Copie todos os blocos de recursos do arquivo
main.tf
(exceto os blocosterraform
eprovider
) e cole-os no arquivomain_staging.tf
. - Em seguida, modifique cada um dos blocos de recursos replicados em
main_staging.tf
para que funcionem com seu projeto de preparo:- Rótulos de recursos:use um novo nome para evitar conflitos. Por exemplo, renomeie
resource "google_project" "default"
comoresource "google_project" "staging"
. - Referências de recursos:atualize cada uma delas. Por exemplo, atualize
google_firebase_project.default.project
paragoogle_firebase_project.staging.project
.
main_staging.tf
no repositório do GitHub deste codelab:web/terraform-checkpoints/replicate-config/main_staging-copypaste.tf
. Se quiser usar essa configuração, faça o seguinte:- Copie a configuração de
main_staging-copypaste.tf
e cole no arquivomain_staging.tf
. - No arquivo
main_staging.tf
, faça o seguinte:- No bloco de recursos
google_project
, atualize os atributosname
,project-id
e (se você configurou a autenticação via Terraform)billing_account
com seus próprios valores. - No bloco de recursos
google_firebase_web_app
, atualize o atributodisplay_name
com seu próprio valor. - Nos blocos de recursos
google_firestore_database
egoogle_app_engine_application
, atualize os atributoslocation_id
com seu próprio valor.
- No bloco de recursos
# 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" }
- Rótulos de recursos:use um novo nome para evitar conflitos. Por exemplo, renomeie
- Execute
terraform apply
para provisionar seu novo projeto do Firebase "staging" e todos os recursos dele, além de ativar os serviços. - Verifique se tudo foi provisionado e ativado conforme o esperado no Console do Firebase, como antes.
Opção 2: reutilizar configurações com for_each
Essa opção oferece mais reutilização de código se cada projeto não for muito diferente e você quiser propagar as mudanças para todos os projetos de uma só vez. Ele usa o meta-argumento for_each
na linguagem Terraform.
- Abra seu arquivo
main.tf
. - Em cada bloco de recursos que você quer replicar, adicione um meta-argumento
for_each
, assim:
main.tf Confira a configuração completa de um arquivo# 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.
main.tf
que usa o metaargumentofor_each
no repositório do GitHub deste codelab:web/terraform-checkpoints/replicate-config/main-foreach.tf
Se quiser usar essa configuração, faça o seguinte:- Copie a configuração de
main-foreach.tf
e cole no arquivomain.tf
. - No arquivo
main.tf
, faça o seguinte:- No bloco de recursos
google_project
, atualize os atributosname
,project-id
e (se você configurou a autenticação via Terraform)billing_account
com seus próprios valores. - No bloco de recursos
google_firebase_web_app
, atualize o atributodisplay_name
com seu próprio valor. - Nos blocos de recursos
google_firestore_database
egoogle_app_engine_application
, atualize os atributoslocation_id
com seu próprio valor.
- No bloco de recursos
- Copie a configuração de
- Em vez de aplicar essa configuração imediatamente, é importante entender e corrigir algumas coisas sobre como o Terraform interpreta essa configuração em comparação com a infraestrutura atual.
- No momento, se você aplicasse essa configuração que usa
for_each
, os endereços de recursos seriam semelhantes a este: No entanto, o projeto que você criou na primeira parte deste codelab é conhecido pelo Terraform como: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"]
google_project.default google_firebase_project.default google_firebase_android_app.default
- Execute
terraform plan
para ver quais ações o Terraform realizaria no estado atual.
A saída vai mostrar que o Terraform excluiria o projeto criado na primeira parte deste codelab e criaria dois novos projetos. Isso acontece porque o Terraform não sabe que o projeto no endereçogoogle_project.default
foi movido para o novo endereçogoogle_project.default["prod"]
. - Para corrigir isso, execute o comando
terraform state mv
:terraform state mv "google_project.default" "google_project.default[\"prod\"]"
- Da mesma forma, para corrigir todos os outros blocos de recursos, execute
terraform state mv
paragoogle_firebase_project
,google_firebase_web_app
e todos os outros blocos de recursos no arquivomain.tf
. - Agora, se você executar
terraform plan
novamente, não vai aparecer que o Terraform excluiria o projeto criado na primeira parte deste codelab.
- No momento, se você aplicasse essa configuração que usa
- Execute
terraform apply
para provisionar seu novo projeto do Firebase "staging" e todos os recursos dele, além de ativar os serviços. - Verifique se tudo foi provisionado e ativado conforme o esperado no Console do Firebase, como antes.
12. Etapa extra: implante os apps de teste e produção
- Na base de código do app, mude o
firebase-config.js
para usar a configuração do Firebase do projeto de teste.
Para lembrar como acessar e adicionar a configuração do Firebase ao app, consulte a etapa anterior deste codelab, "Adicionar a configuração do Firebase ao app". - Na raiz do diretório
web
, execute o comando a seguir para implantar o app no projeto de teste do Firebase.firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
- Abra o app de teste no navegador usando o URL impresso na saída de
firebase deploy
. Tente fazer login, enviar mensagens e fazer upload de imagens.
Quando você implanta um app em um projeto do Firebase, ele usa recursos reais do Firebase, não emulados. Ao interagir com o app de teste, você vai ver dados e imagens aparecerem no projeto de teste no console do Firebase. - Depois de testar o app em staging, mude o
firebase-config.js
para usar a configuração do Firebase do projeto de produção (o primeiro projeto criado neste codelab). - Na raiz do diretório
web
, execute o seguinte comando para implantar o app no projeto de produção do Firebase.firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
- Abra o app de produção no navegador usando o URL impresso na saída de
firebase deploy
. Tente fazer login, enviar mensagens e fazer upload de imagens.
Os dados e as imagens vão aparecer no projeto de produção no console do Firebase. - Quando terminar de interagir com os dois apps deste codelab, você poderá impedir que o Firebase os veicule. Execute o seguinte comando para cada um dos seus projetos:
firebase hosting:disable --project=<STAGING_PROJECT_ID>
firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
13. Parabéns!
Você usou o Terraform para configurar um aplicativo da Web de chat em tempo real. Você seguiu as práticas recomendadas para ambientes de desenvolvimento criando projetos separados do Firebase para preparo e produção.
O que vimos
- Como usar a CLI do Terraform para gerenciar recursos da nuvem
- Usar o Terraform para configurar produtos do Firebase (Authentication, Firestore, Cloud Storage e regras de segurança)
- Executar e testar um app da Web localmente usando o Pacote de emuladores locais do Firebase
- Importar o Firebase para um app da Web
- Usar o Terraform para replicar uma configuração em vários ambientes
Para mais informações sobre o Firebase e o Terraform, acesse nossa documentação. Confira uma lista de todos os produtos do Firebase com suporte do Terraform, exemplos de configurações do Terraform para casos de uso comuns e perguntas frequentes e dicas úteis para solução de problemas.