1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
1
Help us understand the problem. What are the problem?