💣

【GCP】Terraformでpolicyは弄ってはいけない

2022/10/17に公開

各プロバイダーの権限の仕組みの理解が疎かな状態でTerraformを書くと、スーパーユーザーじゃないと何もできない、terraform planさえも通らない、Web UIからも参照できないリソースができあがっちゃうので注意しよう という話です。

事例

やりたかったこと

外部公開したいデータを格納するため公開バケットを作成したい

誤ったコード

resource "google_storage_bucket" "oidc_keys" {
  name          = "hoge_bucket"
  location      = var.region
  project       = data.terraform_remote_state.project.outputs.project_id
  storage_class = "STANDARD"
  force_destroy = false

  versioning {
    enabled = true
  }

  uniform_bucket_level_access = true
}

data "google_iam_policy" "viewer" {
  binding {
    role = "roles/storage.objectViewer"
    members = [
        "allUsers",
    ] 
  }
}

resource "google_storage_bucket_iam_policy" "editor" {
  bucket = "${google_storage_bucket.bucket.name}"
  policy_data = "${data.google_iam_policy.viewer.policy_data}"
}

どうなるか

こんなバケットができちゃいます。

  • terraform planさえ通らない
  • gcloud CLIの参照系APIも通らない
  • スーパー権限以外何もできない
    • オブジェクト直指定での参照はできる(多分)

何がダメなのか

GCPの権限管理では、ポリシーとロールバインディングは下記のようなリソースになっています。

  • ポリシー:ロールバインディングの集合
  • ロールバインディング:メンバーと、そのメンバーに付与されたロールの紐付けを行うデータ

よって、ポリシーをterraformで定義すると、リソース作成時に自動的に作成されるデフォルトポリシーを破壊する可能性があります。

AWSを使っているとpolicyというワードでそのままリソースを作成したくなりますが、注意が必要です。

今回のコードも、既存のポリシーを上書きしたことで、全てのユーザーがオブジェクト参照しかできない状態になってしまいました。

正しい(期待通り動作する)コード

ロールバインディングを定義してあげれば期待通り、既存のポリシーへのバインディング追加になります。

# bucket定義は省略

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

まとめ

リソースのアクセス権限を調整する際は、providerの権限管理をきちんと理解してから行うべきです。同じ用語でもproviderによって意味が全く異なっていたりするので注意です。

参考資料

https://zenn.dev/nananaoto/articles/3b1b12a1c9db5ad2cfac
https://stackoverflow.com/questions/69456540/how-do-i-add-back-the-default-viewers-of-project-permission-on-a-gcs-bucket

Discussion