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

[feature request] sepearete resource for team membership

Open JordanSussman opened this issue 5 years ago • 22 comments

Terraform Version

v0.12.20

Affected Resource(s)

  • opsgenie_team

If this issue appears to affect multiple resources, it may be an issue with Terraform's core, so please mention this.

Terraform Configuration Files

resource "opsgenie_user" "first" {
  username  = "[email protected]"
  full_name = "name "
  role      = "User"
}

resource "opsgenie_user" "second" {
  username  = "[email protected]"
  full_name = "name "
  role      = "User"
}

resource "opsgenie_team" "test" {
  name        = "example"
  description = "This team deals with all the things"

  member {
    id   = "${opsgenie_user.first.id}"
    role = "admin"
  }

  member {
    id   = "${opsgenie_user.second.id}"
    role = "user"
  }
}

I'd like to propose a separate resource of opsgenie_team_membership instead of relying on utilizing opsgenie_team for membership. This change would allow us to manage initial team membership Terraform and some further changes done through the UI.

Currently, if you make changes through the UI for a team that is managed via Terraform it will attempt to delete users from the team. If we instead utilize opsgenie_team_membership to add members to the team it wouldn't need to delete membership at the team level if users are added via the UI.

Proposed Terraform Configuration Files

resource "opsgenie_user" "first" {
  username  = "[email protected]"
  full_name = "name "
  role      = "User"
}

resource "opsgenie_user" "second" {
  username  = "[email protected]"
  full_name = "name "
  role      = "User"
}

resource "opsgenie_team" "test" {
  name        = "example"
  description = "This team deals with all the things"
}

resource "opsgenie_team_membership" "first" {
    id   = "${opsgenie_user.first.id}"
    role = "admin"
    team = "${opsgenie_team.test.id}"
}

resource "opsgenie_team_membership" "second" {
    id   = "${opsgenie_user.second.id}"
    role = "admin"
    team = "${opsgenie_team.test.id}"
}

JordanSussman avatar Jan 29 '20 17:01 JordanSussman

@JordanSussman hey could you write what kind of changes make this

Currently, if you make changes through the UI for a team that is managed via Terraform it will attempt to delete users from the team

I think there is a bug in team resource. Thats shouldnt be a expected behaviour (deleting user)

ffahri avatar Feb 03 '20 06:02 ffahri

Steps to reproduce the deletion of team membership:

  1. Apply the following terraform code

    resource "opsgenie_user" "first" {
      username  = "[email protected]"
      full_name = "name "
      role      = "User"
    }
    
    resource "opsgenie_user" "second" {
      username  = "[email protected]"
      full_name = "name "
      role      = "User"
    }
    
    resource "opsgenie_team" "test" {
      name        = "example"
      description = "This team deals with all the things"
    
      member {
          id   = "${opsgenie_user.first.id}"
          role = "admin"
      }
    }
    
  2. Navigate to app.opsgenie.com/teams/dashboard/<team id of test team>/members

  3. Manually add second user to the test team

  4. Run plan against the previously mentioned terraform file and notice that it wants to remove the second user from the team

JordanSussman avatar Feb 03 '20 15:02 JordanSussman

But that sounds right, when you create team via TF it manages that resource in authoritative way, this means that if anything was 'clicked' additionally it will be reset back to state defined in Terraform. I think that overall mixing of TF managed resources with manual additions beats the purpose of TF

jaceq avatar Feb 05 '20 08:02 jaceq

But that sounds right, when you create team via TF it manages that resource in authoritative way, this means that if anything was 'clicked' additionally it will be reset back to state defined in Terraform. I think that overall mixing of TF managed resources with manual additions beats the purpose of TF

I don't disagree that the behavior is expected, however I still want the provider to support this specific use case by providing the opsgenie_team_membership resource. Which would allow me to do something like the following:

resource "opsgenie_user" "first" {
  username  = "[email protected]"
  full_name = "name "
  role      = "User"
}

resource "opsgenie_user" "second" {
  username  = "[email protected]"
  full_name = "name "
  role      = "User"
}

resource "opsgenie_team" "test" {
  name        = "example"
  description = "This team deals with all the things"
  
  lifecycle {
    ignore_changes = [
      member,
    ]
  }
}

resource "opsgenie_team_membership" "first" {
    id   = "${opsgenie_user.first.id}"
    role = "admin"
    team = "${opsgenie_team.test.id}"
}

resource "opsgenie_team_membership" "second" {
    id   = "${opsgenie_user.second.id}"
    role = "admin"
    team = "${opsgenie_team.test.id}"
}

Quite a few other providers provide similar workflows by separateing the high level creation of a resource from the smaller details. For example: aws_volume_attachment.

I'm happy to contribute this functionality if the maintainers agree it would be accepted.

JordanSussman avatar Feb 09 '20 17:02 JordanSussman

I would very welcome a(ny) change that makes the provider able to ignore team membership. I want TF to create the team, and that's just it.

arnisoph avatar Feb 17 '20 20:02 arnisoph

I've build a very ugly hack to workaround this -issue- behaviour (simply disable the member attribute at all). @ffahri could you share your opinion to @JordanSussman 's comment please? thx :)

arnisoph avatar Feb 18 '20 15:02 arnisoph

Hey @arnisoph @JordanSussman If there are use cases for managing users via ui etc we should provide this functionality to provider. However question is should we change current behaviour (which can be hard to migrate some of users not sure)

team {
user{}
user{}
}

or we introduce new resource for this just for creating and managing teams without looking members

team_only{}

or flag inside team resource such as below example

team {
manage_members=false
}

ffahri avatar Feb 19 '20 07:02 ffahri

I think having the optional flag "manage_members=false" (member{} is already optional anyway) and providing additional resources like team_membership{} would be the easiest for the users.

AWS and GCP already have a similar approach for some time:

https://www.terraform.io/docs/providers/google/r/google_project_iam.html#google_project_iam_member-1

arnisoph avatar Feb 19 '20 08:02 arnisoph

@ffahri I could prepare PR for that, what do you think?

arnisoph avatar Mar 03 '20 09:03 arnisoph

I think having the optional flag "manage_members=false" (member{} is already optional anyway) and providing additional resources like team_membership{} would be the easiest for the users.

AWS and GCP already have a similar approach for some time:

https://www.terraform.io/docs/providers/google/r/google_project_iam.html#google_project_iam_member-1

I agree with this approach compared to the other options suggested.

JordanSussman avatar Mar 03 '20 14:03 JordanSussman

I started to prepare a PR that first adds sth like "manage_members=false" and later a separate PR that adds new resources to maintain team membership. all those changes should be non-breaking for our users.

arnisoph avatar Mar 04 '20 12:03 arnisoph

@JordanSussman you can find the first PR in #79 . It makes it possible to disable Terraform to maintain team membership. This is useful, if you apply changes via OpsGenie web UI. Would you like to try this PR out? I can provide you the binary if needed.

A second PR would add a new resource type for actual team membership.

arnisoph avatar Mar 10 '20 17:03 arnisoph

@ffahri if this PR is fine and completed/merged I'd continue with the second PR for the new team_membership resource.

arnisoph avatar Mar 10 '20 19:03 arnisoph

ignore_members flag is in 0.2.9 release. we are waiting for this release. We can this resource to v0.3.0 release. thanks @arnisoph

ffahri avatar Mar 23 '20 12:03 ffahri

@arnisoph for the second pr what is on your mind? I dont think we should not change current member type for backward compatibilty. Adding new field should be okey team_membership for this

ffahri avatar Mar 23 '20 12:03 ffahri

yes, let's keep backwards compatibility "for some time". I will prepare a second PR soon, too.

arnisoph avatar Mar 23 '20 12:03 arnisoph

we also have usecase to group multiple users to multiple teams, @arnisoph any update on team_membership resource

mrajeshh avatar Jul 02 '20 19:07 mrajeshh

@mrajeshh sorry, I decided not to implement a resource such as team_membership. There's currently no need for that in my current team.

arnisoph avatar Jul 03 '20 11:07 arnisoph

Expect a PR soon.

arnisoph avatar Aug 11 '20 12:08 arnisoph

Added PR #156 . I propose deprecating the members attribute in opsgenie_team to avoid confusions about the ignore_members attribute.

arnisoph avatar Aug 13 '20 17:08 arnisoph

We have another reason to ask for a separate opsgenie_team_membership resource. Today, it is not possible to bulk-assign users to OpsGenie team using for_each (you simply can not have a for_each statement on the member {} section). In our case the list of members for each OpsGenie team comes from another provider, and we'd like to be able to do something like this:

resource "opsgenie_team" "engineers" {
  name        = "engineers"
}

resource "opsgenie_team_membership" "engineers_members" {
  for_each = local.engineer_member_ids # or similiar
  team_id   = opsgenie_team.engineers.id
    
  role = "user"
  user_id = each.key
}

dreamiurg avatar Sep 25 '20 17:09 dreamiurg

@dreamiurg it's almost done, but I have to touch it again... #167

arnisoph avatar Sep 28 '20 07:09 arnisoph

We have another reason to ask for a separate opsgenie_team_membership resource. Today, it is not possible to bulk-assign users to OpsGenie team using for_each (you simply can not have a for_each statement on the member {} section). In our case the list of members for each OpsGenie team comes from another provider, and we'd like to be able to do something like this:

resource "opsgenie_team" "engineers" {
  name        = "engineers"
}

resource "opsgenie_team_membership" "engineers_members" {
  for_each = local.engineer_member_ids # or similiar
  team_id   = opsgenie_team.engineers.id
    
  role = "user"
  user_id = each.key
}

Bit late, but you actually can by using something like this:

  dynamic "member" {
    for_each = data.opsgenie_user.admins
    content {
      id   = member.value.id
      role = "admin"
    }
  }

slushysnowman avatar Jun 14 '23 11:06 slushysnowman

This would still be a great feature to have in place.

We are adopting a 'self-service' model where we want to assign team admins via automation and then allow them to assign team users themselves. But with the current way this works, it's basically impossible using the opsgenie provider.

slushysnowman avatar Jun 14 '23 11:06 slushysnowman

@JordanSussman a bit late, but looks like but this comment does not reproduce the bug for me. This is what I get once I follow the steps you have mentioned in the comment. `No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.` Can you try it out with v0.6.26 and let me know?

koushik-swaminathan avatar Jul 06 '23 12:07 koushik-swaminathan

Closing the issue as I was not able to reproduce the issue. Please feel free to raise a new issue if it is still persistent with steps to reproduce the bug.

koushik-swaminathan avatar Jul 18 '23 06:07 koushik-swaminathan