GoogleCloudPlatform/cloud-foundation-fabric

Permission error when using project-factory for creating organization policies in the project

Closed this issue · 3 comments

I want to disable the organization policy sql.restrictAuthorizedNetworks at the project level to whitelist secondary IP ranges for GKE pods, allowing them to communicate with Cloud SQL.

After reading the documentation, I found an easy way to configure it in the project factory. Here’s the complete project factory setup:

3-project-factory/terraform.tfvars:

factories_config = {
  hierarchy = {
    folders_data_path = "data/hierarchy"
  }
  projects_data_path = "data/projects"

}

3-project-factory/data/hierarchy/zk/_config.yaml:

name: Zeroit # dummy name
parent: folders/<folder id>

3-project-factory/data/hierarchy/zk/dev/_config.yaml:

name: Development

3-project-factory/data/projects/zk-dev.yaml:

prefix: zk-dev
billing_account: <billing account>
parent: zk/dev
labels:
  team: zk
services:
  - compute.googleapis.com
  - container.googleapis.com
  - storage.googleapis.com
  - sqladmin.googleapis.com
  - servicenetworking.googleapis.com
  - orgpolicy.googleapis.com
org_policies: # org policy configuration
  sql.restrictAuthorizedNetworks:
    rules:
      - enforce: false

3-project-factory/3-project-factory-providers.tf:

terraform {
  backend "gcs" {
    bucket                      = "zeroit-resman-pf-0"
    impersonate_service_account = "zeroit-resman-pf-0@zeroit-prod-iac-core-0.iam.gserviceaccount.com"
  }
}
provider "google" {
  impersonate_service_account = "zeroit-resman-pf-0@zeroit-prod-iac-core-0.iam.gserviceaccount.com"
}
provider "google-beta" {
  impersonate_service_account = "zeroit-resman-pf-0@zeroit-prod-iac-core-0.iam.gserviceaccount.com"
}

NOTE: I am using the main service account for project factory as discussed here.

The error is following:

Error creating Policy: googleapi: Error 403: Permission 'orgpolicy.policies.create' denied on resource '//cloudresourcemanager.googleapis.com/projects/zeroit-dev-zk-dev' (or it may not exist).
│ Details:
│ [
│   {
│     "@type": "type.googleapis.com/google.rpc.ErrorInfo",
│     "domain": "cloudresourcemanager.googleapis.com",
│     "metadata": {
│       "permission": "orgpolicy.policies.create",
│       "resource": "projects/zeroit-dev-zk-dev"
│     },
│     "reason": "IAM_PERMISSION_DENIED"
│   }
│ ]
│ 
│   with module.projects.module.projects["zk-dev"].google_org_policy_policy.default["sql.restrictAuthorizedNetworks"],
│   on ../../../modules/project/organization-policies.tf line 77, in resource "google_org_policy_policy" "default":
│   77: resource "google_org_policy_policy" "default" {

The service account for the project factory does not have the required permissions. Here are the current permissions:

  • serviceProjectNetworkAdmin
  • Owner
  • Tag Administrator
  • Tag User

I tried to extend its permissions at the Teams folder level during the resman stage, but the roles/orgpolicy.policyAdmin is only grantable at the organization level. I also tried to create a custom role with the required permissions during the bootstrap stage, but I encountered another error:

custom_roles = {
  organizationPolicyAdmin = [
      "orgpolicy.constraints.list",
      "orgpolicy.policies.create",
      "orgpolicy.policies.delete",
      "orgpolicy.policies.get",
      "orgpolicy.policies.list",
  ]
}
 Error creating the custom organization role Custom role organizationPolicyAdmin: googleapi: Error 400: Permission orgpolicy.policies.create is not supported in custom roles., badRequest
│ 
│   with module.organization.google_organization_iam_custom_role.roles["organizationPolicyAdmin"],
│   on ../../../modules/organization/iam.tf line 70, in resource "google_organization_iam_custom_role" "roles":
│   70: resource "google_organization_iam_custom_role" "roles" {

What is the top level folder you are using with folders/<folder id>? Does it have a tag binding for the context/project-factory value? Which version of FAST are you using?

The top level folder is the Teams folder, and adding context: project-factory tag in resman staged solved the problem.

top_level_folders = {
  teams = {
    name = "Teams"
    iam_by_principals = {
      "serviceAccount:zeroit-resman-pf-0@zeroit-prod-iac-core-0.iam.gserviceaccount.com" = [
        "roles/owner",
        "roles/resourcemanager.folderAdmin",
        "roles/resourcemanager.projectCreator",
        "roles/resourcemanager.tagAdmin",
        "roles/resourcemanager.tagUser",
      ]
    }
    tag_bindings = {
      context = "tagValues/<tag-value>"
    }
  }
}

FAST Version commit: 1174604efe2da84432b9516ca80e484258f90770

Thank you @ludoo for your support!

Thanks for confirming! We should document this better.