logo

アルパカログ

Cloud Run+IAP(Identity-Aware Proxy)構成をTerraformで管理する

Cloud RunにIAP(Identity-Aware Proxy)を適用する で紹介した Ruby on Rails アプリケーションを例に、Cloud Run+IAP 構成を Terraform で管理する方法を説明します。

ただし、完全自動化はできず一部 Google Cloud コンソールでの手動操作が必要になります。あらかじめご了承ください。

前提条件

今回使用するソフトウェアのバージョンは下記です。

  • Terraform 1.1.2
HTTP(S) ロードバランサの作成
ℹ️
Cloud Run + Cloud SQL の Terraform 構成は Cloud Run+Cloud SQL構成をTerraformで管理する で紹介したので省略します。

main.tf に Cloud Load Balancing を定義していきます。

Terraform を使用したサーバーレス負荷分散: 地道な方法 を参照してください。

作成するリソースは下記になります。

  • グローバル IP アドレス
  • SSL 証明書 (Google マネージド)
  • ネットワークエンドポイントグループ(リージョン)
  • バックエンドサービス
  • IAP Web バックエンドサービス IAM バインディング
  • URL マップ
  • HTTPS プロキシ
  • フォワーディングルール

少し多いですが サーバーレス ネットワーク エンドポイント グループの概要 を見つつ一度手動で IAP を構成してみると理解が進むでしょう。

#
# Cloud Load Balancing
#
resource "google_compute_global_address" "rails7-cloudrun-iap-sample" {
  name = "rails7-cloudrun-iap-sample-global-address"
}

resource "google_compute_managed_ssl_certificate" "rails7-cloudrun-iap-sample" {
  name = "rails7-cloudrun-iap-sample-cert"

  managed {
    domains = [var.domain]
  }
}

resource "google_compute_region_network_endpoint_group" "rails7-cloudrun-iap-sample" {
  name                  = "rails7-cloudrun-iap-sample-neg"
  region                = "asia-northeast1"
  network_endpoint_type = "SERVERLESS"
  cloud_run {
    service = google_cloud_run_service.rails7-cloudrun-iap-sample.name
  }
}

resource "google_compute_backend_service" "rails7-cloudrun-iap-sample" {
  name      = "rails7-cloudrun-iap-sample-backend"

  protocol  = "HTTP"
  port_name = "http"
  timeout_sec = 30

  backend {
    group = google_compute_region_network_endpoint_group.rails7-cloudrun-iap-sample.id
  }
}

resource "google_iap_web_backend_service_iam_binding" "rails7-cloudrun-iap-sample" {
  web_backend_service = google_compute_backend_service.rails7-cloudrun-iap-sample.name
  role = "roles/iap.httpsResourceAccessor"
  members = [
    "user:${var.iap_email}",
  ]
}

resource "google_compute_url_map" "rails7-cloudrun-iap-sample" {
  name            = "rails7-cloudrun-iap-sample-urlmap"

  default_service = google_compute_backend_service.rails7-cloudrun-iap-sample.id
}

resource "google_compute_target_https_proxy" "rails7-cloudrun-iap-sample" {
  name   = "rails7-cloudrun-iap-sample-https-proxy"

  url_map          = google_compute_url_map.rails7-cloudrun-iap-sample.id
  ssl_certificates = [
    google_compute_managed_ssl_certificate.rails7-cloudrun-iap-sample.id
  ]
}

resource "google_compute_global_forwarding_rule" "rails7-cloudrun-iap-sample" {
  name   = "rails7-cloudrun-iap-sample-forwarding-rule"

  target = google_compute_target_https_proxy.rails7-cloudrun-iap-sample.id
  port_range = "443"
  ip_address = google_compute_global_address.rails7-cloudrun-iap-sample.address
}
main.tf

IAP で許可するユーザーのメールアドレスと、SSL 証明書のドメインのための変数を定義します。

variable "iap_email" {
  description = "IAP user email"
  type        = string
}

variable "domain" {
  description = "Domain"
  type        = string
}

secret.tfvarsiap_emaildomain を追加しておきましょう。

iap_email = "<you@gmail.com>"
domain = "your.domain"

ロードバランサの IP アドレスと Cloud Run の URL を出力しておきましょう。

# Outputs

output "load_balancer_ip" {
  value = google_compute_global_address.rails7-cloudrun-iap-sample.address
}

output "cloud_run_url" {
  value = element(google_cloud_run_service.rails7-cloudrun-iap-sample.status, 0).url
}

ロードバランサを追加したので直接 Cloud Run へアクセスできないように制限しておきます。

 resource "google_cloud_run_service" "rails7-cloudrun-iap-sample" {
   ...
+  metadata {
+    annotations = {
+      "run.googleapis.com/ingress" = "internal-and-cloud-load-balancing"
+    }
+  }
 }

もしすでに Cloud Run サービスが作成済みの場合は google_cloud_run_serviceautogenerate_revision_name = true を追加するのを忘れないでください。

 resource "google_cloud_run_service" "rails7-cloudrun-iap-sample" {
   ...
+  autogenerate_revision_name = true
 }

一度 plan, apply しておきます。

$ terraform plan -var-file="secret.tfvars"
$ terraform apply -var-file="secret.tfvars"
IAP の有効化と OAuth クライアントの設定

現時点で OAuth クライアントは API で作成できない(internal org のみ対応)ため IAP の有効化(とそれに付随する OAuth クライアントの作成)は Google Cloud コンソールから手動で行う必要があります。

Only internal org clients can be created via declarative tools. External clients must be manually created via the GCP console.

Google Cloud コンソールから IAP を開き手動で IAP を有効化します。

IAP を有効化したらメニュー「OAuth 構成に移動」を開きます。

クライアントID とクライアントシークレットをコピーし secret.tfvars に追加します。

oauth_client_id = "<client_id>"
oauth_client_secret = "<client_secret>"

main.tf に変数の定義を追加します。

variable "oauth_client_id" {
  description = "OAuth Client ID"
  type        = string
}

variable "oauth_client_secret" {
  description = "OAuth Client Secret"
  type        = string
}

google_compute_backend_service リソースに iap ブロックを追加してクライアントID とクライアントシークレットを指定します。

resource "google_compute_backend_service" "rails7-cloudrun-iap-sample" {
   name      = "rails7-cloudrun-iap-sample-backend"
 
   protocol  = "HTTP"
   port_name = "http"
   timeout_sec = 30
 
   backend {
     group = google_compute_region_network_endpoint_group.rails7-cloudrun-iap-sample.id
   }
+
+  iap {
+    oauth2_client_id = var.oauth_client_id
+    oauth2_client_secret = var.oauth_client_secret
+  }
 }

変更したので apply しておきます。

$ terraform apply -var-file="secret.tfvars"

以上です。この記事では Cloud Run+IAP 構成を Terraform で管理する方法を説明しました。