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 primer lugar, este codelab describe cómo compilar un archivo de configuración de Terraform para crear un proyecto nuevo de Firebase y, luego, cómo configurar las apps y los productos de Firebase que deseas usar en ese proyecto. También abarcamos los conceptos básicos de la línea de comandos de Terraform, como obtener una vista previa de los cambios que se realizarán y, luego, implementarlos.
Si querías aprender a configurar y administrar proyectos y productos de Firebase con Terraform, este codelab es para ti.
Qué aprenderás
- 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 tus recursos y servicios
- Cómo aplicar tu configuración en una app web real (llamada Friendly Chat)
- Cómo definir parámetros de configuración paralelos (y sincronizados) en diferentes entornos (producción, etapa de pruebas, etc.)
Requisitos
- Una terminal o consola
- El IDE o editor de texto que prefieras, como WebStorm, Atom, Sublime o VS Code
- El navegador que elijas, como Chrome
- Google Cloud CLI (CLI de gcloud): Instala esta CLI y accede con una cuenta de usuario o una cuenta de servicio.
Para completar este codelab, debes tener conocimientos básicos de Terraform y su terminología, incluidos los siguientes requisitos previos:
- Instala Terraform y familiarízate con él a través de sus instructivos oficiales.
En este codelab, se proporciona una app de ejemplo real para que puedas probar y usar lo que aprovisionas a través de Terraform. Para ello, necesitarás lo siguiente:
- El código de muestra de una app web (descarga este código en el siguiente paso del codelab)
- El administrador de paquetes npm (que, por lo general, se incluye con Node.js): Instala estas herramientas.
- Firebase CLI: Instala esta CLI y accede a tu cuenta.
2. Obtén el código de partida
En este codelab, puedes probar lo que aprovisionas a través de Terraform con una app web real. Te recomendamos que lo hagas para 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
También tienes la opción de descargar el repositorio como archivo ZIP si no tienes instalado git.
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 a 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á la cuota 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 que tu proyecto acepte verificaciones de cuotas, primero debes usar user_project_override=false
. La sintaxis de alias
de Terraform te permite distinguir entre las dos configuraciones del proveedor en los próximos pasos de este codelab.
Inicializa Terraform en el directorio
Crear una configuración nueva por primera vez requiere 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 tu archivo de configuración main.tf
:
terraform init
4. Crea un proyecto de Firebase a través de 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 con los servicios de Firebase habilitados.
Agrega bloques para el proyecto y las APIs subyacentes de Google Cloud
- Primero, aprovisiona el proyecto subyacente de Google Cloud.
Agrega el siguiente bloque de recursos a tu archivo de configuraciónmain.tf
.
Debes especificar tu propio nombre de proyecto (como"Terraform FriendlyChat Codelab"
) y tu propio ID de proyecto (como"terraform-codelab-your-initials"
). Ten en cuenta que el valor dename
solo se usa dentro de las interfaces de Firebase y no es visible para los usuarios finales. Sin embargo, el valor deproject_id
identifica de forma única tu proyecto 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, esta habilitación de la API se controla en segundo plano cuando usas Firebase console para crear un proyecto de Firebase, pero se le debe indicar explícitamente a Terraform que realice esta habilitación.
En tu archivo de configuración demain.tf
(justo debajo del bloque que crea el nuevo proyecto de Cloud), agrega el siguiente bloque de recursos:
main.tf Si habilitas la API de Service Usage, tu proyecto nuevo podrá aceptar verificaciones de cuota. Por lo tanto, para todos los aprovisionamientos de recursos y habilitaciones 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
(no se necesita alias).
Agrega un bloque para habilitar los servicios de Firebase
Lo último que se requiere para "crear un proyecto de Firebase" es habilitar los servicios de Firebase en el proyecto.
En tu 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 observes 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 tener errores cuando aprovisiona recursos en paralelo.
Aplica la configuración
- Para aprovisionar los recursos nuevos y habilitar las APIs especificadas en el archivo de configuración, ejecuta el siguiente comando desde la raíz del mismo directorio que el archivo
main.tf
(que debería serweb
):terraform apply
- En la terminal, Terraform imprimirá un plan de acciones que realizará.
Si todo se ve como se espera, aprueba las acciones ingresandoyes
.
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
.
Valida los cambios
Una vez que Terraform termine de ejecutarse, puedes inspeccionar el estado de todos los recursos y servicios aprovisionados por Terraform habilitados ejecutando el siguiente comando:
terraform show
Este es un ejemplo de lo que deberías ver impreso. Tu estado contendrá valores específicos de 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 haya creado en Firebase console.
5. Registra tu app de Firebase a través de Terraform
Para usar Firebase, debes registrar cada variante de plataforma de tu app en tu proyecto de Firebase. En este codelab, usarás una app real para probar y, luego, interactuar con lo que aprovisiones a través de Terraform. Esta app es una app web, por lo que debes indicarle a Terraform que registre una app web de Firebase en tu proyecto de Firebase recién creado.
Agrega un bloque para registrar la app web
Para registrar tu app web en tu proyecto de Firebase, agrega el siguiente bloque de recursos a tu archivo main.tf
.
Debes especificar tu propio display_name
para tu app web. Ten en cuenta que este nombre solo se usa en 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 que el archivo
main.tf
(que debería serweb
). 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 especificado, comparará el estado actual del proyecto con lo que se encuentra en el archivoterraform apply
.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 aprovisionado recientemente ejecutando el siguiente comando:
terraform show
También puedes verificar que la app se haya registrado correctamente en tu proyecto. Para ello, mírala en 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.
- Si usas esta opción, no tienes que asociar tu proyecto nuevo a una cuenta de facturación de Cloud.
- Opción 2: Configura Firebase Authentication a través de Terraform con las APIs de Google Cloud Identity Platform (GCIP).
- Si usas esta opción, deberás asociar tu proyecto nuevo a una cuenta de Facturación de Cloud, ya que GCIP requiere que el proyecto tenga el plan de precios Blaze.
Opción 1: Configura la autenticación con Firebase console
Para configurar Firebase Authentication con Firebase console, tu proyecto no necesita tener el plan de precios Blaze.
Sigue estos pasos para configurar Firebase Authentication y acceder con Google:
- En Firebase console, busca la sección Compilación en el panel izquierdo.
- Haz clic en Authentication, luego 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.
- Establece el nombre público de tu app en algo 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 Google como proveedor de acceso habilitado.
Opción 2: Configura la autenticación a través de Terraform con las APIs de Google Cloud Identity Platform (GCIP)
Para configurar Firebase Authentication a través de Terraform, debes usar las APIs de GCIP, lo que significa que el proyecto debe estar en el plan de precios Blaze. Para actualizar tu proyecto de Firebase y usar el plan Blaze, asocia una cuenta de Facturación de Cloud al proyecto.
Habilita la facturación a través de Terraform
- Si aún no tienes una cuenta de Cloud Billing, el primer paso es crear una cuenta nueva en la consola de Google Cloud. Cuando lo hagas, anota su ID de cuenta de facturación. El ID de la cuenta de facturación se puede encontrar 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 a través de 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 el acceso con Google a través de Terraform
- Para aprovisionar Firebase Authentication con GCIP, agrega los siguientes bloques de recursos a tu archivo
main.tf
:
main.tf... # Enable the Identity Toolkit API. resource "google_project_service" "auth" { provider = google-beta project = google_firebase_project.default.project service = "identitytoolkit.googleapis.com" # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Create an Identity Platform config. # Also, enable Firebase Authentication using Identity Platform (if Authentication isn't yet enabled). resource "google_identity_platform_config" "auth" { provider = google-beta project = google_firebase_project.default.project # For example, you can configure to auto-delete anonymous users. autodelete_anonymous_users = true # Wait for identitytoolkit.googleapis.com to be enabled before initializing Authentication. depends_on = [ google_project_service.auth, ] }
- Para habilitar el acceso con Google, debes tener un cliente de OAuth. Para realizar esta configuración, ve a la sección APIs & Services de la consola de Google Cloud.
- 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 de la pantalla de consentimiento de OAuth y, luego, selecciona el proyecto que acabas de crear.
- Establece el Tipo de usuario en Externo y, luego, haz clic en Crear.
- En la siguiente pantalla, completa la información que se indica a continuación y, luego, haz clic en Guardar y continuar.
- Configura el Nombre de la app público de tu app 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 en la Información de contacto del desarrollador.
- Configura el Nombre de la app público de tu app como
- En las siguientes pantallas, completa lo siguiente:
- Acepta los valores predeterminados en la página Permisos y, luego, haz clic en Guardar y continuar.
- Acepta la configuración predeterminada 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, establece 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
, donde<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 de tu ID de cliente y secreto de cliente de OAuth, agrega el siguiente bloque a tu archivo
main.tf
:
main.tf... variable "oauth_client_secret" { type = string description = "OAuth client secret. For this codelab, you can pass in this secret through the environment variable TF_VAR_oauth_client_secret. In a real app, you should use a secret manager service." sensitive = true } resource "google_identity_platform_default_supported_idp_config" "google_sign_in" { provider = google-beta project = google_firebase_project.default.project enabled = true idp_id = "google.com" client_id = "<YOUR_OAUTH_CLIENT_ID>" client_secret = var.oauth_client_secret depends_on = [ google_identity_platform_config.auth ] }
Aplica la configuración
- Para configurar la autenticación según tu configuración, ejecuta los siguientes comandos desde la raíz del mismo directorio que tu archivo
main.tf
(que debería serweb
):export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
Ten en cuenta que ejecutarterraform apply
terraform apply
no volverá a crear un proyecto de Google Cloud nuevo. Terraform detectará que ya existe un proyecto con el ID especificado y comparará el estado actual del proyecto con lo que se encuentra en el 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 Google como 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 usuarios finales en una base de datos de Firestore.
- Para habilitar las APIs requeridas y aprovisionar la instancia de la base de datos, agrega los siguientes bloques de recursos a tu archivo
main.tf
:
main.tf... # Enable required APIs for Cloud Firestore. resource "google_project_service" "firestore" { provider = google-beta project = google_firebase_project.default.project for_each = toset([ "firestore.googleapis.com", "firebaserules.googleapis.com", ]) service = each.key # Don't disable the service if the resource block is removed by accident. disable_on_destroy = false } # Provision the Firestore database instance. resource "google_firestore_database" "default" { provider = google-beta project = google_firebase_project.default.project name = "(default)" # See available locations: # https://firebase.google.com/docs/firestore/locations location_id = "<NAME_OF_DESIRED_REGION>" # "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, # authentication, and Firebase Security Rules. type = "FIRESTORE_NATIVE" concurrency_mode = "OPTIMISTIC" depends_on = [ google_project_service.firestore ] }
- Cambia
<NAME_OF_DESIRED_REGION>
por la región en la que deseas que resida la base de datos.
Cuando desarrolles una app de producción, te convendrá 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). - Todas las instancias de bases de datos de Firestore a las que se puede acceder desde Firebase deben estar protegidas 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 los siguientes bloques de recursos a tu archivo
main.tf
para hacer lo siguiente:- Crea un conjunto de reglas de las reglas de seguridad de Firebase a partir del archivo
firestore.rules
local. - 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 a partir del archivo
- Ejecuta
terraform apply
para aprovisionar la base de datos de Firestore y, luego, implementa sus reglas de seguridad. - Verifica que la base de datos esté aprovisionada y que sus reglas de seguridad estén implementadas:
- En Firebase console, busca la sección Build en el panel izquierdo.
- Ve a la sección Firestore Database y, luego, haz clic en la pestaña Rules.
8. Configura un bucket de Cloud Storage y sus reglas de seguridad
En la app web de este codelab, almacenarás las imágenes que se comparten entre los usuarios finales en un bucket de Cloud Storage.
- Para habilitar las APIs requeridas 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 para 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, aprovisiónalos con el recursogoogle_storage_bucket
(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 }
- Todos los buckets de Cloud Storage a los que se puede acceder desde Firebase deben estar protegidos por las reglas de seguridad de Firebase.
El código de ejemplo 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 los siguientes bloques de recursos a tu archivo
main.tf
para hacer lo siguiente:- Crea un conjunto de reglas de las reglas de seguridad de Firebase a partir del archivo local.
- Publica el conjunto de reglas para el 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, implementa sus reglas de seguridad. - Verifica que el bucket esté aprovisionado y que sus reglas de seguridad estén implementadas:
- En Firebase console, busca la sección Compilación en el panel izquierdo.
- Ve a la sección Storage y, luego, haz clic en la pestaña Reglas.
9. Ejecuta tu app de forma local
Ya puedes ejecutar tu app web por primera vez. Usarás el emulador de Firebase Hosting para entregar tu app de forma local.
- Abre una ventana de terminal nueva y, desde el directorio
web
, ejecuta el siguiente comando de Firebase CLI para iniciar el emulador:firebase emulators:start --project=<PROJECT_ID>
- En tu navegador, abre tu 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á en funcionamiento. La app aún no está conectada a Firebase, pero, si completas los próximos pasos de este codelab, lo estará.
Ten en cuenta que, cada vez que realices cambios en tu app web (como lo harás en los siguientes pasos de este codelab), deberás actualizar el navegador para actualizar la URL local con esos cambios.
10. Instala, configura e inicializa Firebase
Para que una app funcione con Firebase, necesita el SDK de Firebase y la configuración de Firebase para tu proyecto de Firebase.
El código de muestra de este codelab ya es una app en funcionamiento con todas las dependencias y funciones necesarias para usar varios productos de Firebase en la app. Puedes consultar web/package.json
y web/src/index.js
si quieres ver lo que ya se hizo.
Aunque el código de muestra está casi completo, aún debes hacer algunas cosas para que se ejecute tu app, como instalar el SDK de Firebase, iniciar tu compilación, agregar la configuración de Firebase a tu app y, por último, inicializar Firebase.
Instala el SDK de Firebase y comienza la compilación de 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 ahora volverá a compilar tu código fuente de forma continua.
Agrega tu configuración de Firebase a la app
También debes agregar tu configuración de Firebase a la app para que los SDKs 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 desde Firebase console.
- Opción 2: Obtén tu 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 app web.
- Selecciona Config en el panel de fragmentos del SDK de Firebase y, luego, copia el fragmento de configuración.
- Pega tu 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
Como alternativa, puedes obtener tu configuración de Firebase a través de Terraform como un valor de salida en la CLI.
- En tu archivo
main.tf
, busca el bloque de recursosgoogle_firebase_web_app
(el bloque que registró una app web en tu proyecto). - Inmediatamente después de ese bloque, agrega los siguientes:
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 el bloque
data
y el bloqueoutput
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 app 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:
A continuación, se muestra un ejemplo del resultado de una configuración. El resultado impreso contendrá los valores de tu proyecto y tu 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 cargar la configuración de Firebase de tu app 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 la siguiente 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 lo siguiente al archivo web/src/index.js
de tu app:
...
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 ejecuta tu app.
- Ahora deberías poder acceder con Google y comenzar a publicar mensajes en el chat. Si tienes archivos de imágenes, incluso puedes subirlos.
11. Cómo replicar tu configuración en diferentes entornos
Terraform se destaca en la administración de varias infraestructuras configuradas de manera similar (por ejemplo, la configuración de un proyecto de Firebase de etapa de pruebas que es similar a un proyecto de producción).
En este codelab, crearás un segundo proyecto de Firebase que será un entorno de pruebas.
Para replicar una configuración existente y 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 que puede haber entre el proyecto replicado y el proyecto de origen. - Opción 2: Reutiliza la configuración con
for_each
.
Esta opción ofrece más reutilización de código si cada proyecto no debe diferir de manera significativa y deseas propagar los cambios a todos los proyectos a la vez.
Opción 1: Haz una copia de la configuración de Terraform
Esta opción ofrece la mayor flexibilidad en cuanto a la diferencia que puede haber entre el proyecto replicado y el proyecto fuente, como tener apps con diferentes nombres visibles y lanzamientos en etapas.
- En la raíz de tu directorio
web
, crea un archivo de configuración de Terraform nuevo llamadomain_staging.tf
. - Copia todos los bloques de recursos de tu archivo
main.tf
(excepto los bloquesterraform
yprovider
) y, luego, pégalos en tu archivomain_staging.tf
. - Luego, debes modificar cada uno de los bloques de recursos replicados en
main_staging.tf
para que funcionen con tu 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 quieres usar esta configuración, asegúrate de hacer lo siguiente:- Copia la configuración de
main_staging-copypaste.tf
y, luego, pégala en tu 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 configuraste 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 Firebase de "etapa de pruebas", todos sus recursos y habilitar sus servicios. - Verifica que todo se haya aprovisionado y habilitado según lo esperado. Para ello, revísalo en Firebase console como antes.
Opción 2: Reutiliza la configuración con for_each
Esta opción ofrece más reutilización de código si cada proyecto no debe diferir de manera significativa y deseas propagar los cambios a todos los proyectos a la vez. Utiliza el metaargumento for_each
en el lenguaje de Terraform.
- Abre el archivo
main.tf
. - En cada bloque de recursos que quieras 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 tu 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 configuraste 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 cómo 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 como lo siguiente: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 corregir este problema, ejecuta el comando
terraform state mv
:terraform state mv "google_project.default" "google_project.default[\"prod\"]"
- Del mismo modo, 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 en 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 Firebase de "etapa de pruebas", todos sus recursos y habilitar sus servicios. - Verifica que todo se haya aprovisionado y habilitado según lo esperado. Para ello, revísalo en Firebase console como antes.
12. Paso adicional: Implementa tus apps de producción y de etapa de pruebas
- En la base de código de tu app, cambia
firebase-config.js
para que use la configuración de Firebase de tu proyecto de etapa de pruebas.
Para recordar cómo obtener tu configuración de Firebase y agregarla a tu app, consulta el paso anterior de este codelab, Agrega tu configuración de Firebase a tu app. - En la raíz de tu directorio
web
, ejecuta el siguiente comando para implementar tu app en tu proyecto de Firebase de etapa de pruebas.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 imprimió 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. A medida que interactúas con tu app de etapa de pruebas, deberías ver que aparecen datos e imágenes en tu proyecto de etapa de pruebas en Firebase console. - Después de probar tu app en la etapa de pruebas, vuelve a cambiar
firebase-config.js
para que use la configuración de Firebase del proyecto de producción (el primer proyecto que creaste en este codelab). - En la raíz de tu directorio
web
, ejecuta el siguiente comando para implementar tu 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 se imprimió en el resultado de
firebase deploy
. Intenta acceder, enviar mensajes y subir imágenes.
Deberías ver datos e imágenes en tu proyecto de producción en Firebase console. - Cuando termines de interactuar con las dos apps para este codelab, puedes detener la publicación de Firebase. 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!
Usaste Terraform para configurar una aplicación web de chat en tiempo real. Además, seguiste las prácticas recomendadas para los entornos de desarrollo creando proyectos de Firebase independientes para la etapa de pruebas y la producción.
Temas abordados
- Usa la CLI de Terraform para administrar recursos de la nube
- Usa Terraform para configurar productos de Firebase (Authentication, Firestore, Cloud Storage y reglas de seguridad)
- Cómo ejecutar y probar una app web de forma local con Firebase Local Emulator Suite
- Cómo importar Firebase a una aplicación web
- Usa Terraform para replicar una configuración en varios entornos
Para obtener más información sobre Firebase y Terraform, consulta 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.