microsoft / terraform-provider-azuredevops

Terraform Azure DevOps provider
https://www.terraform.io/docs/providers/azuredevops/
MIT License
386 stars 276 forks source link

Serviceendpoint azurecr : failed to obtain an access token of identity using cached refresh token #978

Open MathKlim opened 8 months ago

MathKlim commented 8 months ago

Community Note

Hi, I'm trying to automate the creation of an azurecr service connection, but I'm not able to.

Terraform (and Azure DevOps Provider) Version

Terraform v1.7.3 on linux_amd64

Affected Resource(s)

Terraform Configuration Files

# ####################### Providers #######################

terraform {
  required_version = ">=1.5.0"
  required_providers {

    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=3.83.0"
    }

    azuredevops = {
      source  = "microsoft/azuredevops"
      version = ">= 0.1.0"
    }

    azuread = {
      source  = "hashicorp/azuread"
      version = ">= 2.15.0"
    }

  }
}

# ####################### Azure Configuration #######################
data "azurerm_subscription" "current" {}

data "azuread_client_config" "current" {}
data "azurerm_resource_group" "current" {
  name = var.resource_group_name
}

data "azurerm_container_registry" "current" {
  name                = var.acr_name
  resource_group_name = data.azurerm_resource_group.current.name
}

resource "random_uuid" "current" {}

resource "azuread_application" "current" {
  display_name = "spn-azdevops-sbx"
  owners = [
    data.azuread_client_config.current.object_id
  ]

  sign_in_audience = "AzureADandPersonalMicrosoftAccount"

  feature_tags {
    enterprise            = true
    custom_single_sign_on = true
  }

  api {
    requested_access_token_version = 2
    oauth2_permission_scope {
      admin_consent_description  = "Allow the application to access example on behalf of the signed-in user."
      admin_consent_display_name = "Access example"
      enabled                    = true
      id                         = random_uuid.current.result
      type                       = "User"
      user_consent_description   = "Allow the application to access example on your behalf."
      user_consent_display_name  = "Access example"
      value                      = "user_impersonation"
    }

  }

  web {
    homepage_url  = "https://VisualStudio/SPN"
    redirect_uris = ["https://VisualStudio/SPN"]

    implicit_grant {
      access_token_issuance_enabled = true
      id_token_issuance_enabled     = true
    }
  }

  description = "Application used to create the Docker service connection between azure devops and the sandbox environment. Managed by Terraform."
}

resource "azuread_service_principal" "current" {
  client_id                    = azuread_application.current.client_id
  app_role_assignment_required = false
  owners = [
    data.azuread_client_config.current.object_id
  ]
}

resource "azuread_service_principal_password" "current" {
  service_principal_id = azuread_service_principal.current.id
  end_date_relative    = "${24 * 365 * 2}h" # 2 years
}

module "spn_acr_roles" {
  source = "../az_role_assignment"

  count = length(var.spn_acr_roles) # ["AcrPush", "AcrImageSigner"]

  scope                = data.azurerm_container_registry.current.id
  role_definition_name = var.spn_acr_roles[count.index]
  principal_id         = azuread_service_principal.current.id
}

# ####################### Azure DevOps Configuration #######################

data "azuredevops_project" "current" {
  name = "${var.project_configuration.team}-${var.project_configuration.project_name}"
}

resource "azuredevops_serviceendpoint_azurecr" "current" {
  project_id                = data.azuredevops_project.current.id
  service_endpoint_name     = "spn-sc-${var.project_configuration.project_name}-${var.acr_name}"
  resource_group            = data.azurerm_container_registry.current.resource_group_name
  azurecr_spn_tenantid      = azuread_service_principal.current.client_id
  azurecr_name              = data.azurerm_container_registry.current.name
  azurecr_subscription_id   = data.azurerm_subscription.current.subscription_id
  azurecr_subscription_name = data.azurerm_subscription.current.display_name
  description               = "Service connection between the project ${data.azuredevops_project.current.name} and the Azure Container Registry ${data.azurerm_container_registry.current.name}. Managed by Terraform."
}

Debug Output

https://gist.github.com/MathKlim/e997047a9cbbfa061dc8c7864b8b9b80

I do get the following error in the terminal.

β”‚ Error: waiting for service endpoint ready. Error looking up service endpoint given ID (32d963ca-8d13-4a25-818f-8e4447f66905) and project ID (d7fff28e-369e-4233-bedf-2eab9f303cd2): map[severity: state:Failed statusMessage:HandleMsalServiceExceptionFromRefreshTokenUse: Failed to obtain an access token of identity dd2bdf7b-482d-7dd1-b821-b298fc1f9d28 using cached refresh token. Sign-in required.]
β”‚ β”‚ with azuredevops_serviceendpoint_azurecr.current, β”‚ on main.tf line 88, in resource "azuredevops_serviceendpoint_azurecr" "current": β”‚ 88: resource "azuredevops_serviceendpoint_azurecr" "current" {

Expected Behavior

The service connection should be created.

Actual Behavior

Everything is created but the service connection.

Steps to Reproduce

  1. terraform apply

Important Factoids

Where did I miss something ?

References

xuzhang3 commented 8 months ago

@MathKlim What permissions does the PAT assigned? It appears that the PAT used to create the service connection does not have enough permissions.

thegooddalton commented 6 months ago

@MathKlim You're using; azuread_service_principal.current.client_id for the azurecr_spn_tenantid try;

azuread_service_principal.current.application_tenant_id

PS. I'd be interested to know what API Permissions you're executing Service Principal has? We are currently facing a similar issue, I've granted the executing Service Principal 'Owner' Rights on Resource Group containing the Container Registry - But the Service Principal also need's permission in Entra so it can create and manage the Service Principal used by the Service Endpoint - Not currently playing ball!