terraform-provider-grafana icon indicating copy to clipboard operation
terraform-provider-grafana copied to clipboard

Allow to map roles directly to users, teams and service accounts

Open vtorosyan opened this issue 3 years ago • 7 comments

Context

Grafana fine-grained access control allows now to assign roles directly to users and teams. We would need to update relevant terraform resources to support this functionality.

Implementation proposal

I can think of about three different approaches:

First option - extend grafana_user and grafana_team resources

Extend grafana_user and grafana_team resources with an ability to assign roles in-place

resource "grafana_user" "staff" {
  email    = "[email protected]"
  name     = "Staff Name"
  login    = "staff"
  password = "my-password"
  is_admin = false

 roles {
    uid  = "uid"
    global = false
  }

 roles {
    uid  = "seconduid"
    global = true
  }
}

resource "grafana_team" "test-team" {
  name  = "Test Team"
  email = "[email protected]"
  members = [
    "[email protected]"
  ]

  roles {
    uid  = "uid"
  }
}

Pros:

  • The roles are assigned in-place, this gives very clear idea of what a team or a user can do.

Cons:

  • Fine-grained access control is an enterprise feature. The grafana_role and grafana_user resources are supporting open source functionality. Mixing the two comes with a cost - maintainability, clarity and unmanageable expectations from users perspective are few of the things I can think of.
  • When you have terraform modules and resources spread in different places, I can imagine it might be a hard job for terraform users to pass down necessary variables to couple roles to users/teams.

Second option - create a new resource

We can create a new resource, which will be designated for adding roles to users and teams.

resource "grafana_role_assignments" "assignments" {
 role_uid = "uid"

 users {
    user_id  = 1
    global = true
  }

 teams {
    team_id  = 1
  }
}

Pros:

  • This follows the grafana_folder_permission design somehow. So might be a pattern we want to keep consistent.
  • You clearly see who has the given role assigned and control it in one place.
  • You can have your teams and users defined in one place, roles in another and the grafana_role_assignments in another.
  • This will allow to assign fixed roles to users and teams without a need of having the fixed role definition first in the terraform. Note that fixed roles are created by grafana backend and if users need to terraform it, they would need first to define it and import from the backend.

Cons:

  • If your users and teams are defined in a different terraform module, you might have a hard time to couple them with the roles, and need to answer the question of where to put the grafana_role_assignments resource and controlling the lifecycle of each also becomes difficult.
  • We already have builtin_role_assignments resource and it will create a confusion. The motivation for keeping these two separate though is really we want to treat the built-in role assignments in a special way, particularly because we eventually want to discourage users using it and encourage using only custom and fixed roles.

Third option - extend grafana_role resource

Third option is to extend grafana_role resource and add additional fields which will allow to directly assign it to users and teams

resource "grafana_role" "super_user" {
  name        = "Super User"
  description = "My Super User description"
  uid         = "superuseruid"
  version     = 1
  global      = true

  permissions {
    action = "users:create"
  }

  permissions {
    action = "users:read"
    scope  = "global:users:*"
  }

  users {
    user_id = 1
    global = true
  }

  teams {
    team_id = 1
  }
}

Pros:

  • All in one place, you have a role and you see what it can do, and who can use it.

Cons:

  • This might be too much for a single resource and result to an inconvenient dependencies between different terraform resources.

vtorosyan avatar Feb 07 '22 10:02 vtorosyan

Thanks @vtorosyan for such a thoughtful post. At this point I'm more inclined for the second option, but I'd like to discuss the cons you've found a bit more in detail.

  • If your users and teams are defined in a different terraform module, you might have a hard time to couple them with the roles, and need to answer the question of where to put the grafana_role_assignments resource and controlling the lifecycle of each also becomes difficult.

This is a good point, and makes me wonder if this could be solved somehow with user/team/roles data sources. Currently we only have grafana_user but we could extend it to team and roles. This way, if users/teams are defined in one module and roles in another, then you could do something like

# in users.tf
data "grafana_role" "super_user" {
  name = "Super User"
}

data "grafana_user" "foo" {
  email = "[email protected]"
}

data "grafana_team" "super_users" {
  name = "Super Users"
}

resource "grafana_role_assignments" "super_users" {
 role_uid = data.grafana_role.super_user.uid

 users {
    user_id  = data.grafana_user.foo.user_id
    global   = true
  }

 teams {
    team_id = data.grafana_team.super_users.team_id
  }
}

What do you think?

  • We already have builtin_role_assignments resource and it will create a confusion. The motivation for keeping these two separate though is really we want to treat the built-in role assignments in a special way, particularly because we eventually want to discourage users using it and encourage using only custom and fixed roles.

I believe this resource is already confusing 😸 but it makes total sense to have them separated for the reasons you exposed. I honestly don't think this is a blocking on pursuing something like this proposed solution.

@grafana/terraform-provider what do you think about this?

inkel avatar Feb 07 '22 14:02 inkel

Option 1 makes it harder for organizations to mix and match user provisioning and entitlements management. For example, if I want to manage users through LDAP but role grants through Terraform, I end up a bit stuck. Whereas if users could be a data source, it would be easy to mix and match. Denormalization is appealing but limiting.

ekpdt avatar Feb 07 '22 15:02 ekpdt

That's a really good argument that I haven't thought of, thanks for sharing!

inkel avatar Feb 07 '22 18:02 inkel

A quick update:

  • Since now we have Grafana service accounts, as well as upcoming terraform resource for it, to fully support RBAC we would also need to make it possible to assign roles directly to service accounts. So I'd propose to add this to the acceptance criteria of this issue.
  • After several discussions and feedbacks, it seems that the best option to move forward would be 2nd proposal, which is to introduce a new resource grafana_role_assignments.

vtorosyan avatar Jul 12 '22 18:07 vtorosyan

I'd second (or third) the need for this, the proposed path works for my use case as well. Any idea on when this would hopefully be incorporated?

NickAdolf avatar Jul 22 '22 13:07 NickAdolf

@NickAdolf thanks for the feedback. Unfortunately I can't unfortunately any exact ETA at the moment, but can share for sure that we are going to start working on this around next week. I'll make sure to update the issue once we know anything more specific.

vtorosyan avatar Aug 09 '22 18:08 vtorosyan

Hi, My team uses Grafana Cloud / Enterprise and we are having to perform work arounds without this feature. We would love it if we could add roles to teams via Terraform!

Thanks!

crflanigan avatar Aug 25 '22 14:08 crflanigan

Hi @crflanigan! Absolutely, that makes sense. We are currently actively working on this, so fingers crossed we get there soon 🤞

IevaVasiljeva avatar Aug 25 '22 15:08 IevaVasiljeva

Reopening as the terraform PR is still open (this was automatically marked as closed)

vtorosyan avatar Sep 21 '22 19:09 vtorosyan