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 descreve primeiro como criar um arquivo de configuração do Terraform para criar um novo projeto do Firebase, seguido de 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 conferir uma prévia das 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 os comandos da CLI do Terraform para gerenciar sua infraestrutura
- Como modificar a 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, preparação etc.)
Pré-requisitos
- Um terminal/console
- O ambiente de desenvolvimento integrado/editor de texto de sua escolha, como o WebStorm, o Atom, o Sublime ou o VS Code
- O navegador de sua escolha, como o Chrome
- Google Cloud CLI (CLI gcloud): instale essa CLI e faça login usando uma conta de usuário ou uma conta de serviço.
Para ter sucesso neste codelab, você precisa ter conhecimento básico do Terraform e da terminologia dele, incluindo os seguintes pré-requisitos:
- Instale o Terraform e leia os tutoriais oficiais dele.
Este codelab fornece um app de exemplo real para que você possa testar e interagir com o que provisionou pelo Terraform. Para fazer isso, você precisa do seguinte:
- O exemplo de código para um app da Web: faça o download dele 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 provisionamento pelo Terraform com um app da Web real. Recomendamos fazer isso para entender todas as etapas necessárias para usar os recursos provisionados pelo Terraform.
Clone o repositório do GitHub do codelab na linha de comando:
git clone https://github.com/firebase/codelab-friendlychat-web
Se o git não estiver instalado, faça o download do 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 transferido por download, 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 pela 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.
Inicializar o Terraform no diretório
A criação de uma nova configuração pela primeira vez exige o download do provedor especificado na configuração.
Para fazer essa inicialização, execute o comando a seguir na raiz do mesmo diretório do 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 é um projeto do Google Cloud, apenas 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.
Adicione o seguinte bloco de recursos ao arquivo de configuraçãomain.tf
.
Especifique o nome do projeto (como"Terraform FriendlyChat Codelab"
) e o ID do projeto (como"terraform-codelab-your-initials"
). O valorname
é usado apenas nas interfaces do Firebase e não é visível para os usuários finais. 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 necessárias: a API Usage e a API Firebase Management.
Essa ativação de API geralmente é processada em segundo plano quando você usa o console do Firebase para criar um projeto do Firebase, mas o Terraform precisa ser instruído explicitamente para fazer essa ativação.
Adicione o seguinte bloco de recursos ao arquivo de configuraçãomain.tf
(logo abaixo do bloco que cria o novo projeto do Cloud):
main.tf Ao ativar a API Service Usage, seu novo projeto poderá aceitar verificações de cota. Portanto, para todo 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 usar 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 no projeto.
Continuando no arquivo de configuração main.tf
, adicione o bloco de recursos a seguir.
Como mencionado acima, este bloco de recursos usa 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 instrui o Terraform a aguardar a ativação das APIs. Sem essa cláusula, o Terraform não sabe sobre a 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 mostra um plano de ações que serão realizadas.
Se tudo estiver conforme o esperado, aprove as ações digitandoyes
.
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ó precisa conferir as mudanças sem aplicá-las, use o comando terraform plan
.
Validar as mudanças
Depois que o Terraform terminar a execução, será possível inspecionar o estado de todos os recursos e serviços provisionados e ativados pelo Terraform executando o seguinte comando:
terraform show
Confira um exemplo do que você vai encontrar impresso. O estado vai conter valores específicos do 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, é possível verificar se o projeto foi criado visualizando-o no Console do Firebase.
5. Registrar seu app do Firebase pelo 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 provisionou pelo Terraform. Como esse app é da Web, você precisa informar ao Terraform que um app da Web do Firebase foi registrado no projeto do Firebase recém-criado.
Adicionar um bloco para registrar o app da Web
Para registrar o app da Web no projeto do Firebase, anexe o arquivo main.tf
ao bloco de recursos a seguir.
É necessário especificar seu próprio display_name
para o app da Web. Esse nome é usado apenas nas interfaces do Firebase e não é 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 comando a seguir na raiz do mesmo diretório do arquivo
main.tf
(que deve serweb
). Esse comando não recria um projeto do Google Cloud. O Terraform vai detectar que um projeto com o ID especificado já existe e comparar o estado atual do projeto com o que está no arquivoterraform apply
.tf
e fazer as alterações encontradas. - 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 provisionado, execute o seguinte comando:
terraform show
Como alternativa, você pode verificar se o app foi registrado no projeto no 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 próprias 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.
- Ao usar essa opção, não é necessário associar o novo projeto a uma conta do Cloud Billing.
- Opção 2: configurar a Autenticação do Firebase pelo Terraform usando as APIs do Google Cloud Identity Platform (GCIP).
- Ao usar essa opção, você precisa associar o 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.
Confira 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, Começar e na guia Método de login (ou clique aqui para acessar diretamente).
- Clique em Adicionar novo provedor e, na seção Outros provedores, selecione Google.
- Ative a opção Ativar.
- Defina o nome público do app como algo como
FriendlyChat
. Ele 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 pelo 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 seu projeto do Firebase e usar o plano Blaze, basta associar uma conta do Cloud Billing a ele.
Ativar o faturamento pelo Terraform
- Se você ainda não tem uma conta do Cloud Billing, a primeira etapa é criar uma no Console do Google Cloud. Anote o ID da conta de faturamento. O ID da conta de faturamento pode ser encontrado na página de faturamento em ID da conta de faturamento associado ao seu projeto.
- Para ativar o faturamento no seu projeto pelo 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 fazer login com o Google pelo Terraform
- Para provisionar o Firebase Authentication com o GCIP, anexe o arquivo
main.tf
aos 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 com o 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 consentimento 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 as informações a seguir e clique em Salvar e continuar.
- Defina o nome público do app para algo como
FriendlyChat
. Ele 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.
- Defina o nome público do app para algo como
- Nas próximas telas, faça o seguinte:
- Aceite os padrões na página Escopos e clique em Salvar e continuar.
- Aceite as configurações padrão na página Testar usuários e clique em Salvar e continuar.
- Leia o resumo e clique em Voltar ao painel.
- Configure um cliente OAuth na página Credenciais:
- Clique em Criar credenciais e selecione ID do cliente do Oauth.
- No menu suspenso Tipo de aplicativo, selecione Aplicativo da Web.
- No campo Name, 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 com o Google usando o ID e a chave secreta do cliente OAuth, anexe o arquivo
main.tf
com o seguinte bloco:
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>"
A execução deterraform apply
terraform apply
não recria um projeto do Google Cloud. O Terraform vai detectar que um projeto com o ID especificado já existe e comparar o estado atual do projeto com o que está no arquivo.tf
. Em seguida, ele vai fazer as mudanças encontradas. - 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 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
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 do banco de dados, anexe o arquivo
main.tf
com 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 fique 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, useus-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 que podem ser acessadas pelo 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 usando o arquivo
firestore.rules
local. - 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 usando o arquivo
- Execute
terraform apply
para provisionar o banco de dados do Firestore e implantar as regras de segurança. - Verifique se o banco de dados está provisionado e se as regras de segurança dele estão implantadas:
- No Console do Firebase, localize a seção Build no painel esquerdo.
- Acesse 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
Para o app da Web 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, anexe o arquivo
main.tf
com os blocos de recursos a seguir.
O bucket padrão do Cloud Storage para seu projeto é provisionado pelo Google App Engine e precisa ter o mesmo local que seu 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 usando o arquivo local.
- Libere a regra para o 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 está provisionado e se as regras de segurança dele estão 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 o app da Web pela primeira vez. Você vai usar o emulador do Firebase Hosting para disponibilizar o app localmente.
- Abra uma nova janela do terminal e, no diretório
web
, execute o comando CLI do Firebase a seguir 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 notar a interface do app FriendlyChat, que (ainda) não está funcionando. O app ainda não está conectado ao Firebase, mas será depois de concluir as próximas etapas deste codelab.
Sempre que você fizer mudanças no app da Web (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 e da configuração do Firebase para o 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. Você pode conferir em web/package.json
e web/src/index.js
se quiser saber o que já foi feito.
Embora o código de exemplo esteja quase completo, ainda é necessário fazer algumas coisas para que o app funcione, 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 o 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 do Firebase você quer usar.
Para este codelab, você tem duas opções diferentes para acessar a configuração do Firebase:
- Opção 1: extraia a configuração do Firebase do console do Firebase.
- Opção 2: extrair a configuração do Firebase pelo Terraform.
Opção 1: extrair a configuração do console do Firebase e adicioná-la à 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 o app da Web.
- Selecione Configuração no painel do snippet do SDK do Firebase e copie o snippet de configuração.
- Cole a configuração no arquivo
web/src/firebase-config.js
do app, como esta:
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 pelo Terraform e adicioná-la à base de código
Como alternativa, você pode receber a configuração do Firebase pelo Terraform como um valor de saída na CLI.
- No arquivo
main.tf
, encontre o bloco de recursosgoogle_firebase_web_app
, que registrou um app da Web com o 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 têm a finalidade de modificar a infraestrutura de nenhuma forma, você só precisa executar os comandos a seguir.- 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, como este:
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, anexe o arquivo web/src/index.js
do app com o seguinte:
...
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á exibindo seu app.
- Agora você pode fazer login com o Google e começar a postar mensagens no chat. Se você tiver arquivos de imagem, pode fazer o upload deles.
11. Replique a configuração em vários ambientes
O Terraform é excelente para gerenciar várias infraestruturas configuradas de maneira semelhante (por exemplo, configurar um projeto do Firebase de teste semelhante a um projeto de produção).
Neste codelab, você vai criar um segundo projeto do Firebase para ser um ambiente de preparo.
Para replicar uma configuração atual e criar esse projeto de preparação, 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 para a diferença entre o projeto replicado e o projeto de origem. - Opção 2: reutilize as configurações com
for_each
.
Essa opção oferece mais reutilização de código se cada projeto não for diferente de forma significativa e você quiser propagar as mudanças para todos os projetos de uma vez.
Opção 1: fazer uma cópia da configuração do Terraform
Essa opção oferece a maior flexibilidade para a diferença entre o projeto replicado e o projeto de origem, como ter apps com nomes de exibição e lançamentos em etapas diferentes.
- Na raiz do diretório
web
, crie um novo 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 eles funcionem com seu projeto de preparação:- 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 você quiser usar essa configuração, siga estas etapas:- 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 o atributoname
, o atributoproject-id
e (se você configurar a autenticação pelo Terraform) o atributobilling_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 o novo projeto de "ambiente de testes" do Firebase e todos os recursos e 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 diferente de forma significativa e você quiser propagar as mudanças para todos os projetos de uma 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
, como este:
main.tf Você encontra 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 você quiser usar essa configuração, siga estas etapas:- 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 o atributoname
, o atributoproject-id
e (se você configurar a autenticação pelo Terraform) o atributobilling_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ê aplicar essa configuração que usa
for_each
, os endereços de recursos vão ficar assim: No entanto, o projeto criado na primeira parte deste codelab é conhecido pelo Terraform da seguinte forma: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 conferir quais ações o Terraform realizaria com base 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 ocorre 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 que você criou na primeira parte deste codelab.
- No momento, se você aplicar essa configuração que usa
- Execute
terraform apply
para provisionar o novo projeto de "ambiente de testes" do Firebase e todos os recursos e ativar os serviços. - Verifique se tudo foi provisionado e ativado conforme o esperado no Console do Firebase, como antes.
12. Etapa extra: implantar os apps de teste e de produção
- Na base de código do app, mude o
firebase-config.js
para usar a configuração do Firebase do seu projeto de preparação.
Para lembrar como acessar a configuração do Firebase e adicioná-la 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 abaixo para implantar o app no projeto de teste do Firebase.firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
- Abra o app de pré-produção no navegador pelo URL impresso na saída de
firebase deploy
. Tente fazer login, enviar mensagens e fazer upload de imagens.
Ao implantar um app em um projeto do Firebase, ele usa recursos reais do Firebase, não recursos emulados. Ao interagir com o app de pré-produção, os dados e as imagens vão aparecer no projeto de pré-produção no Console do Firebase. - Depois de testar o app no ambiente de pré-produção, mude o
firebase-config.js
para usar a configuração do Firebase do projeto de produção (o primeiro projeto que você criou neste codelab). - Na raiz do diretório
web
, execute o comando abaixo 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
. Faça login, envie mensagens e faça 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ê pode impedir que o Firebase os exiba. 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 do Firebase separados para ambiente de testes e produção.
O que vimos
- Como usar a CLI do Terraform para gerenciar recursos da nuvem
- Como usar o Terraform para configurar produtos do Firebase (Authentication, Firestore, Cloud Storage e regras de segurança)
- Como executar e testar um app da Web localmente usando o Pacote de emuladores locais do Firebase
- Como importar o Firebase para um app da Web
- Como 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 ao Terraform, exemplos de configurações do Terraform para casos de uso comuns, além de solução de problemas e perguntas frequentes.