-
-
Save martin-mok/e2d5c32f87a87ab8f5ea25656edad629 to your computer and use it in GitHub Desktop.
Terraform configuration for creating a firebase project with firestore, functions and storage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # firebase.tf https://gist.githubusercontent.com/Zebreus/906b8870e49586adfe8bd7bbff43f0a8/raw/firebase.tf | |
| # Terraform configuration for creating a firebase project with firestore, functions and storage | |
| # Unfinished | |
| terraform { | |
| required_providers { | |
| google-beta = { | |
| source = "hashicorp/google-beta" | |
| version = "4.11.0" | |
| } | |
| null = { | |
| version = "~> 3.1.0" | |
| } | |
| time = { | |
| source = "hashicorp/time" | |
| version = "0.7.2" | |
| } | |
| } | |
| } | |
| variable "billing_account_id" { | |
| type = string | |
| description = "The id of the associated billing account" | |
| nullable = false | |
| } | |
| variable "project_id" { | |
| type = string | |
| description = "The id of the created project" | |
| nullable = false | |
| } | |
| variable "project_name" { | |
| type = string | |
| description = "The name of the created project" | |
| nullable = false | |
| } | |
| variable "region" { | |
| type = string | |
| description = "The region to create the project in" | |
| default = "europe-west1" | |
| nullable = false | |
| } | |
| variable "zone" { | |
| type = string | |
| description = "The zone to create the project in" | |
| default = "europe-west1-b" | |
| nullable = false | |
| } | |
| variable "location" { | |
| type = string | |
| description = "The location to create the project in" | |
| default = "europe-west" | |
| nullable = false | |
| } | |
| locals { | |
| bucket_location = "EUROPE-WEST1" | |
| } | |
| # Basic provider | |
| provider "google-beta" { | |
| alias = "gcloud-user" | |
| region = var.region | |
| zone = var.zone | |
| } | |
| data "google_billing_account" "account" { | |
| provider = google-beta.gcloud-user | |
| billing_account = var.billing_account_id | |
| } | |
| data "google_client_config" "gcloud-user" { | |
| provider = google-beta.gcloud-user | |
| # depends_on = [ | |
| # google_service_account.service_account | |
| # ] | |
| } | |
| data "google_client_openid_userinfo" "gcloud-user" { | |
| provider = google-beta.gcloud-user | |
| } | |
| // Create new google cloud project with service account | |
| resource "google_project" "default" { | |
| provider = google-beta.gcloud-user | |
| project_id = var.project_id | |
| name = var.project_name | |
| billing_account = data.google_billing_account.account.id | |
| } | |
| resource "google_service_account" "service_account" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| account_id = "terraform" | |
| display_name = "Terraform" | |
| } | |
| # Allow your user to create a access token | |
| resource "google_service_account_iam_member" "grant-token-iam" { | |
| provider = google-beta.gcloud-user | |
| service_account_id = google_service_account.service_account.id | |
| role = "roles/iam.serviceAccountTokenCreator" | |
| member = "user:${data.google_client_openid_userinfo.gcloud-user.email}" | |
| } | |
| resource "time_sleep" "delay_token_creation" { | |
| depends_on = [ | |
| google_service_account_iam_member.grant-token-iam, | |
| google_service_account.service_account, | |
| google_project_iam_member.firebase-admin-iam, | |
| google_project_iam_member.service-usage-admin-iam, | |
| google_project_iam_member.appengine-admin-iam, | |
| google_project_iam_member.appengine-creator-iam, | |
| google_project_iam_member.editor-iam | |
| ] | |
| create_duration = "30s" | |
| } | |
| # Create access token | |
| data "google_service_account_access_token" "default" { | |
| provider = google-beta.gcloud-user | |
| # project = google_project.default.project_id | |
| target_service_account = google_service_account.service_account.email | |
| scopes = ["userinfo-email", "cloud-platform"] | |
| lifetime = "300s" | |
| depends_on = [ | |
| google_service_account_iam_member.grant-token-iam, | |
| google_service_account.service_account, | |
| google_project_iam_member.firebase-admin-iam, | |
| google_project_iam_member.service-usage-admin-iam, | |
| google_project_iam_member.appengine-admin-iam, | |
| google_project_iam_member.appengine-creator-iam, | |
| google_project_iam_member.editor-iam, | |
| time_sleep.delay_token_creation | |
| ] | |
| } | |
| # Give some roles to the service account | |
| resource "google_project_iam_member" "firebase-admin-iam" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| role = "roles/firebase.admin" | |
| member = "serviceAccount:${google_service_account.service_account.email}" | |
| } | |
| resource "google_project_iam_member" "service-usage-admin-iam" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| role = "roles/serviceusage.serviceUsageAdmin" | |
| member = "serviceAccount:${google_service_account.service_account.email}" | |
| } | |
| resource "google_project_iam_member" "appengine-admin-iam" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| role = "roles/appengine.appAdmin" | |
| member = "serviceAccount:${google_service_account.service_account.email}" | |
| } | |
| resource "google_project_iam_member" "appengine-creator-iam" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| role = "roles/appengine.appCreator" | |
| member = "serviceAccount:${google_service_account.service_account.email}" | |
| } | |
| resource "google_project_iam_member" "editor-iam" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| role = "roles/editor" | |
| member = "serviceAccount:${google_service_account.service_account.email}" | |
| } | |
| # Create provider with service account | |
| resource "google_service_account_key" "mykey" { | |
| provider = google-beta.gcloud-user | |
| service_account_id = google_service_account.service_account.id | |
| # Wait for the account being added to roles | |
| depends_on = [ | |
| google_project_iam_member.firebase-admin-iam, | |
| google_project_iam_member.service-usage-admin-iam, | |
| ] | |
| } | |
| provider "google-beta" { | |
| alias = "service-account" | |
| project = google_project.default.project_id | |
| region = var.region | |
| zone = var.zone | |
| # impersonate_service_account = google_service_account.service_account.email | |
| # credentials = base64decode(google_service_account_key.mykey.private_key) | |
| access_token = data.google_service_account_access_token.default.access_token | |
| } | |
| # Activate all required apis | |
| resource "google_project_service" "serviceusage" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| service = "serviceusage.googleapis.com" | |
| disable_dependent_services = true | |
| depends_on = [ | |
| ] | |
| } | |
| resource "google_project_service" "firebase" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "firebase.googleapis.com" | |
| disable_dependent_services = true | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "firestore" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "firestore.googleapis.com" | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "firebasestorage" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "firebasestorage.googleapis.com" | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "cloudresourcemanager" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "cloudresourcemanager.googleapis.com" | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "identitytoolkit" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "identitytoolkit.googleapis.com" | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "compute" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "compute.googleapis.com" | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "container_registry" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "containerregistry.googleapis.com" | |
| disable_dependent_services = true | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "cloud_run" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "run.googleapis.com" | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| resource "google_project_service" "cloud_build" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| service = "cloudbuild.googleapis.com" | |
| depends_on = [ | |
| google_project_service.serviceusage | |
| ] | |
| } | |
| # Create firebase project | |
| resource "google_firebase_project" "default" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| depends_on = [ | |
| google_project_service.firebase | |
| ] | |
| } | |
| # Create firebase web app | |
| resource "google_firebase_web_app" "basic" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| display_name = "${var.project_name} App" | |
| depends_on = [ | |
| google_firebase_project.default | |
| ] | |
| } | |
| data "google_firebase_web_app_config" "basic" { | |
| provider = google-beta.service-account | |
| web_app_id = google_firebase_web_app.basic.app_id | |
| } | |
| # Create firestore database | |
| resource "google_app_engine_application" "app" { | |
| provider = google-beta.service-account | |
| # provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| location_id = var.location | |
| database_type = "CLOUD_FIRESTORE" | |
| depends_on = [ | |
| google_project_iam_member.appengine-admin-iam, | |
| google_project_iam_member.appengine-creator-iam, | |
| google_project_service.firestore | |
| ] | |
| } | |
| # Create a bucket for backups | |
| resource "google_storage_bucket" "backup" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| name = "${google_project.default.project_id}-backup" | |
| location = local.bucket_location | |
| } | |
| # Create admin-sdk service account | |
| resource "google_service_account" "admin_sdk" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| account_id = "firebase-adminsdk-ouwu6" | |
| display_name = "firebase-adminsdk" | |
| } | |
| resource "google_project_iam_member" "admin-sdk-token-creator" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| role = "roles/iam.serviceAccountTokenCreator" | |
| member = "serviceAccount:${google_service_account.admin_sdk.email}" | |
| } | |
| resource "google_project_iam_member" "admin-sdk-agent" { | |
| provider = google-beta.gcloud-user | |
| project = google_project.default.project_id | |
| role = "roles/firebase.sdkAdminServiceAgent" | |
| member = "serviceAccount:${google_service_account.admin_sdk.email}" | |
| } | |
| resource "google_service_account_key" "admin_sdk" { | |
| provider = google-beta.gcloud-user | |
| service_account_id = google_service_account.service_account.id | |
| # Wait for the account being added to roles | |
| depends_on = [ | |
| google_project_iam_member.admin-sdk-token-creator, | |
| google_project_iam_member.admin-sdk-agent, | |
| ] | |
| } | |
| # Create firebase storage | |
| resource "null_resource" "activate_storage" { | |
| triggers = { | |
| bucket = data.google_firebase_web_app_config.basic.storage_bucket | |
| } | |
| provisioner "local-exec" { | |
| command = "curl -X POST -H 'Authorization: Bearer ${nonsensitive(data.google_service_account_access_token.default.access_token)}' -H 'Content-Type: application/json' 'https://firebasestorage.googleapis.com/v1beta/projects/${google_project.default.project_id}/buckets/${data.google_firebase_web_app_config.basic.storage_bucket}:addFirebase'" | |
| interpreter = ["sh", "-c"] | |
| } | |
| depends_on = [ | |
| google_firebase_web_app.basic, | |
| google_project_service.firebasestorage | |
| ] | |
| } | |
| # Enable authentication service | |
| resource "google_identity_platform_config" "identity_platform_config" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| autodelete_anonymous_users = true | |
| depends_on = [ | |
| google_firebase_web_app.basic, | |
| google_project_service.identitytoolkit | |
| ] | |
| } | |
| resource "google_identity_platform_project_default_config" "identity_project_config" { | |
| provider = google-beta.service-account | |
| project = google_project.default.project_id | |
| sign_in { | |
| allow_duplicate_emails = false | |
| email { | |
| enabled = true | |
| password_required = true | |
| } | |
| } | |
| depends_on =[google_identity_platform_config.identity_platform_config] | |
| } | |
| # Write secrets to local file | |
| resource "local_file" "firebase_config" { | |
| content = jsonencode({ | |
| firebase = { | |
| appId = google_firebase_web_app.basic.app_id | |
| apiKey = data.google_firebase_web_app_config.basic.api_key | |
| authDomain = data.google_firebase_web_app_config.basic.auth_domain | |
| databaseURL = lookup(data.google_firebase_web_app_config.basic, "database_url", "") | |
| storageBucket = lookup(data.google_firebase_web_app_config.basic, "storage_bucket", "") | |
| messagingSenderId = lookup(data.google_firebase_web_app_config.basic, "messaging_sender_id", "") | |
| measurementId = lookup(data.google_firebase_web_app_config.basic, "measurement_id", "") | |
| } | |
| }) | |
| filename = "${path.module}/firebase-config.json" | |
| depends_on = [ | |
| google_firebase_web_app.basic | |
| ] | |
| } | |
| resource "local_file" "secrets_file" { | |
| content = jsonencode({ | |
| private = { | |
| serviceAccount = jsondecode(base64decode(google_service_account_key.admin_sdk.private_key)) | |
| firebase = { | |
| backupBucket = google_storage_bucket.backup.name | |
| } | |
| } | |
| public = { | |
| firebase = { | |
| projectId = google_project.default.project_id | |
| appId = google_firebase_web_app.basic.app_id | |
| apiKey = data.google_firebase_web_app_config.basic.api_key | |
| authDomain = data.google_firebase_web_app_config.basic.auth_domain | |
| databaseURL = lookup(data.google_firebase_web_app_config.basic, "database_url", "") | |
| storageBucket = lookup(data.google_firebase_web_app_config.basic, "storage_bucket", "") | |
| messagingSenderId = lookup(data.google_firebase_web_app_config.basic, "messaging_sender_id", "") | |
| measurementId = lookup(data.google_firebase_web_app_config.basic, "measurement_id", "") | |
| } | |
| } | |
| }) | |
| filename = "${path.module}/secrets.json" | |
| depends_on = [ | |
| google_firebase_web_app.basic | |
| ] | |
| } | |
| resource "local_file" "firebaserc" { | |
| content = jsonencode({ | |
| projects = { | |
| development = google_project.default.project_id | |
| production = google_project.default.project_id | |
| } | |
| }) | |
| filename = "${path.module}/.firebaserc" | |
| depends_on = [ | |
| google_project.default | |
| ] | |
| } | |
| resource "local_file" "admin_config" { | |
| content = base64decode(google_service_account_key.mykey.private_key) | |
| filename = "${path.module}/admin-config.json" | |
| depends_on = [ | |
| google_service_account_key.mykey, | |
| google_firebase_web_app.basic | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment