1. Introducción
Objetivos
Puedes usar Terraform para configurar y administrar un proyecto de Firebase, incluida la configuración programática de la infraestructura y los productos de Firebase.
En este codelab, primero se describe cómo compilar un archivo de configuración de Terraform para crear un nuevo proyecto de Firebase. Luego, se explica cómo configurar las apps y los productos de Firebase que quieras usar en ese proyecto. También veremos los conceptos básicos de la línea de comandos de Terraform, como la vista previa de los cambios que se realizarán y, luego, su implementación.
Si quieres aprender a configurar y administrar proyectos y productos de Firebase con Terraform, este codelab es para ti.
Aprendizajes esperados
- Cómo crear un archivo de configuración de Terraform (
*.tf
) - Cómo usar los comandos de la CLI de Terraform para administrar tu infraestructura
- Cómo modificar la configuración para actualizar los recursos y servicios
- Cómo aplicar tu configuración en una aplicación web real (llamada Friendly Chat)
- Cómo definir configuraciones paralelas (y sincronizadas) en diferentes entornos (producción, etapa de pruebas, etcétera)
Requisitos
- Una terminal/consola
- El editor de texto o IDE que prefieras, como WebStorm, Atom, Sublime o VS Code
- El navegador que prefieras, como Chrome
- Google Cloud CLI (gcloud CLI): instala esta CLI y accede con una cuenta de usuario o una cuenta de servicio
Para completar este codelab correctamente, debes tener conocimientos básicos sobre Terraform y su terminología, incluidos los siguientes requisitos previos:
- Instala Terraform y familiarízate con él mediante sus instructivos oficiales.
En este codelab, se proporciona una app de ejemplo real para que puedas probar lo que aprovisionas a través de Terraform y también interactuar con él. Para ello, necesitarás lo siguiente:
- El código de muestra para una app web: Descárgalo en el siguiente paso del codelab
- Instala estas herramientas en el administrador de paquetes npm (que suele incluir Node.js).
- Firebase CLI: Instala esta CLI y accede
2. Obtén el código de partida
En este codelab, puedes probar lo que aprovisionas mediante Terraform con una app web real. Te recomendamos que lo hagas de modo que comprendas todos los pasos necesarios para usar los recursos aprovisionados por Terraform.
Clona el repositorio de GitHub del codelab desde la línea de comandos:
git clone https://github.com/firebase/codelab-friendlychat-web
Como alternativa, si no tienes instalado Git, puedes descargar el repositorio como un archivo ZIP.
3. Cómo crear una configuración de Terraform
Configuración de Terraform
- En la base de código de la app de ejemplo descargada, navega hasta la raíz del directorio
web
. - En la raíz de ese directorio, crea un archivo de configuración de Terraform llamado
main.tf
con la siguiente configuración 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 uno de los proveedores de google-beta
tiene un atributo llamado user_project_override
que determina cómo se verificarán las cuotas de las operaciones de Terraform. Para aprovisionar la mayoría de los recursos, debes usar user_project_override = true
, lo que significa que debes verificar la cuota en tu propio proyecto de Firebase. Sin embargo, si quieres configurar tu proyecto nuevo para que pueda aceptar verificaciones de cuotas, primero debes usar user_project_override=false
. La sintaxis alias
de Terraform te permite distinguir entre las dos configuraciones del proveedor en los siguientes pasos de este codelab.
Inicializa Terraform en el directorio
Para crear una configuración nueva por primera vez, debes descargar el proveedor especificado en la configuración.
Para realizar esta inicialización, ejecuta el siguiente comando desde la raíz del mismo directorio que el archivo de configuración main.tf
:
terraform init
4. Crea un proyecto de Firebase mediante Terraform
Para “crear un proyecto de Firebase”, es importante recordar que cada proyecto de Firebase es en realidad un proyecto de Google Cloud, solo que tiene habilitados los servicios de Firebase.
Agrega bloques para el proyecto de Google Cloud subyacente y las APIs.
- Primero, aprovisiona el proyecto subyacente de Google Cloud.
Agrega el siguiente bloque de recursos al archivo de configuraciónmain.tf
.
Debes especificar el nombre del proyecto (como"Terraform FriendlyChat Codelab"
) y el ID del proyecto (como"terraform-codelab-your-initials"
). Ten en cuenta que el valorname
solo se usa dentro de las interfaces de Firebase y no es visible para los usuarios finales. Sin embargo, el valorproject_id
identifica tu proyecto de forma única para Google, así que asegúrate de especificar un valor único. 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" } }
- A continuación, debes habilitar las APIs subyacentes requeridas: la API de Service Usage y la API de Firebase Management.
Por lo general, la habilitación de la API se realiza en segundo plano cuando se usa Firebase console para crear un proyecto de Firebase. Sin embargo, se le debe indicar explícitamente a Terraform que lo haga.
En tu archivo de configuraciónmain.tf
(justo debajo del bloque que crea el nuevo proyecto de Cloud), agrega el siguiente bloque de recursos:
Las verificaciones de uso de la nueva API de Service.
Por lo tanto, para todo el aprovisionamiento de recursos y la habilitación de servicios posteriores, debes usar el proveedor con... # 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
(sin alias).
Agrega un bloque para habilitar los servicios de Firebase
Lo último que debes hacer para “crear un proyecto de Firebase” es habilitar los servicios de Firebase en el proyecto.
En el archivo de configuración main.tf
, agrega el siguiente bloque de recursos.
Como se mencionó anteriormente, ten en cuenta que este bloque de recursos usa el proveedor con user_project_override
(no se necesita 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,
]
}
En el bloque de recursos anterior, es posible que veas la cláusula depends_on
, que le indica a Terraform que espere a que se habiliten las APIs subyacentes. Sin esta cláusula, Terraform no conoce la dependencia y puede experimentar errores cuando se aprovisionan recursos en paralelo.
Aplica la configuración
- Para aprovisionar los recursos nuevos y habilitar las APIs especificadas en tu archivo de configuración, ejecuta el siguiente comando desde la raíz del mismo directorio que tu archivo
main.tf
(que debería serweb
):terraform apply
- En la terminal, Terraform imprime un plan de acciones que realizará.
Si todo se ve como se esperaba, ingresayes
para aprobar las acciones.
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 # <----
Ten en cuenta que, si solo necesitas obtener una vista previa de los cambios sin aplicarlos, puedes usar el comando terraform plan
en su lugar.
Valida los cambios
Cuando Terraform termine de ejecutarse, puedes inspeccionar el estado de todos los recursos y servicios aprovisionados por Terraform que estén habilitados ejecutando el siguiente comando:
terraform show
Este es un ejemplo de lo que deberías ver impreso. El estado contendrá valores específicos para tu proyecto.
# 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"
}
También puedes verificar que el proyecto se creó en Firebase console.
5. Registra tu app de Firebase mediante Terraform
Para usar Firebase, debes registrar cada variante de plataforma de tu app en el proyecto de Firebase. En este codelab, usarás una app real para probar lo que aprovisiones a través de Terraform y poder interactuar con él. Esta app es una app web, por lo que debes indicarle a Terraform que registre una app web de Firebase en el proyecto de Firebase que acabas de crear.
Agrega un bloqueo para registrar la app web
Para registrar la app web en tu proyecto de Firebase, agrega el archivo main.tf
con el siguiente bloque de recursos.
Debes especificar tu propio display_name
para tu aplicación web. Ten en cuenta que este nombre solo se usa dentro de las interfaces de Firebase y no es visible para los usuarios finales.
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"
}
Aplica la configuración
- Para aprovisionar el recurso nuevo, ejecuta el siguiente comando desde la raíz del mismo directorio en el que se encuentra el archivo
main.tf
(que debería serweb
).terraform apply
Ten en cuenta que este comando no volverá a crear un proyecto de Google Cloud nuevo. Terraform detectará que ya existe un proyecto con el ID del proyecto especificado, comparará el estado actual del proyecto con el contenido del archivo.tf
y realizará los cambios que encuentre. - Revisa el plan de acciones impreso. Si todo se ve como se espera, escribe
yes
y presiona Intro para aprobar las acciones.
Valida los cambios
Puedes inspeccionar el estado del recurso recién aprovisionado; para ello, ejecuta el siguiente comando:
terraform show
También puedes verificar que la app se haya registrado correctamente en tu proyecto. Para ello, ve a Firebase console. Ve a Configuración del proyecto y, luego, desplázate hacia abajo hasta la sección Tus apps.
6. Configura Firebase Authentication
La autenticación es una parte importante de cualquier app. Para permitir que los usuarios finales accedan a tu app web con sus Cuentas de Google, puedes habilitar Firebase Authentication y configurar el método de acceso con Google.
Ten en cuenta que, en este codelab, proporcionamos dos opciones diferentes para configurar Firebase Authentication:
- Opción 1 (recomendada): Configura Firebase Authentication en la consola, que no requiere GCIP.
- Usar esta opción significa que no tienes que asociar tu proyecto nuevo con una cuenta de Facturación de Cloud.
- Opción 2: Configura Firebase Authentication mediante Terraform con las APIs de Google Cloud Identity Platform (GCIP).
- Si usas esta opción, deberás asociar el proyecto nuevo con una cuenta de Facturación de Cloud, ya que GCIP requiere que el proyecto tenga el plan de precios Blaze.
Opción 1: Configura Authentication con Firebase console
Para configurar Firebase Authentication con Firebase console, no es necesario que tu proyecto tenga el plan de precios Blaze.
Aquí te mostramos cómo configurar Firebase Authentication y acceder con Google:
- En Firebase console, busca la sección Compilación en el panel izquierdo.
- Haz clic en Authentication, en Get started y, por último, en la pestaña Sign-in method (o haz clic aquí para ir directamente allí).
- Haz clic en Agregar proveedor nuevo y, en la sección Proveedores adicionales, selecciona Google.
- Activa el botón de activación Habilitar.
- Configura el nombre público de tu app con un valor como
FriendlyChat
(no es necesario que sea único a nivel global). - Elige un Correo electrónico de asistencia del proyecto en el menú desplegable y, luego, haz clic en Guardar.
- Deberías ver a Google como un proveedor de acceso habilitado.
Opción 2: Configura la autenticación mediante Terraform con las APIs de Google Cloud Identity Platform (GCIP)
Para configurar Firebase Authentication mediante Terraform, debes usar las APIs de GCIP, lo que significa que el proyecto debe tener el plan de precios Blaze. Asocia una cuenta de Facturación de Cloud al proyecto para actualizar tu proyecto de Firebase y poder usar el plan Blaze.
Habilita la facturación mediante Terraform
- Si todavía no tienes una cuenta de Facturación de Cloud, el primer paso es crear una cuenta nueva en la consola de Google Cloud. Cuando lo hagas, toma nota del ID de la cuenta de facturación. Puedes encontrar el ID de la cuenta de facturación en la página Facturación, en el ID de la cuenta de facturación asociado a tu proyecto.
- Para habilitar la facturación en tu proyecto mediante Terraform, agrega un atributo
billing_account
al recursogoogle_project
existente en tu archivomain.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" } } ...
Habilita Firebase Authentication y accede con Google mediante Terraform
- Para aprovisionar Firebase Authentication con GCIP, agrega tu archivo
main.tf
con los siguientes bloques 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 habilitar el acceso con Google, es necesario tener un cliente de OAuth. Ve a la sección APIs y servicios de la consola de Google Cloud para realizar esta configuración.
- Dado que es la primera vez que creas un ID de cliente para este proyecto, debes configurar tu pantalla de consentimiento de OAuth.
- Abre la página Pantalla de consentimiento de OAuth y, luego, selecciona el proyecto que acabas de crear.
- Configura el Tipo de usuario como Externo y, luego, haz clic en Crear.
- En la siguiente pantalla, completa lo siguiente y, luego, haz clic en Save and continue.
- Configura el Nombre de la app para el público con un nombre como
FriendlyChat
(no es necesario que sea único a nivel global). - Elige un Correo electrónico de asistencia al usuario en el menú desplegable.
- Ingresa un correo electrónico para la información de contacto del desarrollador.
- Configura el Nombre de la app para el público con un nombre como
- En las próximas pantallas, completa lo siguiente:
- Acepta la configuración predeterminada en la página Permisos y, luego, haz clic en Guardar y continuar.
- Acepta los valores predeterminados en la página Usuarios de prueba y, luego, haz clic en Guardar y continuar.
- Revisa el resumen y, luego, haz clic en Volver al panel.
- Para configurar un cliente de OAuth en la página Credenciales, haz lo siguiente:
- Haz clic en Crear credenciales y, luego, selecciona ID de cliente OAuth.
- En el menú desplegable Tipo de aplicación, selecciona Aplicación web.
- En el campo Nombre, ingresa el nombre de tu app, por ejemplo,
FriendlyChat
(no es necesario que sea único a nivel global). - Para permitir que la URL de tu app use este cliente de OAuth, configura lo siguiente:
- En Orígenes autorizados de JavaScript, haz clic en Agregar URI y, luego, ingresa
https://<PROJECT_ID>.firebaseapp.com
, donde<PROJECT_ID>
es el ID del proyecto que configuraste enmain.tf
. - En URI de redireccionamiento autorizados, haz clic en Agregar URI y, luego, ingresa
https://<PROJECT_ID>.firebaseapp.com/__/auth/handler
, en el que<PROJECT_ID>
es el ID del proyecto que configuraste enmain.tf
.
- En Orígenes autorizados de JavaScript, haz clic en Agregar URI y, luego, ingresa
- Haz clic en Guardar.
- Para habilitar el acceso con Google a través del secreto de cliente y el ID de cliente de OAuth, agrega el archivo
main.tf
con el siguiente bloque:
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 ] }
Aplica la configuración
- Para configurar Authentication según tu configuración, ejecuta los siguientes comandos desde la raíz del mismo directorio en el que está tu archivo
main.tf
(que debería serweb
):export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
terraform apply
Ten en cuenta que ejecutarterraform apply
no volverá a crear un proyecto de Google Cloud nuevo. Terraform detectará que ya existe un proyecto con el ID del proyecto especificado y comparará el estado actual del proyecto con el contenido del archivo.tf
. Luego, realizará los cambios que encuentre. - Revisa el plan de acciones impreso. Si todo se ve como se espera, escribe
yes
y presiona Intro para aprobar las acciones.
Valida los cambios
- En Firebase console, busca la sección Compilación en el panel izquierdo.
- Haz clic en Authentication y, luego, en la pestaña Sign-in method (o haz clic aquí para ir directamente allí).
- Deberías ver a Google como un proveedor de acceso habilitado.
7. Configura una base de datos de Firestore y sus reglas de seguridad
En la app web de este codelab, almacenarás mensajes entre los usuarios finales en una base de datos de Firestore.
- Para habilitar las APIs necesarias y aprovisionar la instancia de base de datos, agrega tu archivo
main.tf
con los siguientes bloques 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 ] }
- Cambia
<NAME_OF_DESIRED_REGION>
a la región en la que quieres que resida la base de datos.
Cuando desarrolles una app de producción, lo ideal es que esté en una región cercana a la mayoría de los usuarios y que sea común con otros servicios de Firebase, como Cloud Functions. En este codelab, puedes usarus-east1
(Carolina del Sur) o la región más cercana a ti (consulta Ubicaciones de Cloud Firestore). - Cada instancia de base de datos de Firestore a la que Firebase puede acceder debe estar protegida por las reglas de seguridad de Firebase.
El código de muestra de este codelab proporciona un conjunto de reglas seguras de Firestore en el archivofirestore.rules
, que puedes encontrar en la raíz del directorioweb
. - Agrega tu archivo
main.tf
con los siguientes bloques de recursos para hacer lo siguiente:- Crea un conjunto de reglas de las reglas de seguridad de Firebase desde el archivo local
firestore.rules
. - Libera el conjunto de reglas para la instancia de 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 ] } }
- Crea un conjunto de reglas de las reglas de seguridad de Firebase desde el archivo local
- Ejecuta
terraform apply
para aprovisionar la base de datos de Firestore y, luego, implementar sus reglas de seguridad. - Verifica que la base de datos esté aprovisionada y que las reglas de seguridad estén implementadas:
- En Firebase console, busca la sección Compilación en el panel izquierdo.
- Ve a la sección Base de datos de Firestore y, luego, haz clic en la pestaña Reglas.
8. Configura un bucket de Cloud Storage y sus reglas de seguridad
En la app web de este codelab, almacenarás imágenes compartidas entre usuarios finales en un bucket de Cloud Storage.
- Para habilitar las APIs necesarias y aprovisionar tu bucket predeterminado de Cloud Storage, agrega los siguientes bloques de recursos a tu archivo
main.tf
.
Ten en cuenta que el bucket predeterminado de Cloud Storage de tu proyecto se aprovisiona a través de Google App Engine y debe tener la misma ubicación que tu base de datos de Firestore. Consulta Ubicaciones de App Engine para obtener más información.
Si quieres tener varios buckets en tu proyecto, aprovisiona los buckets con el recursogoogle_storage_bucket
(que no se muestra en este 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 }
- Cada bucket de Cloud Storage al que puede acceder Firebase debe estar protegido por las reglas de seguridad de Firebase.
El código de muestra de este codelab proporciona un conjunto de reglas seguras de Firestore en el archivostorage.rules
, que puedes encontrar en la raíz del directorioweb
. - Agrega tu archivo
main.tf
con los siguientes bloques de recursos para hacer lo siguiente:- Crea un conjunto de reglas de las reglas de seguridad de Firebase desde el archivo local.
- Libera el conjunto de reglas del bucket de 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 ] } }
- Ejecuta
terraform apply
para aprovisionar el bucket predeterminado de Cloud Storage y, luego, implementar sus reglas de seguridad. - Verifica que el bucket esté aprovisionado y que las reglas de seguridad estén implementadas:
- En Firebase console, busca la sección Compilación en el panel izquierdo.
- Ve a la sección Almacenamiento y, luego, haz clic en la pestaña Reglas.
9. Ejecuta tu app de manera local
Ya está todo listo para que ejecutes tu app web por primera vez. Usarás el emulador de Firebase Hosting para entregar la app de forma local.
- Abre una nueva ventana de terminal y, desde el directorio
web
, ejecuta el siguiente comando de Firebase CLI para iniciar el emulador:firebase emulators:start --project=<PROJECT_ID>
- En el navegador, abre la aplicación web en la URL local que muestra la CLI (por lo general,
http://localhost:5000
).
Deberías ver la IU de tu app de FriendlyChat, que aún no está funcionando. La app aún no está conectada a Firebase, pero cuando completes los próximos pasos de este codelab, podrás hacerlo.
Ten en cuenta que, cada vez que realices cambios en tu app web (como lo harás en los siguientes pasos de este codelab), actualiza el navegador para actualizar la URL local con esos cambios.
10. Instala, configura e inicializa Firebase
Para que una app funcione con Firebase, tu app necesita el SDK de Firebase y la configuración de Firebase de tu proyecto de Firebase.
El código de muestra de este codelab ya es una app funcional con todas las dependencias y las funciones necesarias para usar varios productos de Firebase en la app. Puedes buscar en web/package.json
y web/src/index.js
si deseas ver lo que ya se hizo.
A pesar de que el código de muestra está casi completo, debes realizar algunas acciones para ejecutar tu app, como instalar el SDK de Firebase, comenzar tu compilación, agregar la configuración de Firebase a tu app e inicializar Firebase.
Instala el SDK de Firebase y comienza la compilación de tu webpack
Debes ejecutar algunos comandos para iniciar la compilación de tu app.
- Abre una nueva ventana de terminal.
- Asegúrate de estar en la raíz del directorio
web
. - Ejecuta
npm install
para descargar el SDK de Firebase. - Ejecuta
npm update
para actualizar las dependencias. - Ejecuta
npm run start
para iniciar Webpack.
Para el resto del codelab, webpack volverá a compilar tu código fuente de forma continua.
Agrega la configuración de Firebase a la app
También debes agregar la configuración de Firebase a la app para que los SDK de Firebase sepan qué proyecto de Firebase quieres que usen.
En este codelab, tienes dos opciones diferentes para obtener tu configuración de Firebase:
- Opción 1: Obtén la configuración de Firebase en Firebase console.
- Opción 2: Obtén la configuración de Firebase a través de Terraform.
Opción 1: Obtén la configuración de Firebase console y agrégala a tu base de código
- En Firebase console, ve a Configuración del proyecto.
- Desplázate hacia abajo hasta la tarjeta Tus apps y, luego, selecciona tu aplicación web.
- Selecciona Config en el panel de fragmentos del SDK de Firebase y, luego, copia el fragmento de configuración.
- Pega la configuración en el archivo
web/src/firebase-config.js
de tu app de la siguiente manera:
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>", }; ...
Opción 2: Obtén la configuración a través de Terraform y agrégala a tu base de código
De forma alternativa, puedes obtener la configuración de Firebase a través de Terraform como un valor de salida en la CLI.
- En el archivo
main.tf
, busca tu bloque de recursosgoogle_firebase_web_app
(el bloque que registró una app web con tu proyecto). - Inmediatamente después de ese bloque, agrega los siguientes bloques:
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", "") } } ...
- Dado que los bloques
data
youtput
no están diseñados para modificar la infraestructura de ninguna manera, solo debes ejecutar los siguientes comandos.- Para cargar la configuración de Firebase de tu aplicación web en el estado de Terraform de tu directorio, ejecuta este comando:
terraform refresh
- Para imprimir los valores de configuración de Firebase, ejecuta este comando:
terraform output –json
El siguiente es un resultado de ejemplo de una configuración. El resultado impreso contendrá los valores de tu proyecto y app.{ "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 cargar la configuración de Firebase de tu aplicación web en el estado de Terraform de tu directorio, ejecuta este comando:
- Copia los valores del mapa
value
. - Pega estos valores (tu configuración) en el archivo
web/src/firebase-config.js
de tu app, de esta manera:
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", }; ...
Inicializa Firebase en la app
Por último, para inicializar Firebase, agrega el archivo web/src/index.js
de tu app con lo siguiente:
...
const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);
Prueba tu app
Ahora que todo está configurado para Firebase, puedes probar tu app web funcional.
- Actualiza el navegador que entrega tu app.
- Ahora deberías poder acceder con Google y comenzar a publicar mensajes en el chat. Si tienes archivos de imagen, incluso puedes subirlos.
11. Replica tu configuración en todos los entornos
Terraform se destaca por administrar varias infraestructuras configuradas de forma similar (por ejemplo, configurar un proyecto de Firebase de etapa de pruebas similar a un proyecto de producción).
En este codelab, crearás un segundo proyecto de Firebase para que sea un entorno de etapa de pruebas.
Si quieres replicar una configuración existente para crear este proyecto de etapa de pruebas, tienes dos opciones:
- Opción 1: Haz una copia de la configuración de Terraform.
Esta opción ofrece la mayor flexibilidad en cuanto a la diferencia entre el proyecto replicado y el proyecto de origen. - Opción 2: Vuelve a usar la configuración con
for_each
.
Esta opción ofrece más reutilización del código en caso de que cada proyecto no deba diferir de manera significativa y deseas propagar los cambios a todos los proyectos a la vez.
Opción 1: Crea una copia de la configuración de Terraform
Esta opción ofrece la mayor flexibilidad en cuanto a la diferencia que puede diferir el proyecto replicado del proyecto de origen; por ejemplo, tener apps con diferentes nombres visibles y lanzamientos en etapas.
- En la raíz de tu directorio
web
, crea un nuevo archivo de configuración de Terraform llamadomain_staging.tf
. - Copia todos los bloques de recursos de tu archivo
main.tf
(excepto los bloquesterraform
yprovider
) y, luego, pégalos en el archivomain_staging.tf
. - Luego, debes modificar cada uno de los bloques de recursos replicados en
main_staging.tf
para que funcionen con el proyecto de etapa de pruebas:- Etiquetas de recursos: Usa un nombre nuevo para evitar conflictos. Por ejemplo, cambia el nombre de
resource "google_project" "default"
aresource "google_project" "staging"
. - Referencias de recursos: Actualiza cada una. Por ejemplo, actualiza
google_firebase_project.default.project
agoogle_firebase_project.staging.project
.
main_staging.tf
en el repositorio de GitHub de este codelab:web/terraform-checkpoints/replicate-config/main_staging-copypaste.tf
Si deseas usar esta configuración, asegúrate de hacer lo siguiente:- Copia la configuración de
main_staging-copypaste.tf
y, luego, pégala en el archivomain_staging.tf
. - En tu archivo
main_staging.tf
, haz lo siguiente:- En el bloque de recursos
google_project
, actualiza el atributoname
, el atributoproject-id
y (si configuras la autenticación a través de Terraform) el atributobilling_account
con tus propios valores. - En el bloque de recursos
google_firebase_web_app
, actualiza el atributodisplay_name
con tu propio valor. - En los bloques de recursos
google_firestore_database
ygoogle_app_engine_application
, actualiza los atributoslocation_id
con tu propio valor.
- En el bloque 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" }
- Etiquetas de recursos: Usa un nombre nuevo para evitar conflictos. Por ejemplo, cambia el nombre de
- Ejecuta
terraform apply
para aprovisionar tu nuevo proyecto de “etapa de pruebas” de Firebase y todos sus recursos, y habilitar sus servicios. - Verifica que todo se haya aprovisionado y habilitado como se esperaba. Para ello, revísalo en Firebase console como antes.
Opción 2: Vuelve a usar la configuración con for_each
Esta opción ofrece más reutilización del código si cada proyecto no debe diferir de manera significativa y deseas propagar los cambios a todos los proyectos a la vez. Usa el metaargumento for_each
en el lenguaje de Terraform.
- Abre el archivo
main.tf
. - En cada bloque de recursos que desees replicar, agrega un metaargumento
for_each
de la siguiente manera:
main.tf
Puedes encontrar la configuración completa de un archivo# 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 el metaargumentofor_each
en el repositorio de GitHub de este codelab:web/terraform-checkpoints/replicate-config/main-foreach.tf
Si deseas usar esta configuración, asegúrate de hacer lo siguiente:- Copia la configuración de
main-foreach.tf
y, luego, pégala en el archivomain.tf
. - En tu archivo
main.tf
, haz lo siguiente:- En el bloque de recursos
google_project
, actualiza el atributoname
, el atributoproject-id
y (si configuras la autenticación a través de Terraform) el atributobilling_account
con tus propios valores. - En el bloque de recursos
google_firebase_web_app
, actualiza el atributodisplay_name
con tu propio valor. - En los bloques de recursos
google_firestore_database
ygoogle_app_engine_application
, actualiza los atributoslocation_id
con tu propio valor.
- En el bloque de recursos
- Copia la configuración de
- En lugar de aplicar esta configuración de inmediato, es importante comprender y corregir algunos aspectos sobre la forma en que Terraform interpreta esta configuración en comparación con la infraestructura existente.
- En este momento, si aplicaste esta configuración que usa
for_each
, las direcciones de recursos se verían de la siguiente manera:
Sin embargo, Terraform conoce el proyecto existente que creaste en la primera parte de este codelab de la siguiente manera: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
- Ejecuta
terraform plan
para ver qué acciones realizaría Terraform según el estado actual.
El resultado debería mostrar que Terraform borraría el proyecto que creaste en la primera parte de este codelab y crearía dos proyectos nuevos. Esto se debe a que Terraform no sabe que el proyecto en la direccióngoogle_project.default
se movió a la nueva direccióngoogle_project.default["prod"]
. - Para solucionar este problema, ejecuta el comando
terraform state mv
:terraform state mv "google_project.default" "google_project.default[\"prod\"]"
- De manera similar, para corregir todos los demás bloques de recursos, ejecuta
terraform state mv
paragoogle_firebase_project
,google_firebase_web_app
y todos los demás bloques de recursos de tu archivomain.tf
. - Ahora, si vuelves a ejecutar
terraform plan
, no debería mostrar que Terraform borraría el proyecto que creaste en la primera parte de este codelab.
- En este momento, si aplicaste esta configuración que usa
- Ejecuta
terraform apply
para aprovisionar tu nuevo proyecto de “etapa de pruebas” de Firebase y todos sus recursos, y habilitar sus servicios. - Verifica que todo se haya aprovisionado y habilitado como se esperaba. Para ello, revísalo en Firebase console como antes.
12. Paso adicional: Implementa tus apps de etapa de pruebas y producción
- En la base de código de tu app, cambia el
firebase-config.js
para usar la configuración de Firebase de tu proyecto de etapa de pruebas.
Para recordar cómo obtener la configuración de Firebase y agregarla a tu app, consulta el paso anterior de este codelab: Agrega la configuración de Firebase a tu app. - En la raíz del directorio
web
, ejecuta el siguiente comando para implementar tu app en el proyecto de etapa de pruebas de Firebase.firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
- Abre la app de etapa de pruebas en el navegador a través de la URL que se imprime en el resultado de
firebase deploy
. Intenta acceder, enviar mensajes y subir imágenes.
Cuando implementas una app en un proyecto de Firebase, esta usa recursos reales de Firebase, no recursos emulados. Cuando interactúes con la app de etapa de pruebas, deberías ver que los datos y las imágenes aparecen en el proyecto de etapa de pruebas en Firebase console. - Después de probar tu app en la etapa de pruebas, vuelve a cambiar el
firebase-config.js
a la configuración de Firebase del proyecto de producción (el primer proyecto que creaste en este codelab). - En la raíz del directorio
web
, ejecuta el siguiente comando para implementar la app en tu proyecto de producción de Firebase.firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
- Abre la app de producción en el navegador a través de la URL que está impresa en el resultado de
firebase deploy
. Intenta acceder, enviar mensajes y subir imágenes.
Deberías ver que los datos y las imágenes aparecen en tu proyecto de producción en Firebase console. - Cuando termines de interactuar con las dos apps de este codelab, puedes evitar que Firebase las entregue. Ejecuta el siguiente comando para cada uno de tus proyectos:
firebase hosting:disable --project=<STAGING_PROJECT_ID>
firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
13. ¡Felicitaciones!
Utilizaste Terraform para configurar una aplicación web de chat en tiempo real. Además, seguiste las prácticas recomendadas para los entornos de desarrollo con la creación de proyectos de Firebase independientes para etapa de pruebas y producción.
Temas abordados
- Usa la CLI de Terraform para administrar los recursos de la nube
- Usar Terraform para configurar los productos de Firebase (Authentication, Firestore, Cloud Storage y reglas de seguridad)
- Ejecuta y prueba una aplicación web de forma local con Firebase Local Emulator Suite
- Importa Firebase a una app web
- Usar Terraform para replicar una configuración en varios entornos
Para obtener más información sobre Firebase y Terraform, visita nuestra documentación. Puedes encontrar una lista de todos los productos de Firebase compatibles con Terraform, muestras de configuraciones de Terraform para casos de uso comunes y preguntas frecuentes y soluciones de problemas útiles.