概要 #
Cloud Storage Bucketをコンソールで作ると、Uniform bucket-level accessやPublic access preventionの設定を見落としがちです。後から一つずつ確認するのも手間です。
Terraformなら、これらの設定を含めてコードに残せる構成です。ここでは検証用Bucketを作成し、IAMによる一元的なアクセス管理とPublic公開の防止を設定します。Bucket内にObjectが存在する場合のterraform destroyの挙動も確認します。
Terraformの基本操作は前提としています。Cloud Storageを初めて扱う方向けです。
この基本サンプルではBucketだけを作成し、ObjectのアップロードやIAM権限の追加は行いません。
検証すること #
- TerraformでCloud Storage Bucketを作成できること
- Bucket名をProject IDから組み立てられること
- Uniform bucket-level accessを有効化できること
- Public access preventionを
enforcedにできること force_destroyによる削除時の違いを理解すること
今回の構成 #
Bucketはlocationを指定して作ります。2つの設定を既定で有効にしている点が要点です。
flowchart TB
subgraph GCP["Google Cloud"]
subgraph Project["Project"]
subgraph Loc["location: ASIA-NORTHEAST1"]
subgraph Bucket["Bucket: tf-example-YOUR_PROJECT_ID"]
UBLA["Uniform bucket-level access
有効"]
PAP["Public access prevention
enforced"]
end
end
end
end
Uniform bucket-level accessを有効にすると、ObjectごとのACLが使えなくなりIAMだけで制御します。Public access preventionは、あとから誤って公開設定にすることを防ぎます。
BucketはASIA-NORTHEAST1へ作成し、アクセス管理はIAMへ統一します。また、PublicなPrincipalへ公開できない設定にします。
前提環境 #
- Google Cloud CLI
- Terraform 1.10.0以上、2.0.0未満
- ADCで認証済み
- 検証用Google Cloud Project
- Storage Admin相当の権限
- Service Usageを操作できる権限
- 検証時のバージョン:Terraform 1.14.3、google 7.43.0
使用するTerraformコード #
前回はVPC、Subnet、Firewall Ruleの作成を確認しました。
ファイル構成 #
03-cloud-storage/
├── README.md
├── versions.tf
├── provider.tf
├── variables.tf
├── main.tf
├── outputs.tf
└── terraform.tfvars.example
今回重要なTerraformコード #
Bucket名を組み立てる #
locals {
bucket_name = "${var.bucket_name_prefix}-${var.project_id}"
}
Cloud StorageのBucket名はGoogle Cloud全体で一意である必要があります。デフォルトのPrefixとProject IDを組み合わせ、他の利用者と重複しにくい名前にします。
それでも名前の重複が発生する場合は、bucket_name_prefixを変更します。
Cloud Storage API #
resource "google_project_service" "storage" {
project = var.project_id
service = "storage.googleapis.com"
disable_on_destroy = false
}
Bucketの削除後もCloud Storage APIは有効なまま残します。
Cloud Storage Bucket #
resource "google_storage_bucket" "example" {
name = local.bucket_name
location = var.location
force_destroy = var.force_destroy
uniform_bucket_level_access = true
public_access_prevention = "enforced"
versioning {
enabled = false
}
labels = {
env = "test"
system = "tf-examples"
component = "storage"
managed_by = "terraform"
example = "03-cloud-storage"
}
depends_on = [google_project_service.storage]
}
Uniform bucket-level access #
uniform_bucket_level_access = trueを設定すると、Object ACLではなくBucketに対するIAMでアクセス権を管理します。
Bucket IAMとObject ACLが混在する状態を避けられるため、誰がアクセスできるかを追いやすくなります。
Public access prevention #
public_access_prevention = "enforced"により、allUsersやallAuthenticatedUsersを使ったPublic公開を防止します。
このサンプルはアクセス許可用のIAM Resourceを作成しませんが、後から誤ってPublic Principalを追加するリスクも抑えられます。
force_destroy #
force_destroy = trueの場合、Bucket内にObjectが残っていてもTerraformがObjectを削除してからBucketを削除できます。
学習環境の後片付けには便利ですが、Objectが意図せず削除される可能性があります。本番環境では通常falseにし、データ削除を別の手順で管理する方が安全です。
入力値を設定する #
cd Basic-Examples/03-cloud-storage
cp terraform.tfvars.example terraform.tfvars
project_id = "your-project-id"
region = "asia-northeast1"
必要に応じて次の値を上書きします。
bucket_name_prefix = "tf-example"
location = "ASIA-NORTHEAST1"
force_destroy = true
BucketのLocationは作成後に簡単には変更できないため、データの利用場所や要件に合わせて決めます。
Terraformを実行する #
terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
PlanではCloud Storage APIとBucketが追加対象として表示されます。
Apply後はBucket名とgs://形式のURLがOutputへ表示されます。
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
bucket_name = "tf-example-YOUR_PROJECT_ID"
bucket_url = "gs://tf-example-YOUR_PROJECT_ID"
location = "ASIA-NORTHEAST1"
bucket_name = "tf-example-your-project-id"
bucket_url = "gs://tf-example-your-project-id"
location = "ASIA-NORTHEAST1"
GCP側で確認する #
Google Cloud CLIでBucketを確認します。
gcloud storage buckets describe \
"gs://$(terraform output -raw bucket_name)"
次の点を確認します。
- Locationが
ASIA-NORTHEAST1 - Uniform bucket-level accessが有効
- Public access preventionが
enforced - Versioningが無効
Bucket一覧から確認する場合は次のコマンドを使用します。
gcloud storage buckets list \
--filter="name:$(terraform output -raw bucket_name)"
エラー・注意点 #
Bucket名がすでに使われている #
Bucket名はGoogle Cloud全体で共有される名前空間を使用します。同じ名前が存在する場合は作成できないため、bucket_name_prefixを変更します。
Locationは用途に合わせる #
Bucketと利用者・アプリケーションの場所が離れていると、Latencyやネットワーク料金へ影響する可能性があります。保存先を決める際はデータ所在地の要件も確認します。
BucketとObjectの料金 #
空のBucket自体で大きな料金が発生することは通常ありませんが、Objectの保存容量、Operation、ネットワーク転送などは課金対象になります。
後片付け #
terraform destroy
デフォルトではforce_destroy = trueなので、検証中にObjectをアップロードしていても削除されます。必要なデータがないことを確認してから実行します。
Cloud Storage APIはdisable_on_destroy = falseのため有効なまま残ります。
まとめ #
- TerraformでCloud Storage Bucketを作成できる
- Project IDを使って重複しにくいBucket名を構成できる
- Uniform bucket-level accessでIAMへアクセス管理を統一できる
- Public access preventionでPublic公開を防止できる
force_destroyは便利だが、Objectも削除されるため慎重に使う
参考資料 #
- Terraform Google Provider: google_storage_bucket
- Google Cloud: Uniform bucket-level access
- Google Cloud: Public access prevention
- Google Cloud: Bucketの命名ガイドライン
次回 #
次は、Terraformで外部IPを持たないSpot VMとIAP SSH用ネットワークを作成します。