Skip to content

IAM Conflict in module fleet-app-operator-permissions when managing multiple Teams across separate TF states #2557

@lakrep

Description

@lakrep

There is a resource contention issue in the fleet-app-operator-permissions module when it is used in a decentralized multi-tenant environment (e.g., one Terraform state per Team/Fleet Scope).

When the module is called in multiple independent Terraform states to grant access to the same identity (User, Group, or Service Account) across different Fleet Scopes, the project-level IAM resources conflict with each other.

Scenario to Reproduce

  1. State A (Team "Alpha"): Calls the module for group:engineering@company.com for scope_id = "alpha".
  2. State B (Team "Beta"): Calls the same module for the same group:engineering@company.com for scope_id = "beta".

The Problem

While the Fleet Scope-level IAM (google_gke_hub_scope_iam_member) is unique to each team and does not conflict, the module hardcodes the creation of two project-level resources:

  • google_project_iam_member.gkehub_viewer
  • google_project_iam_member.container_viewer

Because these two project-level resources manage the exact same project + role + member tuple in both states:

  1. State Ownership Conflict: Each Terraform state believes it "owns" the project-level permission.
  2. State Flapping/Deletion: If Team "Alpha's" state is destroyed, it deletes the project-level viewer permissions, which immediately breaks console access for Team "Beta," even though Team "Beta" is still active.
  3. Plan Inconsistency: Running a plan in one state may show "no changes," but applying another state can trigger unexpected updates or "already exists" errors.

Impact
This behavior prevents the module from being used in a scalable, decoupled way where different teams manage their own access via separate Terraform states. It forces users to either centralize all Team IAM into a single massive state file or abandon the module entirely in favor of custom resources.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions