Closed5

インターネットに公開用のGoogle Cloud StorageをTerraformを使って作成する

bisquebisque

最終的なtfファイルは以下です。

variable "bucket_prefix" {
  description = "バケット名のprefixです"
  type        = string
}

resource "google_storage_bucket" "public_bucket" {
  name = "${var.bucket_prefix}-public"
  force_destroy = false
  location = "ASIA1" # ASIA-NORTHEAST1 と ASIA-NORTHEAST2 の デュアルリージョン
  storage_class = "STANDARD"
}

resource "google_storage_bucket_iam_binding" "public_bucket_iam_binding" {
  bucket = google_storage_bucket.public_bucket.name
    role = "roles/storage.legacyObjectReader"
    members = [
      "allUsers",
    ]
}

これをBackendバケットとすることでLoad BalancerのUrlMapに追加することもできます。

以下に注意事項を書きます。

bisquebisque

注意点1

公式ドキュメントのバケットの公開手順に記載されているロール ストレージオブジェクト閲覧者 を設定すると、ルートディレクトリにアクセスしたときバケットの一覧が公開されてしまいます。

https://cloud.google.com/load-balancing/docs/https/ext-load-balancer-backend-buckets#making_the_buckets_public

これを防ぐためには、ロール ストレージオブジェクト閲覧者 ではなく、ロール ストレージのレガシー オブジェクト読み取り を設定します。

https://cloud.google.com/iam/docs/understanding-roles?hl=ja#cloud-storage-legacy-roles

確かに、ロール ストレージ オブジェクト閲覧者 には storage.objects.liststorage.objects.get (と他2つ)の権限があり、ロール ストレージのレガシー オブジェクト読み取りには storage.objects.get の権限しかありません。

「レガシー」というワードが気になるけどDeprecated指定はされていなさそう。

参考:
https://blog.mahoroi.com/posts/2019/08/gcs-read-legacy-object/

bisquebisque

注意点2

Terraformでバケットの権限を設定する方法がいくつかあるのですが、権限を追加する場合は google_storage_bucket_iam_binding を使います。

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket_iam

もし誤って google_storage_bucket_iam_policy を使った場合、権限が すべて上書きされてしまう ため、変更ができなくなります。この場合は、管理者ロールを持つユーザに ロール ストレージ管理者 を付けて、ユーザのバケットへの権限を復活させると操作可能になります。

bisquebisque

キャッシュ

Cloud Storageを直接公開する場合は、Cloud StorageのデフォルトのCDNがキャッシュをコントロールします。

https://cloud.google.com/storage/docs/caching

Cloud StorageのデフォルトのCDNでは機能が足りない場合は、Load Balancerを経由することで、Cloud CDNを設定することができます。

Cloud CDNは、キャシュモードを以下の3つから選択します。

  • CACHE_ALL_STATIC: オリジンのレスポンスのCache-Controlを優先します。
  • FORCE_CACHE_ALL: Cloud CDNの設定を優先(上書き)します。
  • USE_ORIGIN_HEADERS: オリジンのレスポンスのCache-Controlのみを使用します。

オリジンがCloud Storageの場合、メタ情報にCache-ControlがなくてもデフォルトのCDNがCache-Controlを設定するので注意してください。

https://cloud.google.com/cdn/docs/caching#cache-modes

bisquebisque

トラブルシューティング

Terraform で cdn_policy の cache_mode を CACHE_ALL_STATIC から FORCE_CACHE_ALL に変更できない。

変更しようとすると googleapi: Error 400: Invalid value for field 'resource.cdnPolicy.cacheMode': 'FORCE_CACHE_ALL'. max_ttl must be specified with CACHE_ALL_STATIC cache_mode only., invalid のようなエラーになります。

max_ttl を削除しても、cache_modeが FORCE_CACHE_ALL の場合、 max_ttl 自体を無視してしまうためGoogle Cloud側に max_ttl が残り、更新に失敗するようです。

回避するには、Terraformの google_compute_backend_bucket リソースを作り直すしかなさそうです。

このスクラップは2021/12/03にクローズされました