2

Trying to access a public cloud run service and not sure why I keep getting this error message ({"message":"PERMISSION_DENIED:API basic-express-api-1yy1jgrw4nwy2.apigateway.chrome-courage-336400.cloud.goog is not enabled for the project.","code":403}) when hitting the gateway default hostname path with the API key in query string. The config has a service account with the role to be able to invoke cloud run services. All required APIs are also enabled. Here is a link to my entire codebase, but below is my API Gateway specific terraform configuration.

resource "google_api_gateway_api" "basic_express" {
  depends_on = [google_project_service.api_gateway, google_project_service.service_management, google_project_service.service_control]
  provider   = google-beta
  api_id     = "basic-express-api"
}

resource "google_api_gateway_api_config" "basic_express" {
  depends_on    = [google_project_service.api_gateway, google_project_service.service_management, google_project_service.service_control, google_api_gateway_api.basic_express]
  provider      = google-beta
  api           = google_api_gateway_api.basic_express.api_id
  api_config_id = "basic-express-cfg"
  openapi_documents {
    document {
      path     = "api-configs/openapi-spec-basic-express.yaml"
      contents = filebase64("api-configs/openapi-spec-basic-express.yaml")
    }
  }
  lifecycle {
    create_before_destroy = true
  }
  gateway_config {
    backend_config {
      google_service_account = google_service_account.apig_gateway_basic_express_sa.email
    }
    # https://cloud.google.com/api-gateway/docs/configure-dev-env?&_ga=2.177696806.-2072560867.1640626239#configuring_a_service_account
    # when I added this terraform said that the resource already exists, so I had to tear down all infrastructure and re-provision - also did not make a difference, still getting a 404 error when trying to hit the gateway default hostname endpoint - this resource might be immutable...
  }
}

resource "google_api_gateway_gateway" "basic_express" {
  depends_on = [google_project_service.api_gateway, google_project_service.service_management, google_project_service.service_control, google_api_gateway_api_config.basic_express, google_api_gateway_api.basic_express]
  provider   = google-beta
  api_config = google_api_gateway_api_config.basic_express.id
  gateway_id = "basic-express-gw"
  region     = var.region
}

resource "google_service_account" "apig_gateway_basic_express_sa" {
  account_id = "apig-gateway-basic-express-sa"
  depends_on = [google_project_service.iam]
}
# "Identity to be used by gateway"

resource "google_project_iam_binding" "project" {
  project = var.project_id
  role    = "roles/run.invoker"
  members = [
    "serviceAccount:${google_service_account.apig_gateway_basic_express_sa.email}"
  ]
}
# https://cloud.google.com/api-gateway/docs/configure-dev-env?&_ga=2.177696806.-2072560867.1640626239#configuring_a_service_account

2 Answers2

4

Try:

PROJECT=[[YOUR-PROJECT]]
SERVICE="basic-express-api-1yy1jgrw4nwy2.apigateway.chrome-courage-336400.cloud.goog"

gcloud services enable ${SERVICE} \
--project=${PROJECT}
DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • That worked! Thank you so much @DazWilkin. Do you know if it's possible to have this be enabled when provisioning with terraform or in the console? – Refayat Haque Dec 29 '21 at 19:16
  • Super! You can certainly enable using Console's [APIs library](https://console.cloud.google.com/apis/library) and using Terraform's GCP provider you can [google_project_service](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_service) – DazWilkin Dec 29 '21 at 19:39
  • This is very interesting, because using the same tf resource I am also enabling other necessary APIs including the `apigateway.googleapis.com` - seems like you ALSO need to enable the managed service that's created by API Gateway, you would think just enabling `apigateway.googleapis.com`, `servicemanagement.googleapis.com`, `servicecontrol.googleapis.com` would be enough... – Refayat Haque Dec 30 '21 at 02:18
  • How would you get the url from the gateway to put into the terraform config? Would I have to copy/paste it every time the endpoint changes? – PaulyP Jan 05 '22 at 17:38
  • I find this section vía web, where I was able to find certain PRIVATE service and enable it from there: https://console.cloud.google.com/apis/library/browse?filter=visibility:private – Mauricio Aug 24 '23 at 23:05
1

As others have pointed out, you need to enable the api service. You can do via terraform with the google_project_service resource:

resource "google_project_service" "basic_express" {
  project = var.project_id
  service = google_api_gateway_api.basic_express.managed_service

  timeouts {
    create = "30m"
    update = "40m"
  }

  disable_dependent_services = true
}