terraform/modules/datashare-application/api-gateway.tf (99 lines of code) (raw):

/** * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ locals { ds-ui-cloud_run_url = google_cloud_run_service.cloud-run-ds-ui.status[0].url ds-api-cloud_run_url = google_cloud_run_service.cloud-run-service-ds-api.status[0].url ds-api-cloud_run_domain = replace(google_cloud_run_service.cloud-run-service-ds-api.status[0].url, "https://", "") ds-api-open_api_spec_url = "${google_cloud_run_service.cloud-run-service-ds-api.status[0].url}/v1/docs/openapi_spec" use_remote_open_api_spec = var.use_remote_open_api_spec == true && var.use_impersonation == false } // https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/service_account_id_token data "google_service_account_id_token" "oidc" { count = local.use_remote_open_api_spec ? 1 : 0 // The audience claim for the id_token target_audience = "${local.ds-api-cloud_run_url}/" depends_on = [google_project_service.enable_iam_service, google_project_service.enable_iamcredentials_service] } // For impersonation tried passing in access_token but getting a 401 even when granting run.invoker role // created local.use_remote_open_api_spec to use local open api spec when using impersonation data "http" "open_api_spec" { count = local.use_remote_open_api_spec ? 1 : 0 url = "${local.ds-api-open_api_spec_url}/" # Optional request headers request_headers = { Accept = "application/json" Authorization = "Bearer ${data.google_service_account_id_token.oidc[0].id_token}" } depends_on = [google_cloud_run_service.cloud-run-service-ds-api] } locals { marketplace_audience = coalesce(var.api_domain, local.ds-api-cloud_run_domain) open_api_spec_content_local = replace(replace(replace(replace(file(var.open_api_spec_file), "DS_API_FQDN", local.ds-api-cloud_run_domain), "PROJECT_ID", var.project_id), "OAUTH_CLIENT_ID", var.oauth_client_id), "MARKETPLACE_AUDIENCE", local.marketplace_audience) open_api_spec_content_remote = local.use_remote_open_api_spec == true ? replace(replace(replace(replace(yamlencode(jsondecode(data.http.open_api_spec[0].body)), "DS_API_FQDN", local.ds-api-cloud_run_domain), "PROJECT_ID", var.project_id), "OAUTH_CLIENT_ID", var.oauth_client_id), "MARKETPLACE_AUDIENCE", local.marketplace_audience) : "" open_api_spec_content = local.use_remote_open_api_spec == true ? local.open_api_spec_content_remote : local.open_api_spec_content_local } resource "google_api_gateway_api" "api_gw" { project = var.project_id provider = google-beta api_id = "api-gw-ds-api" labels = { (var.goog_packaged_solution_key) = var.goog_packaged_solution_value } } resource "google_api_gateway_api_config" "api_cfg" { project = var.project_id provider = google-beta api = google_api_gateway_api.api_gw.api_id display_name = "Datashare API Config" api_config_id_prefix = "datashare-api-config-" openapi_documents { document { path = "spec.yaml" contents = base64encode(local.open_api_spec_content) } } gateway_config { backend_config { google_service_account = local.api_gateway_service_account_name } } labels = { (var.goog_packaged_solution_key) = var.goog_packaged_solution_value } lifecycle { create_before_destroy = true } } resource "google_api_gateway_gateway" "gw" { provider = google-beta region = var.region project = var.project_id api_config = google_api_gateway_api_config.api_cfg.id gateway_id = "api-gw-ds-api" display_name = "Datashare API Service Gateway" labels = { (var.goog_packaged_solution_key) = var.goog_packaged_solution_value } } // Grant API Gateway account run.invoker access on the API service resource "google_cloud_run_service_iam_member" "cloud_run_invoker" { location = google_cloud_run_service.cloud-run-service-ds-api.location project = google_cloud_run_service.cloud-run-service-ds-api.project service = google_cloud_run_service.cloud-run-service-ds-api.name role = "roles/run.invoker" member = local.iam_policy_api_gateway_service_account // To avoid policy change race condition depends_on = [google_cloud_run_service.cloud-run-service-ds-api, google_cloud_run_service_iam_policy.add_api_gateway_service_account_to_role] }