terraform-google-modules/terraform-google-project-factory

repository·main·Indexed 21 days ago

https://github.com/terraform-google-modules/terraform-google-project-factory

A Terraform module for creating standardized, best-practice-compliant Google Cloud projects. It automates complex setup tasks including Shared VPC integration, IAM provisioning, service account management, and the activation of APIs. The module supports specialized workflows such as provisioning App Engine projects, configuring budget alerts with Pub/Sub forwarding, managing notification settings via the essential_contacts submodule, and integrating GKE with Shared VPCs.

Tokens
40.4K
Snippets
73
Records
131
Agent score
74%

What's inside terraform-google-project-factory

  1. How Shared VPC subnets and IAM permissions are assigned

    main

    The module manages access to Shared VPC networks using the roles/compute.networkUser role. The scope of this access depends on how you configure the input variables:

    1. No Access: If both svpc_host_project_id and shared_vpc_subnets are unset, no compute.networkUser role is assigned.
    2. Full Host Access: If svpc_host_project_id is set but shared_vpc_subnets is not provided, the compute.networkUser role is assigned at the host project level. This gives the service project access to all shared VPC subnetworks.
    3. Granular Subnet Access: If svpc_host_project_id is set and shared_vpc_subnets contains an array of subnetwork paths, the compute.networkUser role is assigned to each specific subnetwork in the array. This limits the service project's access only to those specified subnets.
  2. Default IAM roles and permissions granted by Project Factory

    main

    The module automatically grants specific roles to various identities to ensure the project is functional and secure.

    New Default Service Account

    • compute.networkUser on the host project or specified subnets.
    • storage.admin on the bucket_name GCS bucket (if provided).

    Controlling Group (group_name)

    • compute.networkUser on the host project or specific subnets.
    • The specified group_role on the project.
    • iam.serviceAccountUser on the default Service Account.
    • storage.admin on the bucket_name GCS bucket (if provided).

    Google APIs Service Account

    • compute.networkUser on the host project or specified subnets.
    • storage.admin on the bucket_name GCS bucket (if provided).
  3. Understand why the default Service Account is deleted

    main

    The Project Factory deletes the default Compute Engine Service Account by default. This is a security best practice because the default service account automatically has the Editor role, which poses a significant security risk if an instance is compromised.

    By deleting it, the module forces developers to explicitly create and use new service accounts with minimal, least-privilege permissions, ensuring informed access control.

  4. Caveats: Project movement and Default Service Accounts

    main

    Moving projects from org into a folder

    There is a known bug when moving a project originally created at the root of the organization into a folder. Best Practice: Create all projects directly within folders to avoid this issue. Moving projects between different folders is supported.

    Deleting default service accounts

    Setting default_service_account = "delete" removes default SAs, but be aware of these dependencies:

    1. App Engine: App Engine Flex requires the default service account.
    2. Cloud Scheduler: Requires the AppEngine default SA for setup.

    To safely limit usage, consider combining the disable setting with the constraints/iam.automaticIamGrantsForDefaultServiceAccounts organization policy.

  5. How G Suite integration works in the Project Factory module

    main

    When using the gsuite_enabled module, the following automated actions are performed in addition to the standard project creation:

    1. Google Group Creation: If create_group is set to true, a new Google group is created using the provided group_name. This group is assigned the permissions defined in group_role.
    2. Default Service Account Management: The project's new default service account is automatically added as a MEMBER of the G Suite group specified in sa_group.
    3. Google APIs Service Account Management: The Google APIs service account is automatically added as a MEMBER of the G Suite group specified in api_sa_group.

    This pattern allows for centralized identity management by grouping service accounts into G Suite groups for easier permission auditing and control.

  6. Understand the preconditions script output

    main

    The script outputs a JSON array of check results. Each object in the array represents a specific requirement check.

    Key fields in the output:

    • type: The category of the check (e.g., Required APIs on service account project, Service account permissions on billing account).
    • name: The resource being checked.
    • satisfied: A list of requirements that passed.
    • unsatisfied: A list of requirements that failed. If this list is not empty, you must resolve these issues in your GCP environment before proceeding with the Terraform module.

    Example Output Analysis

    If the output shows unsatisfied: ["admin.googleapis.com", "cloudresourcemanager.googleapis.com"] for the Required APIs on service account project check, you must enable those specific APIs in your seed project.

    [
        {
            "type": "Required APIs on service account project",
            "name": "projects/my-seed-project",
            "satisfied": [
                "iam.googleapis.com"
            ],
            "unsatisfied": [
                "admin.googleapis.com",
                "cloudresourcemanager.googleapis.com",
                "cloudbilling.googleapis.com"
            ]
        }
    ]
  7. Use `random_project_id` to avoid project ID conflicts

    main
    The random_project_id variable appends a 4-character random suffix to the provided project_id. This is highly recommended during testing or development because Google Cloud does not allow you to reuse a project_id once a project has been deleted. Using a random suffix prevents conflicts when repeatedly creating and destroying projects.
  8. Understand the Project Factory domain model

    main

    The Project Factory operates using three primary entities: a Seed Project, a Seed Service Account, and Target Projects. Understanding these relationships is critical for configuring the module correctly:

    1. Seed Project: An existing Google Cloud Platform (GCP) project that contains the necessary resources, services, and service accounts required to drive the creation of new projects.
    2. Seed Service Account: A high-privilege service account residing within the Seed Project. This account acts as a "root level" identity used by the Project Factory to provision and manage Target Projects.
    3. Target Project: The end-state projects that are created and managed by the Project Factory module.
  9. Migrate to Project Factory v11.0

    main

    The v11.0 release is a backwards incompatible release. To upgrade, update your module source version to ~> 11.0.

    Note that the variables credentials_path and impersonate_service_account were removed in v11.0 because the module no longer requires gcloud or local-exec operations (a change introduced in v10.0). Removing these variables from your configuration should result in a no-op.

    module "project-factory" {
      source  = "terraform-google-modules/project-factory/google"
      version = "~> 11.0"
    
      name                            = "pf-test-1"
      random_project_id               = "true"
      org_id                          = "1234567890"
      usage_bucket_name               = "pf-test-1-usage-report-bucket"
      usage_bucket_prefix             = "pf/test/1/integration"
      billing_account                 = "ABCDEF-ABCDEF-ABCDEF"
      # credentials_path and impersonate_service_account must be removed
    }