LoginSignup
1

More than 3 years have passed since last update.

Shared VPC構成でサービスプロジェクトから使用することができるサブネットを限定する方法

Last updated at Posted at 2020-12-08

GCPのShared VPC構成ではホストプロジェクトにあるサブネットに対してサービスプロジェクトのユーザーがVMなどを設置する権限を払い出すことができます。
このときに注意しないといけないのは、IAMによって権限を払い出す対象はプロジェクトではなくユーザーであるということです。
そのため、複数のプロジェクトでVMを設置する権限を持っているユーザーによって予期しない形でVMが建てられることがあります。

例えば、以下の構成を考えます。

resource "google_compute_shared_vpc_service_project" "service-project-a" {
  host_project    = var.host-project
  service_project = "service-project-a"
}

resource "google_compute_subnetwork" "subnet-a" {
  name = "subnet-a"
  ...
}

data "google_iam_policy" "policy-a" {
  binding {
    role    = "roles/compute.networkUser"
    members = ["taro@example.com"]
  }
}

resource "google_compute_subnetwork_iam_policy" "policy-a" {
  project     = var.host-project
  subnetwork  = google_compute_subnetwork.subnet-a.name
  policy_data = data.google_iam_policy.policy-a.policy_data
}

resource "google_compute_shared_vpc_service_project" "service-project-b" {
  host_project    = var.host-project
  service_project = "service-project-b"
}

resource "google_compute_subnetwork" "subnet-b" {
  name = "subnet-b"
  ...
}

data "google_iam_policy" "policy-b" {
  binding {
    role    = "roles/compute.networkUser"
    members = ["taro@example.com"]
  }
}

resource "google_compute_subnetwork_iam_policy" "policy-b" {
  project     = var.host-project
  subnetwork  = google_compute_subnetwork.subnet-b.name
  policy_data = data.google_iam_policy.policy-b.policy_data
}

この時、service-project-aはsubnet-a、service-project-bはsubnet-bのみを利用することを意図しているとします。
しかし、両方のサブネットに対して権限を渡している taro@example.com はservice-project-aのVMをsubnet-bに建てることができます。
サブネット毎に権限を払い出すユーザーの重複がないようにすればこのような自体を防ぐことはできますが、複数プロジェクトにアサインされているメンバーのことを考えると現実的に厳しいケースもあります。

解決策

GCPのOrganization Policyを使うことでこの問題を解決することができます。

Organization Policyは特定のOrganizationやFolderやProjectに対する操作を制限することができる機能です。
aws Organizationを使ったことがある人ならば、サービスコントロールポリシー(SCP)に近しいものという説明がわかりやすいでしょう。

以下のコードを反映するとproject-aが使用できるサブネットワークがsubnet-aに限定されます。また、同様にproject-bとsubnet-bの間でも同様の設定がされます。

resource "google_project_organization_policy" "restrict-shared-vpc-subnetworks-a" {
  project    = "service-project-a"
  constraint = "compute.restrictSharedVpcSubnetworks"

  list_policy {
    inherit_from_parent = false
    allow {
      values = [
        "projects/${var.host-project}/regions/${google_compute_subnetwork.subnet-a.region}/subnetworks/${google_compute_subnetwork.subnet-a.name}"
      ]
    }
  }
}

resource "google_project_organization_policy" "restrict-shared-vpc-subnetworks-b" {
  project    = "service-project-b"
  constraint = "compute.restrictSharedVpcSubnetworks"

  list_policy {
    inherit_from_parent = false
    allow {
      values = [
        "projects/${var.host-project}/regions/${google_compute_subnetwork.subnet-b.region}/subnetworks/${google_compute_subnetwork.subnet-b.name}"
      ]
    }
  }
}

なお、この時にTerraformに対して割り当てる権限はホストプロジェクトのOwner権限だけでは不十分であり、Organizationに対するroles/orgpolicy.policyAdminのRoleを割り当てる必要があります。
https://cloud.google.com/iam/docs/understanding-roles#organization-policy-roles

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1