service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.comが作られない！

# 概要
IAPを経由した、CloudRunへの通信を行う場合、`service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com`というサービスアカウントに対して、`roles/run.invoker`というロールを付与する必要があります。
今回、`backend service`をTerraformで作成時にIAPを有効化した場合に、`service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com`のサービスアカウントが作られず、ロールの付与がそもそもできないという事象が発生しました。そこで、その事象の再現と回避方法をご紹介します。

上記SAへの権限付与の必要性については公式ドキュメントをご参照ください。

https://cloud.google.com/iap/docs/enabling-cloud-run

# 事象の再現
まずは事象の再現方法を紹介します。プロジェクトに対応する`service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com`がまだ有効となっていないことが前提となります。

## Terraform定義
まずは、事象が発生したTerraform定義のサンプルをご紹介します。以下は`backend service`を含めたCloudRunフォワーディングするLB全体のTerraform定義のサンプルです。LB以外のリソースは省略しています。

```tf
resource "google_compute_region_network_endpoint_group" "sample_neg" {
  name                  = "sample_neg"
  network_endpoint_type = "SERVERLESS"
  region                = "asia-northeast1"

  cloud_run {
    service = "sample-cloud-run-service"
  }
}

resource "google_compute_ssl_policy" "sample_ssl_policy" {
  name            = "min-tls-1-2"
  profile         = "MODERN"
  min_tls_version = "TLS_1_2"
}

resource "google_compute_backend_service" "sample_backend_service" {
  name                  = "sample_backend_servie"
  load_balancing_scheme = "EXTERNAL_MANAGED"
  protocol              = "HTTPS"

  backend {
    balancing_mode = "UTILIZATION"
    group          = google_compute_region_network_endpoint_group.sample_neg.self_link
  }

  iap {
    enabled              = true # ※ここでIAPをONに指定しています※
    oauth2_client_id     = "Oauth2のClientID"
    oauth2_client_secret = "Oauth2のSecret"
  }
}

resource "google_compute_url_map" "sample_url_map" {
  name            = "sample-url-map"
  default_service = google_compute_backend_service.sample_backend_service.self_link
}

resource "google_compute_managed_ssl_certificate" "sample_ssl_certificate" {
  name = "sample-ssl-certificate"
  managed {
    domains = ["ドメイン名"]
  }
}

resource "google_compute_target_https_proxy" "sample_target_https_proxy" {
  name             = "sample-target-https-proxy"
  url_map          = google_compute_url_map.sample_url_map.self_link
  ssl_certificates = [google_compute_managed_ssl_certificate.sample_ssl_certificate.self_link]
  ssl_policy       = google_compute_ssl_policy.sample_ssl_policy.name
}

resource "google_compute_global_address" "sample_global_address" {
  name         = "sample-global-address"
  address_type = "EXTERNAL"
}

resource "google_compute_global_forwarding_rule" "sample_forwarding_rule" {
  name       = "sample-forwarding-rule"
  target     = google_compute_target_https_proxy.sample_target_https_proxy.self_link
  port_range = "443"
  ip_address = google_compute_global_address.sample_global_address.address

  load_balancing_scheme = "EXTERNAL_MANAGED"
}
```

## GCPコンソールからIAPの様子を確認
Terraformにてリソース作成後、コンソールを確認すると作成した`backend service`に紐づくIAPが有効になっていることがわかります。

![スクリーンショット 2024-12-13 16.27.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74514/bda7bf85-6875-64c1-0cc0-7c492df860cf.png)

## 対象のCloudRunにロールを付与
次に、IAPを経由した、CloudRunへの通信を行う場合、`service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com`というサービスアカウントに対して、`roles/run.invoker`というロールを付与する必要があるので、コンソールから権限を付与してみます。すると、以下のようにアカウントが有効でないというエラーとなりました。

![スクリーンショット 2024-12-13 16.31.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74514/11d0e575-8dd4-2b4a-903c-8ed2e05f9165.png)

# 回避方法
回避方法は単純で、GCPのコンソール画面でどれか適当な`backend service`に紐づくIAPを選択し、有効化設定を一時的にOFFにしてONにするだけです。

## 手順1
IAPを無効化

![スクリーンショット 2024-12-13 16.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74514/8574d142-60f4-20f1-e2b2-a26fcc0c9af1.png)


## 手順2
IAPを有効化

![スクリーンショット 2024-12-13 16.27.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74514/bda7bf85-6875-64c1-0cc0-7c492df860cf.png)

## 結果
上記手順を行った結果、`service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com`に権限付与ができるようになりました。

![スクリーンショット 2024-12-13 16.32.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74514/8f920225-516e-e671-b48a-c2e4cb789c0b.png)


また、このときCloudRunのAuthenticationを`Allow unauthenticated invocations`にしておくとIAPを一時OFFとしたときに誰でもアクセスできるようになってしまうため、 `Require authentication` としておくことをおすすめします。

![スクリーンショット 2024-12-13 16.43.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74514/f86a3e8e-fb25-4cd2-8491-1e891e9f6b93.png)


# まとめ
本記事では、Terraformにて`backend service`を作ったときに、`service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com`が作られないという事例と、その回避方法を紹介しました。これ以外の発生条件や根本的な原因はわかりませんが、最初に設定しておけば害は無いと思うので深追いはせずに回避方法だけ紹介させていただきました。