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.
Terraform v0.12.28
azuredevops_branch_policy_min_reviewers resourceresource "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"
}
}
}
terraform destroy successful
Error: Error deleting policy in Azure DevOps: The policy configuration with ID '4' and revision '5' does not exist.
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.'
@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:
terraform refresh to sync the resources status manually, after sync finished you can destroy the resource with terraform destroy . .state with terraform state rm xxxxxx. Execute screen shot:


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):
More complex Scenario: Disabled reviewer_count manually in Web UI (so policy does not exist, but TF does have the policy configured):
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.