Azure devops 管道地形错误 - 尝试角色分配时出现 403

Azure devops pipeline terraform error - 403 when attempting role assignment

我正在尝试为通过 terraform 创建的系统分配托管身份部署 aks 集群和角色分配,但我收到 403 响应

azurerm_role_assignment.acrpull_role: Creating...
╷
│ Error: authorization.RoleAssignmentsClient#Create: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client '626eac40-c9dd-44cc-a528-3c3d3e069e85' with object id '626eac40-c9dd-44cc-a528-3c3d3e069e85' does not have authorization to perform action 'Microsoft.Authorization/roleAssignments/write' over scope '/subscriptions/7b73e02c-dbff-4eb7-9d73-e73a2a17e818/resourceGroups/myaks-rg/providers/Microsoft.ContainerRegistry/registries/aksmattcloudgurutest/providers/Microsoft.Authorization/roleAssignments/c144ad6d-946f-1898-635e-0d0d27ca2f1c' or the scope is invalid. If access was recently granted, please refresh your credentials."
│ 
│   with azurerm_role_assignment.acrpull_role,
│   on main.tf line 53, in resource "azurerm_role_assignment" "acrpull_role":
│   53: resource "azurerm_role_assignment" "acrpull_role" {
│ 
╵

这只发生在 Azure Devops 管道中。我的管道如下所示...

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
  
- task: TerraformInstaller@0
  inputs:
    terraformVersion: '1.0.7'

- task: TerraformCLI@0
  inputs:
    command: 'init'
    workingDirectory: '$(System.DefaultWorkingDirectory)/Shared/Pipeline/Cluster'
    backendType: 'azurerm'
    backendServiceArm: 'Matt Local Service Connection'
    ensureBackend: true
    backendAzureRmResourceGroupName: 'tfstate'
    backendAzureRmResourceGroupLocation: 'UK South'
    backendAzureRmStorageAccountName: 'tfstateq7nqv'
    backendAzureRmContainerName: 'tfstate'
    backendAzureRmKey: 'terraform.tfstate'
    allowTelemetryCollection: true

- task: TerraformCLI@0
  inputs:
    command: 'plan'
    workingDirectory: '$(System.DefaultWorkingDirectory)/Shared/Pipeline/Cluster'
    environmentServiceName: 'Matt Local Service Connection'
    allowTelemetryCollection: true

- task: TerraformCLI@0
  inputs:
    command: 'validate'
    workingDirectory: '$(System.DefaultWorkingDirectory)/Shared/Pipeline/Cluster'
    allowTelemetryCollection: true

- task: TerraformCLI@0
  inputs:
    command: 'apply'
    workingDirectory: '$(System.DefaultWorkingDirectory)/Shared/Pipeline/Cluster'
    environmentServiceName: 'Matt Local Service Connection'
    allowTelemetryCollection: false

我正在使用此处的 Terraform 任务 - https://marketplace.visualstudio.com/items?itemName=charleszipp.azure-pipelines-tasks-terraform

这是我的地形文件

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=2.46.0"
    }
  }
}

provider "azurerm" {
   features {}
}

resource "azurerm_resource_group" "TerraformCluster" {
  name     = "terraform-cluster"
  location = "UK South"
}

resource "azurerm_kubernetes_cluster" "TerraformClusterAKS" {
  name                = "terraform-cluster-aks1"
  location            = azurerm_resource_group.TerraformCluster.location
  resource_group_name = azurerm_resource_group.TerraformCluster.name
  dns_prefix          = "terraform-cluster-aks1"

  network_profile {
    network_plugin = "azure"
  }

  default_node_pool {
    name       = "default"
    node_count = 1
    vm_size    = "Standard_D2_v2"
  }

  identity {
    type = "SystemAssigned"
  }

  tags = {
    Environment = "Production"
  }
}

data "azurerm_container_registry" "this" {
  depends_on = [
    azurerm_kubernetes_cluster.TerraformClusterAKS
  ]
  provider            = azurerm
  name                = "aksmattcloudgurutest"
  resource_group_name = "myaks-rg"
}

resource "azurerm_role_assignment" "acrpull_role" {
  scope                = data.azurerm_container_registry.this.id
  role_definition_name = "AcrPull"
  principal_id         = azurerm_kubernetes_cluster.TerraformClusterAKS.identity[0].principal_id
}

我哪里错了?

AAD 中与您的 ADO 服务连接 ('Matt Local Service Connection') 关联的服务主体需要在资源范围内分配 所有者 角色,或者以上(取决于您将在其他地方分配权限)。您可以阅读有关各种角色的详细信息 here 两个最常用的角色是所有者和贡献者,主要区别在于所有者允许管理角色分配。

作为这项工作的一部分,您还应该熟悉 principle of least privilege(如果您还不知道)。在这种情况下将如何适用;如果服务委托人只需要资源级别的所有者,那么不要在资源组或订阅级别为其分配所有者,只是因为这样更方便,您以后可以随时更新范围,但要撤消任何损坏要困难得多(假设是恶意或缺乏经验的演员)在被利用后过度宽松的角色分配。

我尽一切努力将此现有存储服务 re-connect 到 Azure Devops 管道以启用 Terraform 部署。

尝试但未成功:中断 tf 状态的租约,删除 tf 状态,更新 tfstate 的租约,通过 powershell 在 ADO 中内联命令和 bash 清除terraform,re-install Terraform 插件等等等等)

有效的方法: 最终的工作是使用新的存储容器和新的 SAS 令牌创建一个新的存储帐户。

这解决了从 Azure Devops 为 Terraform 部署访问包含 ADLS 中的 TFState 的 Blob 时出现的 403 禁止错误。这并没有解释如何或为什么,访问控制/iam/访问策略没有改变。在不同的存储帐户名称下使用完全相同的设置 拆除并重新创建包含 TFState 的存储。