-
-
Save phlummox/514de91dafc2ac7f20b97cbbf2748804 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 | |
] | |
} | |
# 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