CloudRunで動作するサービスをIAP(Identity Aware Proxy)で保護する構成をTerraformで実装する
記事の内容
CloudRun上で動作するサービスをIAP(Identity Aware Proxy)で保護する構成をTerraformで実装します。
IAPについて
Identity Aware ProxyはGCPのLoadbalancerなどと共に動作するProxyで、GCPサービスを簡単に保護することができます。
IAPを利用するとGCP上で登録したGoogleアカウントでログインしているブラウザからのみCloudRun上で動作するサービスにアクセスできる構成を簡単に作ることができるため、社内管理画面などをインターネットアクセスから保護したい場合に便利です。
記事の長さ
3分で読めます
CloudRunを実装する
まずは、保護対象であるCloudRunサービスを作成します。
cloudrun.tf
resource "google_cloud_run_v2_service" "this" {
project = var.project_id
name = "iap-cloudrun"
location = "asia-northeast1"
ingress = "INGRESS_TRAFFIC_ALL"
template {
containers {
image = "gcr.io/cloudrun/hello"
}
}
}
data "google_iam_policy" "noauth" {
binding {
role = "roles/run.invoker"
members = ["allUsers"]
}
}
resource "google_cloud_run_v2_service_iam_policy" "policy" {
project = var.project_id
location = "asia-northeast1"
name = google_cloud_run_v2_service.this.name
policy_data = data.google_iam_policy.noauth.policy_data
}
上記Terraformファイルをapplyすると、CloudRun上でテストサイトが起動します。
$ terraform apply
Loadbalancerを設定する
IAPはLoadbalancerとともに動作するため、CloudRunへのアクセスをLoadbalancer経由に変更します。
CloudRunのIngressを変更する
先ほど作成したCLoudRunは、インターネットから直接CloudRunにアクセスすることを前提に作成されていたため、Loadbalancer経由でのアクセスに変更します。(ingressを変更する)
cloudrun.tf
resource "google_cloud_run_v2_service" "this" {
project = var.project_id
name = "iap-cloudrun"
location = "asia-northeast1"
# ここを変更。
ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
template {
containers {
image = "gcr.io/cloudrun/hello"
}
}
}
data "google_iam_policy" "noauth" {
binding {
role = "roles/run.invoker"
members = ["allUsers"]
}
}
resource "google_cloud_run_v2_service_iam_policy" "policy" {
project = var.project_id
location = "asia-northeast1"
name = google_cloud_run_v2_service.this.name
policy_data = data.google_iam_policy.noauth.policy_data
}
Loadbalancerを作成する
CloudRunがLoadbalancer経由でアクセスを受け付けるようになったので、次はLoadbalancer自体を設定します。
lb.tf
resource "google_compute_region_network_endpoint_group" "this" {
provider = google-beta
project = var.project_id
name = "cloudrun-neg"
network_endpoint_type = "SERVERLESS"
region = "asia-northeast1"
cloud_run {
service = google_cloud_run_v2_service.this.name
}
}
module "lb-http" {
source = "GoogleCloudPlatform/lb-http/google//modules/serverless_negs"
project = var.project_id
name = "iap-lb"
managed_ssl_certificate_domains = [var.domain_name]
ssl = true
https_redirect = true
backends = {
default = {
groups = [
{
group = google_compute_region_network_endpoint_group.this.id
}
]
enable_cdn = false
log_config = {
enable = false
}
iap_config = {
enable = false
oauth2_client_id = null
oauth2_client_secret = null
}
}
}
}
上記ファイルを作成後、再度Terraform Applyを実行します。
※Httpsアクセスが必要なため、独自ドメインを取得して、Loadbalancerに紐づけています。(DNSへのAレコードの追加は別で対応しています。)
Applyが成功したら、設定したdomain_nameにアクセスしてみてください。
先ほどCloudRunのURLにアクセスした時と同じ画面が表示されます。
IAPを設定する
アプリケーションが動作するCloudRunとLoadbalancerが作成できたので、最後にIAPを導入してCloudrun上で動作するアプリケーションにアクセスできるユーザーを限定します。
Oauth設定をする
まずは、IAP自体を利用できるようにするために、iap_brandを作成します。
iap.tf
resource "google_iap_brand" "project_brand" {
support_email = var.support_email
application_title = "Cloud IAP protected Application"
project = var.project_id
}
IAPを実装するために、IAP Brandを作成します。
Support Emailにemailアドレスを設定し、上記Terraformソースを実行してください。
Applyが完了すると、OAuth Consent Screen
に作成したアプリケーションが作成されているのを確認できます。
OAuth client IDを作成する
次に、Oauth Client IDを作成します。これはTerraformが対応していないため、手動でコンソールから作成します。
Credentialsの画面からCREATE CREDENTIALS
ボタンをクリックし、OAuth client ID
の選択項目を選択します。
その後、Web application
をApplication typeとして選択し、Nameは任意で、Authorized redirect URIs
に保護したいドメイン名を入力します。
この状態で作成すると、Oauth Clientのclient_id
とclient_secret
が表示されますので、それをメモしておきます。(後ほどTerraformに使います)
アクセスできるユーザーを指定する
次にIAPで制限しているアプリケーションにアクセスできるユーザーを指定します。
iap.tf
resource "google_iap_brand" "project_brand" {
support_email = var.support_email
application_title = "Cloud IAP protected Application"
project = var.project_id
}
resource "google_iap_client" "cloudrun_client" {
display_name = "cloudrun_iap_client"
brand = google_iap_brand.project_brand.name
}
# これを追加
resource "google_iap_web_backend_service_iam_binding" "this" {
project = var.project_id
web_backend_service = module.lb-http.backend_services.default.name
role = "roles/iap.httpsResourceAccessor"
members = [
"user:${var.access_user_email}",
]
}
上記のようにTerraformソースを変更して、access_user_email
にCloudRunにアクセス可能なユーザーのemailを設定してTerraform Applyを実行します。
LoadbalancerにIAPを設定する
IAPの準備とIAPにアクセスできるユーザーを設定したので、LoadbalancerにIAPを追加します。
lb.tf
resource "google_compute_region_network_endpoint_group" "this" {
provider = google-beta
project = var.project_id
name = "cloudrun-neg"
network_endpoint_type = "SERVERLESS"
region = "asia-northeast1"
cloud_run {
service = google_cloud_run_v2_service.this.name
}
}
module "lb-http" {
source = "GoogleCloudPlatform/lb-http/google//modules/serverless_negs"
project = var.project_id
name = "iap-lb"
managed_ssl_certificate_domains = [var.domain_name]
ssl = true
https_redirect = true
backends = {
default = {
groups = [
{
group = google_compute_region_network_endpoint_group.this.id
}
]
enable_cdn = false
log_config = {
enable = false
}
# ここを変更
iap_config = {
enable = true
oauth2_client_id = var.oauth2_client_id
oauth2_client_secret = var.oauth2_client_secret
}
}
}
}
上記のようにLoadbalancerのTerraform moduleにIAPを設定して、Terraform Applyを実行します。
※oauth2_client_id
とoauth2_client_secret
には、手動で作成してメモしておいたOAuth Clientのclient_idとclient_secretを設定します。
これで全ての実装が完了しました。
正常に保護されていることを確認する
最後にCloudRunのサイトが正常にIAPで保護されていることを確認します。
※IAPの反映まで5分ほどかかるので、Terraform Applyから10分ほど待ってから実験してください。
今回作成したアプリケーションのURLにアクセスするとGoogle認証が求められます。そして、今回追加したユーザーでログインすることでCloudRunのアプリケーションを表示できます!
Sample Code
Githubに今回作成したリソースを配置しておきます!
note
勉強法やキャリア構築法など、エンジニアに役立つ記事をnoteで配信しています。
Discussion