hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.28k stars 1.72k forks source link

google_compute_resource_policy attachment #11706

Open wilsonfv opened 2 years ago

wilsonfv commented 2 years ago

Community Note

Description

GCP has a feature to add schedule to start / stop VM. All of steps described from above official documentation can be achieved using following terraform resources

However in order to follow Principle of Least Privilege, we should bind permission to Compute Service Agent at instance level rather than on project level. This means using resource google_project_iam_binding is against Principle of Least Privilege.

Replacing google_project_iam_binding with google_compute_instance_iam_binding is currently possible and google_compute_instance_iam_binding is at instance level which would be better fit for Principle of Least Privilege however it will also introduce another dependency problem described following

If we were using google_compute_instance_iam_binding to bind permission to Compute Service Agent, the full steps to add schedule to VM can be described following

  1. Create VM
  2. Bind permission to Compute Service Agent at VM level
  3. Create Resource Policy
  4. Attach Resource Policy to VM

Notably in current terraform implementation, step 1 & 4 are actual one-step in terraform resource, see below

resource "google_compute_resource_policy" "foo" {
  name   = "policy"
  region = "us-central1"
  snapshot_schedule_policy {
    schedule {
      daily_schedule {
        days_in_cycle = 1
        start_time    = "04:00"
      }
    }
  }
}

resource "google_compute_instance" "default" {
  name         = "test"
  machine_type = "e2-medium"
  zone         = "us-central1-a"

  resource_policies = [
    google_compute_resource_policy.foo.id
  ]
}

However step 4 will depend on step 2 & 3 and step 4 & 1 are actual one step so there is no way inject these dependencies with exiting terraform resources if we bind permission to Compute Service Agent at VM level

New or Affected Resource(s)

Potential Terraform Configuration

In order to follow Principle of Least Privilege, we could run step 1 & 4 with separate terraform resources similar to existing google_compute_region_disk_resource_policy_attachment. A proposed new terraform resource google_compute_resource_policy_attachment and relevant configuration could look like below

# Step 1 Create VM
resource "google_compute_instance" "default" {
  name         = "test"
  machine_type = "e2-medium"
  zone         = "us-central1-a"

  resource_policies = [
    google_compute_resource_policy.foo.id
  ]
}

data "google_project" "gcp_project" {
  project_id = google_compute_instance.default.project
}

# Step 2 Bind permission to Compute Service Agent at VM level
resource "google_compute_instance_iam_binding" "binding" {
  project = google_compute_instance.default.project
  zone = google_compute_instance.default.zone
  instance_name = google_compute_instance.default.name

  role = "roles/compute.instanceAdminV1"
  members = [
    "serviceAccount:service-${data.google_project.gcp_project.number}@compute-system.iam.gserviceaccount.com",
  ]
}

# Step 3 Create Resource Policy 
resource "google_compute_resource_policy" "foo" {
  name   = "policy"
  region = "us-central1"
  snapshot_schedule_policy {
    schedule {
      daily_schedule {
        days_in_cycle = 1
        start_time    = "04:00"
      }
    }
  }
}

# Step 4 Attach Resource Policy to VM 
resource "google_compute_resource_policy_attachment" "attachment" {
  name = google_compute_resource_policy.foo.name
  instance = google_compute_instance.default.name
  region = "us-central1"
}
rileykarson commented 2 years ago

@slevenick to investigate prior to triage

slevenick commented 2 years ago

Request is for fine-grained google_compute_resource_policy_attachment resource to mirror google_compute_instance.resource_policies field to remove circular dependency when using google_compute_instance_iam_binding on the instance