🚀

GCPのCloudCDNでwwwなしURLからwwwありURLへリダイレクトをterraformで

2022/11/13に公開約3,700字

静的なサイトをGCPでホスティング(GCS + CloudCDN)した時に、wwwなしのドメインからwww付きのドメインにリダイレクトかけたい。そんな時は、ロードバランサのURLマップ機能を使ってホストリダイレクトをかける。

URLマップとは

GCPのロードバランサ(CloudLoadBalancing)の機能で、リクエストのURLのホスト名やパスでマッピングして様々なバックエンドサービスに割り振る機能。例えば/storage/**みたいなパスでリクエストが来た時だけCloudStrageのバケットに飛ばして、それ以外はCloudRunに飛ばしたい時とかに便利。
https://cloud.google.com/load-balancing/docs/url-map-concepts?hl=ja
元々GCPのロードバランサはこのURLマップで各バックエンドサービスにリクエストを流すだけしかできなくて、wwwなし→wwwありリダイレクトをするにはサービス側で実装しないといけなかったけど、2020年くらいにリダイレクトができるようになったっぽい。えらい。

terraformで実装

とりあえずGCSでWebホスティングする設定も含めて全部版のコード。

 # グローバルIP
resource "google_compute_global_address" "default" {
  name = "test-ip"
}

# マネージドSSL
resource "google_compute_managed_ssl_certificate" "default" {
  name = "test-ssl"
  managed {
    domains = ["example.com", "www.example.com"]
  }
}

# URLマップ
resource "google_compute_url_map" "default" {
  name            = "test-urlmap"
  default_service = google_compute_backend_bucket.default.id
  host_rule {
    hosts        = "example.com"
    path_matcher = "redirect-host"
  }
  path_matcher {
    name = "redirect-host"
    default_url_redirect {
      host_redirect = "www.example.com"
      strip_query   = false
    }
  }
}

# HTTPS Proxy
resource "google_compute_target_https_proxy" "default" {
  name             = "test-https-proxy"
  url_map          = google_compute_url_map.default.id
  ssl_certificates = [
    google_compute_managed_ssl_certificate.default.id
  ]
}

# フォワーディングルール
resource "google_compute_global_forwarding_rule" "default" {
  name       = "test-forwarding-rule"
  target     = google_compute_target_https_proxy.default.id
  port_range = "443"
  ip_address = google_compute_global_address.default.address
}

# バックエンドバケット
resource "google_compute_backend_bucket" "default" {
  name        = "test-backend-bucket"
  bucket_name = google_storage_bucket.default.name
  enable_cdn  = true
}

# バケット生成
resource "google_storage_bucket" "default" {
  name     = "${BUCKET_NAME}" # 世界に一つだけのバケット名を設定
  location = "ASIA-NORTHEAST1"
  website {
    main_page_suffix = "index.html"
  }
}

# AllUsersアクセス付与
resource "google_storage_bucket_iam_member" "default" {
  bucket = google_storage_bucket.default.name
  role   = "roles/storage.legacyObjectReader"
  member = "allUsers"
}

# グローバルIPアドレス確認
output "global_ip" {
  value = google_compute_global_address.default.address
}

これでexaple.comwww.exapmle.comの両方のドメインのAレコードに吐き出されたIPアドレスを設定すれば、exaple.comwww.exapmle.comにリダイレクトされるようになる。

URLマップ部分の解説

URLマップはhost_rulepath_matcherpath_ruleの順番でマッピングされて、このルールと一致しない場合はデフォルトのサービスに飛ばされる。なので今回の場合はホストがwwwなしだった場合のみリダイレクトのルールを設定して、他はデフォルトでGCSのバックエンドバケットに飛ばすように設定。ホスト名しか見なくていいのでpath_ruleの設定は必要なし。

resource "google_compute_url_map" "default" {
  name            = "test-urlmap"
  default_service = google_compute_backend_bucket.default.id
  host_rule {
    hosts        = "example.com"
    path_matcher = "redirect-host"
  }
  path_matcher {
    name = "redirect-host"
    default_url_redirect {
      host_redirect = "www.example.com"
      strip_query   = false
    }
  }
}

default_url_redirect

リダイレクトはdefault_url_redirectで設定する。主な設定項目は下記のとおり。

host_redirect

リダイレクト先のホストを設定。そのままでいい場合は設定しない。

path_redirect

パスを変換する場合は設定。そのままでいい場合は設定しない。

redirect_code

リダイレクトコードを設定。デフォルトはMOVED_PERMANENTLY_DEFAULT。下2つを覚えておけばヨシ!

  • MOVED_PERMANENTLY_DEFAULT: 301リダイレクト(永続)
  • FOUND: 302リダイレクト(一時的)
strip_query ※必須

クエリパラメータを消すか否か。trueを設定するとクエリパラメータを消した状態でリダイレクトする。なぜか必須なのでtruefalseを必ず設定する。

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_url_map#default_url_redirect

まとめ

wwwありリダイレクトとかでググると、AWSはLamda@EdgeとかCloudFrontFunctionsとかでリダイレクトさせる記事がポロポロでてくるのですが、GCPだとほぼ皆無だったので書いてみました。リダイレクト自体が意外と最近できるようになったっぽいので知られてないのかも?みんなもっとGCP使おう!Google最高!

Discussion

ログインするとコメントできます