Terraform-provider-azuredevops: azuredevops_branch_policy_min_reviewers resource fails to detect drift on change

Created on 29 Jul 2020  路  7Comments  路  Source: microsoft/terraform-provider-azuredevops

After Branch policy 'Requires a minimum number of reviewers' is manually disabled in AzDO UI, Terraform fails to notice the drift, and fails when trying to apply Terraform configuration to recover.

Community Note

  • Please vote on this issue by adding a 馃憤 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and Azure DevOps Provider) Version

Terraform v0.12.28

  • provider.azuredevops v0.0.1

Affected Resource(s)

  • azuredevops_branch_policy_min_reviewers resource

Terraform Configuration Files

resource "azuredevops_branch_policy_min_reviewers" "repo_build_reviewers" {
  count      = var.enable_repo_build_reviewers ? 1 : 0
  project_id = azuredevops_project.project.id

  enabled  = true
  blocking = true

  settings {
    reviewer_count     = var.policy_reviewer_count
    submitter_can_vote = false

    scope {
      repository_id  = azuredevops_git_repository.repo.id
      repository_ref = azuredevops_git_repository.repo.default_branch
      match_type     = "Exact"
    }

    scope {
      repository_id  = azuredevops_git_repository.repo.id
      repository_ref = "refs/heads/releases"
      match_type     = "Prefix"
    }
  }
}

Expected Behavior

terraform destroy successful

Actual Behavior

Error: Error deleting policy in Azure DevOps: The policy configuration with ID '4' and revision '5' does not exist.

Steps to Reproduce

Created a AzureDevops project, repository, and azuredevops_branch_policy_min_reviewers policy from this repo: https://github.com/andrefcpimentel2/terraform-provider-azuredevops-cicd
When changing manually the number of reviewers and running tf apply again, it change back to the desired stage. But when disabling the option 'Require a minimum number of reviewers' on the slide button, and running Terraform again, TF does not detect the drift. Also TF destroy fails throwing the message:
'Error: Error deleting policy in Azure DevOps: The policy configuration with ID '4' and revision '5' does not exist.'

Important Factoids

References

  • #0000
question wontfix

All 7 comments

@andrefcpimentel2 It's not recommend to manage resource with both Terraform and Web UI. Terraform cannot detect the resource changes when the change is not managed by Terraform. Terraform manage the resource base on the terraform.tfstate file, the policy configures is in the terraform.tfstate file means the resource exist, when terraform destroy applied, terraform will try to destroy the resource but you have deleted the resource from web UI, the service will return an error with resource not found

In your scenario, you have to choice to get you configuration work:

  1. Use terraform refresh to sync the resources status manually, after sync finished you can destroy the resource with terraform destroy .
  2. Manually remove the min policy config from .state with terraform state rm xxxxxx.

Execute screen shot:

  • create
    image
  • change the policy configuration from web UI and refresh
    image

thakns @xuzhang3

Fix 1 details - trying to understand for use in the real world:

So if we have a Pipeline that is calling Terraform init/plan/apply, and we can update the Terraform configuration in code as well, would the following be needed in addition to 1. above, to destroy the azuredevops_branch_policy_min_reviewers resource (and then create again in a subsequent run)?

I'm assuming here that if we manually disabled reviewer_count manually in Web UI, that Terraform thinks that the policy does not exist (but please could you confirm if that is correct or not?)

Simpler Scenario: Changed reviewer_count number (but not turned off) manually in Web UI - so policy exists (just set to different number than TF):

  • a) Pipeline: Comment out Terraform init/plan/apply, add terraform refresh command instead. Run. Now state file is correct for the actual environment (in this scenario, the policy has been removed in Web UI)
  • b) Pipeline: Uncomment Terraform init/plan/apply, comment out Terraform refresh.
  • c) Terraform config: Change azuredevops_branch_policy_min_reviewers resource in Terraform to match reality & refreshed state file e.g. 10 in above, we have just changed to match the Terraform config with the state file (where just a setting rather than a repo). Run pipeline e.g. terraform init/plan/apply.
  • d) Terraform config: Add TF azuredevops_branch_policy_min_reviewers resource back in. Run pipeline terraform init/plan/apply. The policy will be added as if a new resource

More complex Scenario: Disabled reviewer_count manually in Web UI (so policy does not exist, but TF does have the policy configured):

  • a) Pipeline: Comment out Terraform init/plan/apply, add terraform refresh command instead. Run. Now state file is correct for the actual environment
  • b) Pipeline: Uncomment Terraform init/plan/apply, comment out Terraform refresh.
  • c) Terraform config: Comment out azuredevops_branch_policy_min_reviewers resource in Terraform e.g. not destroy as azuredevops_branch_policy_min_reviewers resource was manually disabled so does not exist in the state file (?). Run pipeline e.g. terraform init/plan/apply
  • d) Terraform config: Add TF azuredevops_branch_policy_min_reviewers resource back in. Run pipeline terraform init/plan/apply. The policy will be added as if a new resource

thanks

@rswe If your resource is managed by Terraform only. You don't need to do the sync operation. If you manage the resources with Terraform and Web UI , you need sync the resource status, but not recommend, unexpected error may happen.

@xuzhang3 Agree we would be trying to manage resources by Terraform only, and restricting privs in AzDO to encourage this good behaviour. But some Administrators would have the permission to make a small change to a Web UI setting (against recommendations) that would mess up the Terraform state and cause us to need to use the workaround.
That's why I wanted to clarify the details of the workaround (while hoping it is not common, realistically it will happen sometimes so we need to recover)

Closing this issue . Feel free to reopen it if you have questions.

We have this issue, I believe this is a provider defect. Here's why:
Terraform did refresh the state file as part of the plan step, and it found 3876:

module.product_team[0].azuredevops_branch_policy_auto_reviewers.devops: Refreshing state... [id=3876]
module.product_team[0].azuredevops_branch_policy_auto_reviewers.azure: Refreshing state... [id=3877]

  # module.product_team[0].azuredevops_branch_policy_auto_reviewers.azure will be updated in-place
  ~ resource "azuredevops_branch_policy_auto_reviewers" "azure" {
      ~ blocking   = false -> true

then in the Apply step it errored:

module.product_team[0].azuredevops_branch_policy_auto_reviewers.devops: Modifying... [id=3876]
module.product_team[0].azuredevops_branch_policy_auto_reviewers.azure: Modifying... [id=3877]
module.product_team[0].azuredevops_branch_policy_auto_reviewers.azure: Modifications complete after 0s [id=3877]
module.product_team[0].azuredevops_group_membership.queue: Modifying... [id=*]
module.product_team[0].azuredevops_group_membership.queue: Still modifying... [id=*, 10s elapsed]
module.product_team[0].azuredevops_group_membership.queue: Modifications complete after 17s [id=*]

Error: Error updating policy in Azure DevOps: The policy configuration with ID '3876' and revision '3' does not exist.

  on ../modules/product_team/main.tf line 157, in resource "azuredevops_branch_policy_auto_reviewers" "devops":
 157: resource "azuredevops_branch_policy_auto_reviewers" "devops" {

When I looked at the API it requires the "revision" attribute.

So it appears _to me_ that the provider does not record the revision in the state file as part off the ID. Where is the provider getting the revision number from????

My hunch is that when a user changes the policy via the UI, the revision is changed and whatever the provider is sending is not matched in the update REST transaction.

I await your responses with keen interest!

I have been able to reproduce the error message"Error: Error updating policy in Azure DevOps: The policy configuration with ID '3876' and revision '3' does not exist." however only if the policy is manually deleted in the UI _after_ the plan has been run. Example:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

azuredevops_project.p: Refreshing state... [id=64b1e548-4731-400e-8028-a79300a068c8]
azuredevops_user_entitlement.user: Refreshing state... [id=64b1e548-4731-400e-8028-a79300a068c8]
data.azuredevops_users.user: Refreshing state... [id=users#64b1e548-4731-400e-8028-a79300a068c8=]
azuredevops_git_repository.r: Refreshing state... [id=64b1e548-4731-400e-8028-a79300a068c8]
azuredevops_branch_policy_auto_reviewers.p: Refreshing state... [id=135]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # azuredevops_branch_policy_auto_reviewers.p will be updated in-place
  ~ resource "azuredevops_branch_policy_auto_reviewers" "p" {
        blocking   = true
        enabled    = true
        id         = "135"
        project_id = "64b1e548-4731-400e-8028-a79300a068c8"

      ~ settings {
            auto_reviewer_ids  = [
                "b64b1e548-4731-400e-8028-a79300a068c8",
            ]
          ~ message            = "Auto reviewer 4" -> "Auto reviewer 5"
            path_filters       = [
                "*/src/*.ts",
            ]
            submitter_can_vote = false

            scope {
                match_type     = "Exact"
                repository_id  = "64b1e548-4731-400e-8028-a79300a068c8"
                repository_ref = "refs/heads/master"
            }
        }
    }

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

------------------------------------------------------------------------

This plan was saved to: p

To perform exactly these actions, run the following command to apply:
    terraform apply "p"

Now Manually delete the policy 135

todo/$ tfa
azuredevops_branch_policy_auto_reviewers.p: Modifying... [id=135]

Error: Error updating policy in Azure DevOps: The policy configuration with ID '135' and revision '3' does not exist.

  on main.tf line 37, in resource "azuredevops_branch_policy_auto_reviewers" "p":
  37: resource "azuredevops_branch_policy_auto_reviewers" "p" {

TIL This is completely normal for Terraform. It's quite possible for a race condition to occur wherever the 'drift' happens between plan and apply.

Was this page helpful?
0 / 5 - 0 ratings