hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.26k stars 1.71k forks source link

`google_firebase_web_app` is creating the default API Key even though a custom `api_key_id` is supplied #17060

Closed BenJackGill closed 6 months ago

BenJackGill commented 6 months ago

Community Note

Terraform Version

Terraform v1.7.0 on darwin_arm64

Affected Resource(s)

Terraform Configuration Files

resource "google_apikeys_key" "firebase_web_browser_api_key" {
  provider     = google
  project      = var.project_id
  name         = "key-${random_id.key_suffix.hex}"
  display_name = "Custom Firebase Web Browser API Key"

  restrictions {
    browser_key_restrictions {
      allowed_referrers = ["https://${var.domain}"]
    }

    dynamic "api_targets" {
      for_each = [
        "firebase.googleapis.com",
        "firestore.googleapis.com"
      ]
      content {
        service = api_targets.value
      }
    }
  }
}

resource "google_firebase_web_app" "main" {
  provider     = google-beta
  project      = var.project_id
  display_name = "Web App"
  api_key_id   = google_apikeys_key.firebase_web_browser_api_key.uid

  deletion_policy = "DELETE"

  depends_on = [
    google_firebase_project.main,
  ]
}

Debug Output

Debug output file as a gist.

Expected Behavior

It should use the custom key during the creation of the web app, and therefore not create the default key named "Browser key (auto created by Firebase)".

Actual Behavior

It creates both the custom key and the default key.

Steps to Reproduce

  1. terraform apply
  2. Check the Google Cloud Console under APIs and Services > Credentials
  3. You will see it created the custom key (correct) and also the default key (this should not happen)

References

edwardmedia commented 6 months ago

@BenJackGill

1) from the log I do not see POST requests which are supposed to create the resources. Not sure how you did tf apply the config.

2) applying the example here, I do see the api key being created but not see the default key in the console. Is it possible the default key was created in a different way? Can you try to apply the example after deleting the default key?

BenJackGill commented 6 months ago

Sorry it's my first time supplying terraform debug logs. Here is an updated gist with new debug logs based on a fresh project. It should be correct now.

Also here is the exact terraform code I am using. As far as I can tell it follows the examples. My original post excluded some parts for brevity but I think it's functionally the same:

# Generates random id for the "name" field of the Firebase Web Browser API Key created below
resource "random_id" "key_suffix" {
  byte_length = 8
}

# Create the Firebase Web Browser API Key and restrict it by domain and all the APIs it uses
resource "google_apikeys_key" "firebase_web_browser_api_key" {
  provider     = google
  project      = var.project_id
  name         = "key-${random_id.key_suffix.hex}" # Used as a uuid by Google. Must be a unique value. Should be random so we don't get errors when deleteing and then re-creating keys, full details here: https://github.com/hashicorp/terraform-provider-google/issues/11726
  display_name = "Firebase Web Browser API Key"

  restrictions {
    browser_key_restrictions {
      allowed_referrers = ["https://${var.domain}"]
    }

    dynamic "api_targets" {
      for_each = [
        "firestore.googleapis.com", # Google Cloud Firestore API
        # "cloudbilling.googleapis.com", # Cloud Billing API
        # "cloudresourcemanager.googleapis.com", # Cloud Resource Manager API
        # "firebase.googleapis.com", # Firebase Management API
        # "serviceusage.googleapis.com", # Service Usage API
        # "identitytoolkit.googleapis.com", # Identity Toolkit API
        # "firebaserules.googleapis.com", # Firebase Rules API
        # "firebasestorage.googleapis.com", # Cloud Storage for Firebase API
        # "storage.googleapis.com", # Cloud Storage API
        # "cloudfunctions.googleapis.com", # Cloud Functions API
        # "apigateway.googleapis.com", # API Gateway API
        # "maps-backend.googleapis.com", # Maps JavaScript API
        # "places.googleapis.com" # Places API (the new Places API currently named as "Places API (New)"" in GCP)
      ]
      content {
        service = api_targets.value
      }
    }
  }
}

# Creates a Firebase Web App in the new project using the Browser API Key created above
resource "google_firebase_web_app" "main" {
  provider     = google-beta
  project      = var.project_id
  display_name = "Web"
  api_key_id   = google_apikeys_key.firebase_web_browser_api_key.uid

  # The other App types (Android and Apple) use "DELETE" by default.
  # Web apps don't use "DELETE" by default due to backward-compatibility.
  deletion_policy = "DELETE"

  # Wait for Firebase to be enabled in the Google Cloud project before creating this App.
  depends_on = [
    google_firebase_project.main,
  ]
}
edwardmedia commented 6 months ago

@BenJackGill I see the apiKeyId being successfully assigned to the webapp in the log you provided

---[ RESPONSE ]--------------------------------------
{
  "name": "operations/workflows/NjRkMzk3MTItNDhiYS00NTY4LWJmYTktYTFmYzVlNDYxNmNj",
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.firebase.service.v1beta1.WebApp",
    "name": "projects/cupcake-ga2n2/webApps/1:270858705069:web:9c5956485f60b59bf40e24",
    "appId": "1:270858705069:web:9c5956485f60b59bf40e24",
    "displayName": "Web",
    "projectId": "cupcake-ga2n2",
    "webId": "YmRkZGQ1MWMtMTJlMi00MmNmLTg4ZGItYWFmOTA0NDY4Njc0",
    "apiKeyId": "ead7b28e-b14e-4f97-8379-eb7adaf932cd",   <--- here
    "state": "ACTIVE",
    "expireTime": "1970-01-01T00:00:00Z",
    "etag": "1_da01a152-0d9d-4844-bdd0-d7ca8afd1bc2"
  }
}

What makes you see wrong with the default API Key?

BenJackGill commented 6 months ago

The custom API key is assigned correctly but when I check the console (APIs and Services > Credentials) I can see that it also creates the default key named "Browser key (auto created by Firebase)". The default key should only be created if there is no custom key.

The Terraform docs say this:

If apiKeyId is not set during creation, then Firebase automatically associates an apiKeyId with the WebApp. This auto-associated key may be an existing valid key or, if no valid key exists, a new one will be provisioned.

Since I am setting a custom key I was surprised to see that the default key was also provisioned. I believe this to be a bug.

Here are the two keys that were created:

1) The custom key.

2) The default key

See Console pic here:

Screenshot 2024-01-23 at 10 41 19 am

edwardmedia commented 6 months ago

@BenJackGill oh I see what you meant. I have the same Browser key being created. I think it was created by the api possibly when the Firebase was enabled. There is little the provider can do with it. Does it impact how your app works?

BenJackGill commented 6 months ago

I am trying to secure my apps and it's confusing to see it there. Future devs could end up using that unsecured default key instead of the custom key that I have restricted.

There also doesn't seems to be a Terraform way of searching for a key named Browser key (auto created by Firebase) and deleting it, which would have been a possible workaround to this issue.

edwardmedia commented 6 months ago

@BenJackGill I can't say how the api uses this key. But to manage it, there are two ways

  1. Terraform: you can first import the key and then you can manage it in a terraform way
  2. api call via curl. Here is the instruction you may want to review.
edwardmedia commented 6 months ago

@BenJackGill let me know if you still need assistance on this matter. Otherwise, I am going to close it soon

rainshen49 commented 6 months ago

@BenJackGill The Browser key (auto created by Firebase) is created when the Firebase project is created, not when the web app is created. You should be able to see the key without even creating a web app. This auto-provisioned API key is needed for legacy use cases, and the team is working on a better alternative. However, for your specific case:

  1. Delete Browser key (auto created by Firebase) in the Cloud console (unfortunately no clean way to do it in Terraform), you may have to resort to an HTTP request.
  2. Make sure all future web apps created in the project uses an api_key_id you supplied.

This together should prevent the auto-creation of the default API key.

BenJackGill commented 6 months ago

Sorry for the late reply. Appreciate your work on this.

From a quick look I think I can use the REST API for API Keys with the list method to get all the keys in a project and then iterate over the list to find a matching display name of the key I want to delete (Browser key (auto created by Firebase)). If a matching key is found in the list, then use the delete method to delete the key.

A little cumbersome but it should work for now until this gets sorted.

edwardmedia commented 6 months ago

@BenJackGill Glad you have a solution for your use case. Closing this issue now

github-actions[bot] commented 5 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.