OpsLevel / terraform-provider-opslevel

Terraform provider for OpsLevel.com
https://registry.terraform.io/providers/OpsLevel/opslevel/latest/docs
MIT License
8 stars 5 forks source link

Db/fix team member keep or delete #351

Closed davidbloss closed 2 months ago

davidbloss commented 2 months ago

Issues

Don't remove members assigned to teams in the UI

Changelog

Tophatting

With this config file

# main.tf
resource "opslevel_team" "example" {
  name             = "foo"
  responsibilities = "Responsible for foo frontend and backend"
  aliases          = ["bar1234", "baz3334", "foo3334", "foo3324"]
  # member {
  #   email = "david+pat@opslevel.com"
  #   role  = "contributor"
  # }
}

Create Team (no members)

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # opslevel_team.example will be created
  + resource "opslevel_team" "example" {
      + aliases          = [
          + "bar1234",
          + "baz3334",
          + "foo3334",
          + "foo3324",
        ]
      + id               = (known after apply)
      + last_updated     = (known after apply)
      + name             = "foo"
      + responsibilities = "Responsible for foo frontend and backend"
    }

Plan: 1 to add, 0 to change, 0 to destroy.
opslevel_team.example: Creating...
opslevel_team.example: Creation complete after 2s [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Add Members to Team in UI ✅

Run terraform plan, no members mentioned

opslevel_team.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # opslevel_team.example will be updated in-place
  ~ resource "opslevel_team" "example" {
      ~ aliases          = [
            # (1 unchanged element hidden)
            "baz3334",
          - "foo3324",
            "foo3334",
          + "foo3324",
        ]
        id               = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg"
      + last_updated     = (known after apply)
        name             = "foo"
        # (1 unchanged attribute hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Add member to config file

resource "opslevel_team" "example" {
  name             = "foo"
  responsibilities = "Responsible for foo frontend and backend"
  aliases          = ["bar1234", "baz3334", "foo3334", "foo3324"]
  member {
    email = "david+pat@opslevel.com"
    role  = "contributor"
  }
}

Run terraform apply, all members from UI replaced with members in TF config

opslevel_team.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # opslevel_team.example will be updated in-place
  ~ resource "opslevel_team" "example" {
      ~ aliases          = [
            # (1 unchanged element hidden)
            "baz3334",
          - "foo3324",
            "foo3334",
          + "foo3324",
        ]
        id               = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg"
      + last_updated     = (known after apply)
        name             = "foo"
        # (1 unchanged attribute hidden)

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
opslevel_team.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]
opslevel_team.example: Modifications complete after 0s [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Remove member from config file

resource "opslevel_team" "example" {
  name             = "foo"
  responsibilities = "Responsible for foo frontend and backend"
  aliases          = ["bar1234", "baz3334", "foo3334", "foo3324"]
  # member {
  #   email = "david+pat@opslevel.com"
  #   role  = "contributor"
  # }
}

Remove TF added member terraform apply

opslevel_team.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # opslevel_team.example will be updated in-place
  ~ resource "opslevel_team" "example" {
      ~ aliases          = [
            # (1 unchanged element hidden)
            "baz3334",
          - "foo3324",
            "foo3334",
          + "foo3324",
        ]
        id               = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg"
      + last_updated     = (known after apply)
        name             = "foo"
        # (1 unchanged attribute hidden)

      - member {
          - email = "david+pat@opslevel.com" -> null
          - role  = "contributor" -> null
        }
    }

Plan: 0 to add, 1 to change, 0 to destroy.
opslevel_team.example: Modifying... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]
opslevel_team.example: Modifications complete after 0s [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Add Member back with TF ✅

Destroy Team and members, terraform destroy

opslevel_team.example: Refreshing state... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # opslevel_team.example will be destroyed
  - resource "opslevel_team" "example" {
      - aliases          = [
          - "bar1234",
          - "baz3334",
          - "foo3324",
          - "foo3334",
        ] -> null
      - id               = "Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg" -> null
      - name             = "foo" -> null
      - responsibilities = "Responsible for foo frontend and backend" -> null

      - member {
          - email = "david+pat@opslevel.com" -> null
          - role  = "contributor" -> null
        }
    }

Plan: 0 to add, 0 to change, 1 to destroy.
opslevel_team.example: Destroying... [id=Z2lkOi8vb3BzbGV2ZWwvVGVhbS8xOTExMg]
opslevel_team.example: Destruction complete after 0s

Destroy complete! Resources: 1 destroyed.
davidbloss commented 2 months ago

What happens for this tophatting step?

Remove member from config file

I updated that step to make it more clear but the member was removed

# main.tf
  # This was originally deleted but I put it back in (commented out) to be clear
  # member {
  #   email = "david+pat@opslevel.com"
  #   role  = "contributor"
  # }