インターネットに公開用のGoogle Cloud StorageをTerraformを使って作成する
最終的な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に追加することもできます。
以下に注意事項を書きます。
注意点1
公式ドキュメントのバケットの公開手順に記載されているロール ストレージオブジェクト閲覧者
を設定すると、ルートディレクトリにアクセスしたときバケットの一覧が公開されてしまいます。
これを防ぐためには、ロール ストレージオブジェクト閲覧者
ではなく、ロール ストレージのレガシー オブジェクト読み取り
を設定します。
確かに、ロール ストレージ オブジェクト閲覧者
には storage.objects.list
と storage.objects.get
(と他2つ)の権限があり、ロール ストレージのレガシー オブジェクト読み取り
には storage.objects.get
の権限しかありません。
「レガシー」というワードが気になるけどDeprecated指定はされていなさそう。
参考:
注意点2
Terraformでバケットの権限を設定する方法がいくつかあるのですが、権限を追加する場合は google_storage_bucket_iam_binding
を使います。
もし誤って google_storage_bucket_iam_policy
を使った場合、権限が すべて上書きされてしまう ため、変更ができなくなります。この場合は、管理者ロールを持つユーザに ロール ストレージ管理者
を付けて、ユーザのバケットへの権限を復活させると操作可能になります。
キャッシュ
Cloud Storageを直接公開する場合は、Cloud StorageのデフォルトのCDNがキャッシュをコントロールします。
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を設定するので注意してください。
トラブルシューティング
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 リソースを作り直すしかなさそうです。