Terraform-provider-azuredevops: azuredevops_serviceendpoint_azurecr expose service_principal_id on output

Created on 11 Dec 2020  ·  6Comments  ·  Source: microsoft/terraform-provider-azuredevops

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

Description

When creating azuredevops_serviceendpoint_azurecr I would like to fetch the service_principal_id it creates to make the proper permission changes

New or Affected Resource(s)

  • azuredevops_serviceendpoint_azurecr

References

Example: I create a connection with azuredevops_serviceendpoint_azurecr and I want to allow the service_principal it generates to AcrPush

resource "azuredevops_serviceendpoint_azurecr" "this" {
 ....
}

resource "azurerm_role_assignment" "this" {
  scope                = "registry_id"
  role_definition_name = "AcrPush"
  principal_id         = azuredevops_serviceendpoint_azurecr.this.service_principal_id
}
enhancement

Most helpful comment

Hello so I re-run again and this is the operation where it fails:

resource "azurerm_role_assignment" "allow_connection_to_read" {
  scope                = var.acr["id"]
  # Built in azure role
  role_definition_name = "Reader"
  principal_id         = azuredevops_serviceendpoint_azurecr.this.service_principal_id
}

The plan looks like this:

 module.azure_devops["backend"].azurerm_role_assignment.allow_connection_to_push must be replaced
-/+ resource "azurerm_role_assignment" "allow_connection_to_push" {
      ~ id                               = "/subscriptions/XXXX/resourceGroups/global-rg/providers/Microsoft.ContainerRegistry/registries/My ACR/providers/Microsoft.Authorization/roleAssignments/50bece16-452f-206d-6a95-db090a6b8c71" -> (known after apply)
      ~ name                             = "50bece16-452f-206d-6a95-db090a6b8c71" -> (known after apply)
      ~ principal_id                     = "AN_ID" -> "TOANOTHERID" # forces replacement
      ~ principal_type                   = "ServicePrincipal" -> (known after apply)
      ~ role_definition_id               = "/subscriptions/XXXXXX/providers/Microsoft.Authorization/roleDefinitions/8311e382-0749-4cb8-b61a-304f252e45ec" -> (known after apply)
      + skip_service_principal_aad_check = (known after apply)
        # (2 unchanged attributes hidden)
    }
 ```

 This means that is trying to change the service principal IDs to the ones created by azuredevops_serviceendpoint_azurecr and allow them to do operations in the Docker Registry (ACR)

 The timeout of the azurerm_role_assignment is 30 minutes so it runs for about 30 minutes and then it timeouts.

 So I was reading about azurerm_role_assignment and it does some service_principal checks as stated in the documentation: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment#skip_service_principal_aad_check

 It says that azurerm_role_assignment does some checks in the service principal (it doesn't mention which). So I decided to disable the checks by doing

 ```bash
resource "azurerm_role_assignment" "allow_connection_to_read" {
  scope                = var.acr["id"]
  # Built in azure role
  role_definition_name = "Reader"
  skip_service_principal_aad_check = true
  principal_id         = azuredevops_serviceendpoint_azurecr.this.service_principal_id
}

Now it works. So I am guessing that the service id created by azuredevops_serviceendpoint_azurecr is not passing the checks for azurerm_role_assignment. I wonder what this checks are... maybe azuredevops_serviceendpoint_azurecr needs to do additional stuff in order to pass the checks.

I was reading about this check and it seems to be a problem from azurerm_role_assignment not yours maybe but I am not sure.

All 6 comments

I think I'm running in the same issue. Service connection is created but Docker@2 task can't use it. For now I have to work around it by using Docker@1 and using a azureSubscriptionEndpoint instead of the azuredevops_serviceendpoint_azurecr which uses exactly the same subscription.

Hi @flmmartins This issue has been fixed in PR #317 and will release in v0.1.3

Hello everyone and @xuzhang3

I just used this new version (thanks!)

The service principal ID was created successfully but when I assign this to ACR via azurerm_role_assignment. Just like in the first example. It timeouts and says that azurerm_role_assignment could not find azuredevops_serviceendpoint_azurecr.this.service_principal_id

Here is the code:

# NEW CODE AFTER PR
resource "azuredevops_serviceendpoint_azurecr" "this" {
  project_id                = var.project["id"]
  service_endpoint_name     = var.connection_name
  description               = "Managed by Terraform" 
  resource_group            = var.resource_group_name
  azurecr_name              = var.acr["name"]
  azurecr_spn_tenantid      = var.spn_tenant_id
  azurecr_subscription_id   = var.subscription["id"]
  azurecr_subscription_name = var.subscription["name"]
}

resource "azurerm_role_assignment" "allow_connection_to_push" {
  scope                = var.acr["id"]
  # Built in azure role
  role_definition_name = "AcrPush"
  principal_id         = azuredevops_serviceendpoint_azurecr.this.service_principal_id
}

I wonder what's happening. Maybe because I am using the AD service principal?

I reverted the code and when I run with the code below it works:

# OLD CODE
resource "azuredevops_serviceendpoint_azurecr" "this" {
  project_id                = var.project["id"]
  service_endpoint_name     = var.connection_name
  description               = "Managed by Terraform" 
  resource_group            = var.resource_group_name
  azurecr_name              = var.acr["name"]
  azurecr_spn_tenantid      = var.spn_tenant_id
  azurecr_subscription_id   = var.subscription["id"]
  azurecr_subscription_name = var.subscription["name"]
}


data "azuread_service_principal" "this" {
  depends_on   = [azuredevops_serviceendpoint_azurecr.this]
  display_name = "${var.organization_name}-${var.project["name"]}-${var.subscription["id"]}"
}

resource "azurerm_role_assignment" "allow_connection_to_push" {
  scope                = var.acr["id"]
  # Built in azure role
  role_definition_name = "AcrPush"
  principal_id         = data.azuread_service_principal.this.id
}

@flmmartins azuredevops_serviceendpoint_azurecr creation timeout or azurerm_role_assignment creation timeout? The default creation timeout for azuredevops_serviceendpoint_azurecr is 2 minutes, Looks like I should adjust the timeout to 5 minutes, I got a timeout error too.

Hello so I re-run again and this is the operation where it fails:

resource "azurerm_role_assignment" "allow_connection_to_read" {
  scope                = var.acr["id"]
  # Built in azure role
  role_definition_name = "Reader"
  principal_id         = azuredevops_serviceendpoint_azurecr.this.service_principal_id
}

The plan looks like this:

 module.azure_devops["backend"].azurerm_role_assignment.allow_connection_to_push must be replaced
-/+ resource "azurerm_role_assignment" "allow_connection_to_push" {
      ~ id                               = "/subscriptions/XXXX/resourceGroups/global-rg/providers/Microsoft.ContainerRegistry/registries/My ACR/providers/Microsoft.Authorization/roleAssignments/50bece16-452f-206d-6a95-db090a6b8c71" -> (known after apply)
      ~ name                             = "50bece16-452f-206d-6a95-db090a6b8c71" -> (known after apply)
      ~ principal_id                     = "AN_ID" -> "TOANOTHERID" # forces replacement
      ~ principal_type                   = "ServicePrincipal" -> (known after apply)
      ~ role_definition_id               = "/subscriptions/XXXXXX/providers/Microsoft.Authorization/roleDefinitions/8311e382-0749-4cb8-b61a-304f252e45ec" -> (known after apply)
      + skip_service_principal_aad_check = (known after apply)
        # (2 unchanged attributes hidden)
    }
 ```

 This means that is trying to change the service principal IDs to the ones created by azuredevops_serviceendpoint_azurecr and allow them to do operations in the Docker Registry (ACR)

 The timeout of the azurerm_role_assignment is 30 minutes so it runs for about 30 minutes and then it timeouts.

 So I was reading about azurerm_role_assignment and it does some service_principal checks as stated in the documentation: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment#skip_service_principal_aad_check

 It says that azurerm_role_assignment does some checks in the service principal (it doesn't mention which). So I decided to disable the checks by doing

 ```bash
resource "azurerm_role_assignment" "allow_connection_to_read" {
  scope                = var.acr["id"]
  # Built in azure role
  role_definition_name = "Reader"
  skip_service_principal_aad_check = true
  principal_id         = azuredevops_serviceendpoint_azurecr.this.service_principal_id
}

Now it works. So I am guessing that the service id created by azuredevops_serviceendpoint_azurecr is not passing the checks for azurerm_role_assignment. I wonder what this checks are... maybe azuredevops_serviceendpoint_azurecr needs to do additional stuff in order to pass the checks.

I was reading about this check and it seems to be a problem from azurerm_role_assignment not yours maybe but I am not sure.

Close this issue, feel free to open another issue if you have questions.

Was this page helpful?
0 / 5 - 0 ratings