1. Introduction
Objectifs
Vous pouvez utiliser Terraform pour configurer et gérer un projet Firebase, y compris la configuration programmatique de l'infrastructure et des produits Firebase.
Cet atelier de programmation explique d'abord comment créer un fichier de configuration Terraform pour créer un projet Firebase, puis comment configurer les applications et les produits Firebase que vous souhaitez utiliser dans ce projet. Nous aborderons également les bases de la ligne de commande Terraform, comme la prévisualisation des modifications à apporter et leur implémentation.
Si vous avez toujours voulu apprendre à configurer et à gérer des projets et des produits Firebase avec Terraform, cet atelier de programmation est fait pour vous.
Points abordés
- Créer un fichier de configuration Terraform (
*.tf
) - Utiliser les commandes de la CLI Terraform pour gérer votre infrastructure
- Modifier votre configuration pour mettre à jour vos ressources et services
- Appliquer votre configuration à une application Web réelle (appelée Friendly Chat)
- Définir des configurations parallèles (et synchronisées) dans différents environnements (production, préproduction, etc.)
Prérequis
- Un terminal/une console
- L'IDE/éditeur de texte de votre choix, tel que WebStorm, Atom, Sublime ou VS Code
- Le navigateur de votre choix, tel que Chrome
- Google Cloud CLI (gcloud CLI) : installez cette CLI et connectez-vous à l'aide d'un compte utilisateur ou d'un compte de service.
Pour réussir cet atelier de programmation, vous devez maîtriser les bases de Terraform et de sa terminologie, y compris les prérequis suivants :
- Installez Terraform et familiarisez-vous avec Terraform en suivant les tutoriels officiels.
Cet atelier de programmation fournit un exemple d'application réel pour que vous puissiez tester et interagir avec ce que vous provisionnez via Terraform. Pour ce faire, vous aurez besoin des éléments suivants :
- Exemple de code pour une application Web : téléchargez ce code à la prochaine étape de l'atelier de programmation.
- Le gestionnaire de packages npm (généralement fourni avec Node.js) : installez ces outils.
- La CLI Firebase : installez cette CLI et connectez-vous.
2. Obtenir le code de démarrage
Dans cet atelier de programmation, vous pouvez tester ce que vous provisionnez via Terraform avec une véritable application Web. Nous vous recommandons de le faire pour comprendre toutes les étapes nécessaires à l'utilisation des ressources provisionnées par Terraform.
Clonez le dépôt GitHub de l'atelier de programmation à partir de la ligne de commande :
git clone https://github.com/firebase/codelab-friendlychat-web
Si vous n'avez pas installé git, vous pouvez également télécharger le dépôt sous forme de fichier ZIP.
3. Créer une configuration Terraform
Configurer Terraform
- Dans le code source de l'exemple d'application téléchargé, accédez à la racine du répertoire
web
. - À la racine de ce répertoire, créez un fichier de configuration Terraform appelé
main.tf
avec la configuration initiale suivante :
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 }
Chacun des fournisseurs google-beta
possède un attribut nommé user_project_override
qui détermine la façon dont les opérations de Terraform seront vérifiées par rapport au quota. Pour provisionner la plupart des ressources, vous devez utiliser user_project_override = true
, ce qui signifie vérifier le quota par rapport à votre propre projet Firebase. Toutefois, pour configurer votre nouveau projet afin qu'il puisse accepter les vérifications de quota, vous devez d'abord utiliser user_project_override=false
. La syntaxe alias
de Terraform vous permet de faire la distinction entre les deux configurations de fournisseur dans les prochaines étapes de cet atelier de programmation.
Initialiser Terraform dans le répertoire
Pour créer une configuration pour la première fois, vous devez télécharger le fournisseur spécifié dans la configuration.
Pour effectuer cette initialisation, exécutez la commande suivante à partir de la racine du même répertoire que votre fichier de configuration main.tf
:
terraform init
4. Créer un projet Firebase avec Terraform
Pour "créer un projet Firebase", il est important de se rappeler que chaque projet Firebase est en fait un projet Google Cloud, mais avec les services Firebase activés.
Ajouter des blocs pour le projet et les API Google Cloud sous-jacents
- Commencez par provisionner le projet Google Cloud sous-jacent.
Ajoutez le bloc de ressources suivant à votre fichier de configurationmain.tf
.
Vous devez spécifier votre propre nom de projet (comme"Terraform FriendlyChat Codelab"
) et votre propre ID de projet (comme"terraform-codelab-your-initials"
). Notez que la valeurname
n'est utilisée que dans les interfaces Firebase et n'est pas visible par les utilisateurs finaux. Toutefois, la valeurproject_id
identifie de manière unique votre projet auprès de Google. Veillez donc à spécifier une valeur unique. 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" } }
- Vous devez ensuite activer les API sous-jacentes requises : l'API Service Usage et l'API Firebase Management.
Cette activation d'API est généralement gérée en arrière-plan lorsque vous utilisez la console Firebase pour créer un projet Firebase, mais Terraform doit être explicitement informé de cette activation.
Dans votre fichier de configurationmain.tf
(juste en dessous du bloc qui crée le nouveau projet Cloud), ajoutez le bloc de ressources suivant :
main.tf En activant l'API Service Usage, votre nouveau projet pourra accepter les vérifications de quota. Par conséquent, pour tous les provisionnements de ressources et les activations de services ultérieurs, vous devez utiliser le fournisseur avec... # 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
(aucun alias n'est nécessaire).
Ajouter un bloc pour activer les services Firebase
La toute dernière chose à faire pour "créer un projet Firebase " est d'activer les services Firebase dans le projet.
Dans votre fichier de configuration main.tf
, ajoutez le bloc de ressources suivant.
Comme indiqué ci-dessus, notez que ce bloc de ressources utilise le fournisseur with user_project_override
(aucun alias n'est nécessaire).
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,
]
}
Dans le bloc de ressources ci-dessus, vous remarquerez peut-être la clause depends_on
, qui indique à Terraform d'attendre que les API sous-jacentes soient activées. Sans cette clause, Terraform ne connaît pas la dépendance et peut rencontrer des erreurs lors du provisionnement des ressources en parallèle.
Appliquer la configuration
- Pour provisionner les nouvelles ressources et activer les API spécifiées dans votre fichier de configuration, exécutez la commande suivante à partir de la racine du même répertoire que votre fichier
main.tf
(qui doit êtreweb
) :terraform apply
- Dans le terminal, Terraform affiche un plan des actions qu'il va effectuer.
Si tout semble correct, approuvez les actions en saisissantyes
.
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 # <----
Notez que si vous n'avez besoin que de prévisualiser les modifications sans les appliquer, vous pouvez utiliser la commande terraform plan
à la place.
Valider les modifications
Une fois Terraform exécuté, vous pouvez inspecter l'état de toutes les ressources et de tous les services provisionnés par Terraform en exécutant la commande suivante :
terraform show
Voici un exemple de ce que vous devriez voir imprimé. Votre état contiendra des valeurs spécifiques à votre projet.
# 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"
}
Vous pouvez également vérifier que le projet a été créé en l'affichant dans la console Firebase.
5. Enregistrer votre application Firebase via Terraform
Pour utiliser Firebase, vous devez enregistrer chaque variante de plate-forme de votre application dans votre projet Firebase. Dans cet atelier de programmation, vous allez utiliser une application réelle pour tester et interagir avec ce que vous provisionnez via Terraform. Cette application étant une application Web, vous devez indiquer à Terraform d'enregistrer une application Web Firebase dans le projet Firebase que vous venez de créer.
Ajouter un bloc pour enregistrer l'application Web
Pour enregistrer votre application Web dans votre projet Firebase, ajoutez le bloc de ressources suivant à votre fichier main.tf
.
Vous devez spécifier votre propre display_name
pour votre application Web. Notez que ce nom n'est utilisé que dans les interfaces Firebase et n'est pas visible par les utilisateurs finaux.
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"
}
Appliquer la configuration
- Pour provisionner la nouvelle ressource, exécutez la commande suivante à partir de la racine du même répertoire que votre fichier
main.tf
(qui doit êtreweb
). Notez que cette commande ne recrée pas de projet Google Cloud. Terraform détecte qu'un projet associé à l'ID de projet spécifié existe déjà. Il compare l'état actuel du projet à celui du fichierterraform apply
.tf
et apporte les modifications nécessaires. - Examinez le plan d'actions imprimé. Si tout semble correct, saisissez
yes
et appuyez sur Entrée pour approuver les actions.
Valider les modifications
Vous pouvez inspecter l'état de la ressource nouvellement provisionnée en exécutant la commande suivante :
terraform show
Vous pouvez également vérifier que l'application a bien été enregistrée dans votre projet en l'affichant dans la console Firebase. Accédez à Paramètres du projet, puis faites défiler la page jusqu'à la section Vos applications.
6. Configurer Firebase Authentication
L'authentification est un élément important de toute application. Pour permettre aux utilisateurs finaux de se connecter à votre application Web avec leur compte Google, vous pouvez activer Firebase Authentication et configurer la méthode de connexion avec Google.
Notez que dans cet atelier de programmation, nous vous proposons deux options différentes pour configurer Firebase Authentication :
- Option 1 (recommandée) : Configurez Firebase Authentication dans la console, ce qui ne nécessite pas GCIP.
- Si vous choisissez cette option, vous n'aurez pas à associer votre nouveau projet à un compte Cloud Billing.
- Option 2 : Configurez Firebase Authentication via Terraform à l'aide des API Google Cloud Identity Platform (GCIP).
- Si vous choisissez cette option, vous devez associer votre nouveau projet à un compte de facturation Cloud, car GCIP exige que le projet soit associé au forfait Blaze.
Option 1 : Configurer l'authentification à l'aide de la console Firebase
Pour configurer Firebase Authentication à l'aide de la console Firebase, votre projet n'a pas besoin d'être associé à la formule Blaze.
Voici comment configurer Firebase Authentication et la connexion avec Google :
- Dans la console Firebase, localisez la section Créer dans le panneau de gauche.
- Cliquez sur Authentification, puis sur Commencer, puis sur l'onglet Méthode de connexion (ou cliquez ici pour y accéder directement).
- Cliquez sur Ajouter un fournisseur, puis sélectionnez Google dans la section Fournisseurs supplémentaires.
- Activez le bouton Activer.
- Définissez le nom public de votre application sur
FriendlyChat
(il n'a pas besoin d'être unique au niveau mondial). - Sélectionnez une adresse e-mail d'assistance pour le projet dans le menu déroulant, puis cliquez sur Enregistrer.
- Google devrait s'afficher comme fournisseur de connexion activé.
Option 2 : Configurer l'authentification via Terraform à l'aide des API Google Cloud Identity Platform (GCIP)
Pour configurer Firebase Authentication avec Terraform, vous devez utiliser les API GCIP. Cela signifie que le projet doit être associé à la formule Blaze. Pour passer à la formule Blaze pour votre projet Firebase, associez-y un compte de facturation Cloud.
Activer la facturation avec Terraform
- Si vous ne possédez pas encore de compte de facturation Cloud, la première étape consiste à en créer un dans la console Google Cloud. Notez l'ID du compte de facturation. L'ID du compte de facturation se trouve sur la page Facturation, dans la section ID du compte de facturation associée à votre projet.
- Pour activer la facturation dans votre projet via Terraform, ajoutez un attribut
billing_account
à la ressourcegoogle_project
existante dans votre fichiermain.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" } } ...
Activer Firebase Authentication et la connexion avec Google via Terraform
- Pour provisionner l'authentification Firebase avec GCIP, ajoutez les blocs de ressources suivants à votre fichier
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, ] }
- Pour activer Se connecter avec Google, vous devez disposer d'un client OAuth. Pour effectuer cette configuration, accédez à la section API et services de la console Google Cloud.
- Puisque c'est la première fois que vous créez un ID client pour ce projet, vous devez configurer votre écran d'autorisation OAuth.
- Ouvrez la page Écran d'autorisation OAuth, puis sélectionnez le projet que vous venez de créer.
- Définissez le type d'utilisateur sur Externe, puis cliquez sur Créer.
- Sur l'écran suivant, effectuez les opérations suivantes, puis cliquez sur Enregistrer et continuer.
- Définissez le nom de l'application public sur
FriendlyChat
(il n'est pas nécessaire qu'il soit unique au niveau mondial). - Sélectionnez une adresse e-mail d'assistance aux utilisateurs dans le menu déroulant.
- Saisissez une adresse e-mail dans le champ Coordonnées du développeur.
- Définissez le nom de l'application public sur
- Sur les écrans suivants, procédez comme suit :
- Acceptez les valeurs par défaut sur la page Champs d'application, puis cliquez sur Enregistrer et continuer.
- Acceptez les valeurs par défaut sur la page Test users (Utilisateurs de test), puis cliquez sur Save and Continue (Enregistrer et continuer).
- Vérifiez le récapitulatif, puis cliquez sur Revenir au tableau de bord.
- Configurez un client OAuth sur la page Identifiants en procédant comme suit :
- Cliquez sur Créer des identifiants, puis sélectionnez ID client OAuth.
- Dans le menu déroulant Type d'application, sélectionnez Application Web.
- Dans le champ Nom, saisissez le nom de votre application, par exemple
FriendlyChat
(il n'est pas nécessaire qu'il soit unique au niveau mondial). - Autorisez l'URL de votre application à utiliser ce client OAuth en définissant les éléments suivants :
- Sous Origines JavaScript autorisées, cliquez sur Ajouter un URI, puis saisissez
https://<PROJECT_ID>.firebaseapp.com
, où<PROJECT_ID>
correspond à l'ID de projet que vous avez défini dansmain.tf
. - Sous URI de redirection autorisés, cliquez sur Ajouter un URI et saisissez
https://<PROJECT_ID>.firebaseapp.com/__/auth/handler
, où<PROJECT_ID>
correspond à l'ID de projet que vous avez défini dansmain.tf
.
- Sous Origines JavaScript autorisées, cliquez sur Ajouter un URI, puis saisissez
- Cliquez sur Enregistrer.
- Pour activer la connexion avec Google à l'aide de votre ID client et de votre code secret OAuth, ajoutez le bloc suivant à votre fichier
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 ] }
Appliquer la configuration
- Pour configurer l'authentification en fonction de votre configuration, exécutez les commandes suivantes à partir de la racine du même répertoire que votre fichier
main.tf
(qui doit êtreweb
) :export TF_VAR_oauth_client_secret="<YOUR_OAUTH_CLIENT_SECRET>"
Notez que l'exécution deterraform apply
terraform apply
ne recrée pas de projet Google Cloud. Terraform détecte qu'un projet associé à l'ID de projet spécifié existe déjà et compare l'état actuel du projet avec ce qui se trouve dans le fichier.tf
. Il apportera ensuite les modifications qu'il trouvera. - Examinez le plan d'actions imprimé. Si tout semble correct, saisissez
yes
et appuyez sur Entrée pour approuver les actions.
Valider les modifications
- Dans la console Firebase, localisez la section Créer dans le panneau de gauche.
- Cliquez sur Authentification, puis sur l'onglet Méthode de connexion (ou cliquez ici pour y accéder directement).
- Google devrait s'afficher comme fournisseur de connexion activé.
7. Configurer une base de données Firestore et ses règles de sécurité
Pour l'application Web de cet atelier de programmation, vous allez stocker les messages entre les utilisateurs finaux dans une base de données Firestore.
- Pour activer les API requises et provisionner l'instance de base de données, ajoutez les blocs de ressources suivants à votre fichier
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 ] }
- Remplacez
<NAME_OF_DESIRED_REGION>
par la région dans laquelle vous souhaitez que la base de données réside.
Lorsque vous développez une application de production, vous devez choisir une région proche de la majorité des utilisateurs et commune aux autres services Firebase, comme Cloud Functions. Pour cet atelier de programmation, vous pouvez utiliserus-east1
(Caroline du Sud) ou la région la plus proche de vous (consultez Emplacements Cloud Firestore). - Chaque instance de base de données Firestore accessible à Firebase doit être protégée par des règles de sécurité Firebase.
L'exemple de code de cet atelier de programmation fournit un ensemble de règles Firestore sécurisées dans le fichierfirestore.rules
, que vous trouverez à la racine du répertoireweb
. - Ajoutez les blocs de ressources suivants à votre fichier
main.tf
pour effectuer les opérations suivantes :- Créez un ensemble de règles de sécurité Firebase à partir du fichier
firestore.rules
local. - Publiez l'ensemble de règles pour l'instance 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 ] } }
- Créez un ensemble de règles de sécurité Firebase à partir du fichier
- Exécutez
terraform apply
pour provisionner la base de données Firestore et déployer ses règles de sécurité. - Vérifiez que la base de données est provisionnée et que ses règles de sécurité sont déployées :
- Dans la console Firebase, localisez la section Créer dans le panneau de gauche.
- Accédez à la section Base de données Firestore, puis cliquez sur l'onglet Règles.
8. Configurer un bucket Cloud Storage et ses règles de sécurité
Pour l'application Web de cet atelier de programmation, vous allez stocker les images partagées entre les utilisateurs finaux dans un bucket Cloud Storage.
- Pour activer les API requises et provisionner votre bucket Cloud Storage par défaut, ajoutez les blocs de ressources suivants à votre fichier
main.tf
.
Notez que le bucket Cloud Storage par défaut de votre projet est provisionné via Google App Engine et doit se trouver au même emplacement que votre base de données Firestore. Pour en savoir plus, consultez Emplacements App Engine.
Si vous souhaitez utiliser plusieurs buckets dans votre projet, provisionnez-les à l'aide de la ressourcegoogle_storage_bucket
(non affichée dans cet atelier de programmation).
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 }
- Chaque bucket Cloud Storage accessible à Firebase doit être protégé par des règles de sécurité Firebase.
L'exemple de code de cet atelier de programmation fournit un ensemble de règles Firestore sécurisées dans le fichierstorage.rules
, que vous trouverez à la racine du répertoireweb
. - Ajoutez les blocs de ressources suivants à votre fichier
main.tf
pour effectuer les opérations suivantes :- Créez un ensemble de règles de sécurité Firebase à partir du fichier local.
- Publiez l'ensemble de règles pour le bucket 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 ] } }
- Exécutez
terraform apply
pour provisionner le bucket Cloud Storage par défaut et déployer ses règles de sécurité. - Vérifiez que le bucket est provisionné et que ses règles de sécurité sont déployées :
- Dans la console Firebase, localisez la section Créer dans le panneau de gauche.
- Accédez à la section Stockage, puis cliquez sur l'onglet Règles.
9. Exécutez l'application en local
Vous êtes maintenant prêt à exécuter votre application Web pour la première fois. Vous utiliserez l'émulateur Firebase Hosting pour diffuser votre application en local.
- Ouvrez une nouvelle fenêtre de terminal et, à partir du répertoire
web
, exécutez la commande CLI Firebase suivante pour démarrer l'émulateur :firebase emulators:start --project=<PROJECT_ID>
- Dans votre navigateur, ouvrez votre application Web à l'URL locale renvoyée par l'interface de ligne de commande (généralement
http://localhost:5000
).
Vous devriez voir l'UI de votre application FriendlyChat, qui ne fonctionne pas (pas encore !). L'application n'est pas encore connectée à Firebase, mais elle le sera en suivant les prochaines étapes de cet atelier de programmation.
Notez que chaque fois que vous modifiez votre application Web (comme vous le ferez dans les étapes suivantes de cet atelier de programmation), vous devez actualiser votre navigateur pour mettre à jour l'URL locale avec ces modifications.
10. Installer, configurer et initialiser Firebase
Pour qu'une application fonctionne avec Firebase, elle a besoin du SDK Firebase et de la configuration Firebase pour votre projet Firebase.
L'exemple de code de cet atelier de programmation est déjà une application fonctionnelle avec toutes les dépendances et fonctions requises pour utiliser différents produits Firebase dans l'application. Vous pouvez consulter web/package.json
et web/src/index.js
si vous souhaitez voir ce qui a déjà été fait.
Même si l'exemple de code est presque complet, vous devez encore effectuer quelques opérations pour que votre application s'exécute. Par exemple, vous devez installer le SDK Firebase, démarrer votre compilation, ajouter la configuration Firebase à votre application et enfin initialiser Firebase.
Installer le SDK Firebase et démarrer votre compilation webpack
Vous devez exécuter quelques commandes pour lancer la compilation de votre application.
- Ouvrez une nouvelle fenêtre de terminal.
- Assurez-vous d'être à la racine du répertoire
web
. - Exécutez
npm install
pour télécharger le SDK Firebase. - Exécutez
npm update
pour mettre à jour les dépendances. - Exécutez
npm run start
pour démarrer webpack.
Pour le reste de l'atelier de programmation, webpack va maintenant recompiler en permanence votre code source.
Ajouter votre configuration Firebase à votre application
Vous devez également ajouter votre configuration Firebase à votre application afin que les SDK Firebase sachent quel projet Firebase vous souhaitez qu'ils utilisent.
Pour cet atelier de programmation, vous disposez de deux options pour obtenir votre configuration Firebase :
- Option 1 : Obtenez votre configuration Firebase depuis la console Firebase.
- Option 2 : Obtenez votre configuration Firebase via Terraform.
Option 1 : Obtenir la configuration depuis la console Firebase et l'ajouter à votre codebase
- Dans la console Firebase, accédez à vos Paramètres du projet.
- Faites défiler la page jusqu'à la fiche Vos applications, puis sélectionnez votre application Web.
- Sélectionnez Config dans le volet d'extrait de code du SDK Firebase, puis copiez l'extrait de code de configuration.
- Collez votre configuration dans le fichier
web/src/firebase-config.js
de votre application, comme suit :
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>", }; ...
Option 2 : Obtenir la configuration via Terraform et l'ajouter à votre codebase
Vous pouvez également obtenir votre configuration Firebase via Terraform en tant que valeur de sortie dans la CLI.
- Dans votre fichier
main.tf
, recherchez le bloc de ressourcesgoogle_firebase_web_app
(le bloc qui a enregistré une application Web auprès de votre projet). - Juste après ce bloc, ajoutez les blocs suivants :
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", "") } } ...
- Étant donné que les blocs
data
etoutput
ne sont pas destinés à modifier l'infrastructure de quelque manière que ce soit, vous n'avez qu'à exécuter les commandes suivantes.- Pour charger la configuration Firebase de votre application Web dans l'état Terraform de votre répertoire, exécutez la commande suivante :
terraform refresh
- Pour imprimer les valeurs de configuration Firebase, exécutez cette commande :
Voici un exemple de résultat d'une configuration. Votre sortie imprimée contiendra les valeurs de votre projet et de votre application.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" } } }
- Pour charger la configuration Firebase de votre application Web dans l'état Terraform de votre répertoire, exécutez la commande suivante :
- Copiez les valeurs de la carte
value
. - Collez ces valeurs (votre configuration) dans le fichier
web/src/firebase-config.js
de votre application, comme suit :
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", }; ...
Initialiser Firebase dans votre application
Enfin, pour initialiser Firebase, ajoutez les éléments suivants au fichier web/src/index.js
de votre application :
...
const firebaseAppConfig = getFirebaseConfig();
initializeApp(firebaseAppConfig);
Tester votre application
Maintenant que tout est configuré pour Firebase, vous pouvez tester votre application Web fonctionnelle.
- Actualisez le navigateur qui diffuse votre application.
- Vous devriez maintenant pouvoir vous connecter avec Google et commencer à publier des messages dans le chat. Si vous avez des fichiers image, vous pouvez même les importer.
11. Répliquer votre configuration dans différents environnements
Terraform excelle dans la gestion de plusieurs infrastructures configurées de manière similaire (par exemple, la configuration d'un projet Firebase intermédiaire semblable à un projet de production).
Dans cet atelier de programmation, vous allez créer un deuxième projet Firebase qui servira d'environnement de préproduction.
Pour répliquer une configuration existante afin de créer ce projet intermédiaire, deux options s'offrent à vous :
- Option 1 : Copiez la configuration Terraform.
Cette option offre la plus grande flexibilité quant à la différence entre le projet répliqué et le projet source. - Option 2 : Réutilisez les configurations avec
for_each
.
Cette option permet de réutiliser davantage de code si chaque projet ne doit pas différer de manière significative et que vous souhaitez propager les modifications à tous les projets en même temps.
Option 1 : Copier la configuration Terraform
Cette option offre la plus grande flexibilité quant à la différence entre le projet répliqué et le projet source. Par exemple, elle permet d'avoir des applications avec des noms à afficher différents et des déploiements progressifs.
- À la racine de votre répertoire
web
, créez un fichier de configuration Terraform nommémain_staging.tf
. - Copiez tous les blocs de ressources de votre fichier
main.tf
(à l'exception des blocsterraform
etprovider
), puis collez-les dans votre fichiermain_staging.tf
. - Vous devez ensuite modifier chacun de vos blocs de ressources répliqués dans
main_staging.tf
pour qu'ils fonctionnent avec votre projet de préproduction :- Libellés de ressources : utilisez un nouveau nom pour éviter les conflits. Par exemple, renommez
resource "google_project" "default"
enresource "google_project" "staging"
. - Références aux ressources : mettez-les toutes à jour. Par exemple, remplacez
google_firebase_project.default.project
pargoogle_firebase_project.staging.project
.
main_staging.tf
dans le dépôt GitHub de cet atelier de programmation :web/terraform-checkpoints/replicate-config/main_staging-copypaste.tf
Si vous souhaitez utiliser cette configuration, assurez-vous de procéder comme suit :- Copiez la configuration à partir de
main_staging-copypaste.tf
, puis collez-la dans votre fichiermain_staging.tf
. - Dans votre fichier
main_staging.tf
, procédez comme suit :- Dans le bloc de ressources
google_project
, mettez à jour les attributsname
,project-id
et (si vous avez configuré l'authentification via Terraform)billing_account
avec vos propres valeurs. - Dans le bloc de ressources
google_firebase_web_app
, mettez à jour l'attributdisplay_name
avec votre propre valeur. - Dans les blocs de ressources
google_firestore_database
etgoogle_app_engine_application
, mettez à jour les attributslocation_id
avec votre propre valeur.
- Dans le bloc de ressources
# 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" }
- Libellés de ressources : utilisez un nouveau nom pour éviter les conflits. Par exemple, renommez
- Exécutez
terraform apply
pour provisionner votre nouveau projet Firebase "staging" et toutes ses ressources, et activer ses services. - Vérifiez que tout a été provisionné et activé comme prévu en les vérifiant dans la console Firebase comme précédemment.
Option 2 : Réutiliser des configurations avec for_each
Cette option offre une meilleure réutilisation du code si chaque projet ne doit pas différer de manière significative et que vous souhaitez propager les modifications à tous les projets en même temps. Il utilise le méta-argument for_each
dans le langage Terraform.
- Ouvrez votre fichier
main.tf
. - Dans chaque bloc de ressources que vous souhaitez répliquer, ajoutez un méta-argument
for_each
, comme suit :
main.tf Vous trouverez la configuration complète d'un fichier# 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
qui utilise le méta-argumentfor_each
dans le dépôt GitHub de cet atelier de programmation :web/terraform-checkpoints/replicate-config/main-foreach.tf
Si vous souhaitez utiliser cette configuration, assurez-vous de procéder comme suit :- Copiez la configuration à partir de
main-foreach.tf
, puis collez-la dans votre fichiermain.tf
. - Dans votre fichier
main.tf
, procédez comme suit :- Dans le bloc de ressources
google_project
, mettez à jour les attributsname
,project-id
et (si vous avez configuré l'authentification via Terraform)billing_account
avec vos propres valeurs. - Dans le bloc de ressources
google_firebase_web_app
, mettez à jour l'attributdisplay_name
avec votre propre valeur. - Dans les blocs de ressources
google_firestore_database
etgoogle_app_engine_application
, mettez à jour les attributslocation_id
avec votre propre valeur.
- Dans le bloc de ressources
- Copiez la configuration à partir de
- Au lieu d'appliquer immédiatement cette configuration, il est important de comprendre et de corriger certains aspects de la façon dont Terraform interprète cette configuration par rapport à l'infrastructure existante.
- Pour l'instant, si vous appliquez cette configuration qui utilise
for_each
, les adresses de ressources ressemblent à ce qui suit : Toutefois, le projet existant que vous avez créé dans la première partie de cet atelier de programmation est connu de Terraform sous le nom suivant :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
- Exécutez
terraform plan
pour voir les actions que Terraform effectuerait en fonction de l'état actuel.
Le résultat devrait indiquer que Terraform supprimerait le projet que vous avez créé dans la première partie de cet atelier de programmation et en créerait deux nouveaux. En effet, Terraform ne sait pas que le projet à l'adressegoogle_project.default
a été déplacé vers la nouvelle adressegoogle_project.default["prod"]
. - Pour résoudre ce problème, exécutez la commande
terraform state mv
:terraform state mv "google_project.default" "google_project.default[\"prod\"]"
- De même, pour corriger tous les autres blocs de ressources, exécutez
terraform state mv
pourgoogle_firebase_project
,google_firebase_web_app
et tous les autres blocs de ressources de votre fichiermain.tf
. - Maintenant, si vous exécutez à nouveau
terraform plan
, Terraform ne devrait pas indiquer qu'il supprimerait le projet que vous avez créé dans la première partie de cet atelier de programmation.
- Pour l'instant, si vous appliquez cette configuration qui utilise
- Exécutez
terraform apply
pour provisionner votre nouveau projet Firebase "staging" et toutes ses ressources, et activer ses services. - Vérifiez que tout a été provisionné et activé comme prévu en les vérifiant dans la console Firebase comme précédemment.
12. Étape bonus : Déployez vos applications de préproduction et de production
- Dans le codebase de votre application, remplacez
firebase-config.js
par la configuration Firebase de votre projet intermédiaire.
Pour vous rappeler comment obtenir votre configuration Firebase et l'ajouter à votre application, consultez l'étape précédente de cet atelier de programmation : Ajouter votre configuration Firebase à votre application. - À la racine de votre répertoire
web
, exécutez la commande suivante pour déployer votre application sur votre projet Firebase de préproduction.firebase deploy --only hosting --project=<STAGING_PROJECT_ID>
- Ouvrez votre application intermédiaire dans le navigateur à l'aide de l'URL affichée dans le résultat de
firebase deploy
. Essayez de vous connecter, d'envoyer des messages et d'importer des images.
Lorsque vous déployez une application sur un projet Firebase, elle utilise de vraies ressources Firebase, et non des ressources émulées. Lorsque vous interagissez avec votre application de préproduction, des données et des images devraient apparaître dans votre projet de préproduction dans la console Firebase. - Après avoir testé votre application en préproduction, remplacez
firebase-config.js
par la configuration Firebase du projet de production (le premier projet que vous avez créé dans cet atelier de programmation). - À la racine de votre répertoire
web
, exécutez la commande suivante pour déployer votre application dans votre projet Firebase de production.firebase deploy --only hosting --project=<PRODUCTION_PROJECT_ID>
- Ouvrez votre application de production dans le navigateur à l'aide de l'URL imprimée dans le résultat de
firebase deploy
. Essayez de vous connecter, d'envoyer des messages et d'importer des images.
Vous devriez voir des données et des images apparaître dans votre projet de production dans la console Firebase. - Une fois que vous avez terminé d'interagir avec les deux applications pour cet atelier de programmation, vous pouvez empêcher Firebase de les diffuser. Exécutez la commande suivante pour chacun de vos projets :
firebase hosting:disable --project=<STAGING_PROJECT_ID>
firebase hosting:disable --project=<PRODUCTION_PROJECT_ID>
13. Félicitations !
Vous avez utilisé Terraform pour configurer une application Web de chat en temps réel. Vous avez suivi les bonnes pratiques pour les environnements de développement en créant des projets Firebase distincts pour la préproduction et la production.
Points abordés
- Utiliser la CLI Terraform pour gérer les ressources cloud
- Utiliser Terraform pour configurer les produits Firebase (Authentication, Firestore, Cloud Storage et règles de sécurité)
- Exécuter et tester une application Web en local à l'aide de la suite d'émulateurs locaux Firebase
- Importer Firebase dans une application Web
- Utiliser Terraform pour répliquer une configuration dans plusieurs environnements
Pour en savoir plus sur Firebase et Terraform, consultez notre documentation. Vous trouverez la liste de tous les produits Firebase compatibles avec Terraform, des exemples de configurations Terraform pour les cas d'utilisation courants, ainsi que des conseils de dépannage et des questions fréquentes utiles.