Open rubenaster opened 4 months ago
My use case for this is to set the permissions for the build service user on a repository, likely same as OP.
This is a workaround using local-exec
, found to be working on stock Terraform Cloud agents:
data "azuredevops_client_config" "org" {}
data "azuredevops_project" "project" {
project_id = var.project_id
}
locals {
organization_name = regex("https?://.+?/(.+?)/", data.azuredevops_client_config.org.organization_url)[0]
build_service_name = "${data.azuredevops_project.project.name} Build Service (${local.organization_name})"
}
resource "azuredevops_git_repository" "repo" {
# ...
}
resource "terraform_data" "assign_build_user_permissions" {
lifecycle {
replace_triggered_by = [
azuredevops_git_repository.repo
]
}
provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = replace(<<-EOT
DESCRIPTOR=$(curl "https://vssps.dev.azure.com/$ORGNAME/_apis/identities" --get --data "searchFilter=DisplayName" --data-urlencode "filterValue=$BUILDUSER" --data 'api-version=7.0-preview' --location -u ":$AZDO_PERSONAL_ACCESS_TOKEN" -s -f | jq -r '.value[].descriptor')
curl "https://dev.azure.com/$ORGNAME/_apis/AccessControlEntries/2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87?api-version=7.0-preview" --data $${JSONTEMPLATE//@DESCRIPTOR/$DESCRIPTOR} -u ":$AZDO_PERSONAL_ACCESS_TOKEN" -H 'Content-Type: application/json' -s -f
EOT
, "\r", "") # convert to unix newlines (otherwise $DESCRIPTOR ends up with an extra \r)
environment = {
BUILDUSER = local.build_service_name
ORGNAME = local.organization_name
JSONTEMPLATE = jsonencode({
token = "repoV2/${data.azuredevops_project.project.project_id}/${azuredevops_git_repository.repo.id}"
merge = true
accessControlEntries = [
# GenericContribute, CreateTag, PullRequestContribute
for allow in [4, 32, 16384] : { descriptor = "@DESCRIPTOR", allow = allow }
]
})
}
}
}
I found that it is possible to assign permissions to users. Even though the docs say it is only possible to groups. What you need is a user descriptor. You can get one for Build Service using data block:
data "azuredevops_users" "build_service" {
principal_name = azuredevops_project.main.id
}
resource "azuredevops_git_permissions" "project_build_service" {
project_id = azuredevops_git_repository.project.project_id
repository_id = azuredevops_git_repository.projectid
//Then use the descriptor in principal param
principal = data.azuredevops_users.build_service.users[0].descriptor
permissions = {
GenericContribute = "Allow"
}
}
Worked for me as well with a few syntax tweaks, here's my final code:
data "azuredevops_users" "build_service" {
principal_name = var.project_id
}
resource "azuredevops_git_permissions" "build_service_permission" {
project_id = var.project_id
repository_id = azuredevops_git_repository.repo.id
principal = one(data.azuredevops_users.build_service.users).descriptor
permissions = {
GenericContribute = "Allow"
#PullRequestContribute = "Allow"
#CreateTag = "Allow"
}
}
Community Note
Description
Currently, azuredevops_git_permissions allows only to use groups as service principals, but not just single users. It also explicitly informs about that.
In general you're able to configure repository permissions for single user. My request is to reflect this also in the resource.
New or Affected Resource(s)
Potential Terraform Configuration