簡體   English   中英

如何使用 Terraform 自動創建服務主體或 MSI,以在 Azure 管道中使用以管理 AKS 資源?

[英]How do I automatically create service principals or MSIs with Terraform for use in Azure Pipelines to manage AKS resources?

我正在按照官方文檔創建 Azure Kube.netes 集群 我需要先手動創建服務主體並提供 client_id 和 client_secret 的文檔 state。

手動操作不是一種選擇。

這是我的服務主體的代碼。 它裝飾有指向最新 Terraform 文檔的鏈接以供參考。

data "azurerm_subscription" "current" {}
data "azuread_client_config" "current" {}

resource "random_id" "current" {
  byte_length = 8
  prefix      = "ExternalDnsTf"
}

# Create Azure AD App.
# https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application
resource "azuread_application" "current" {
  display_name = random_id.current.hex
  owners       = [data.azuread_client_config.current.object_id]

}

# Create Service Principal associated with the Azure AD App
# https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal
resource "azuread_service_principal" "current" {
  application_id               = azuread_application.current.application_id
  app_role_assignment_required = false
  owners                       = [data.azuread_client_config.current.object_id]
}

# Create Service Principal password
# https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_password
resource "azuread_application_password" "current" {
  application_object_id = azuread_application.current.object_id
}

# Create role assignment for service principal
# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment
resource "azurerm_role_assignment" "current" {
  scope                = data.azurerm_subscription.current.id
  role_definition_name = "Contributor"

 # When assigning to a SP, use the object_id, not the appId
 # see: https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-cli
  principal_id = azuread_service_principal.current.object_id
}

我的管道中不斷出現以下錯誤:(注意,我是訂閱的所有者)

ApplicationsClient.BaseClient.Post(): unexpected status 403 with OData
│ error: Authorization_RequestDenied: Insufficient privileges to complete the
│ operation.

我想做的是消除設置支持服務的手動步驟。 以 ExternalDNS 為例。 我需要使用az ad sp create-for-rbac -n ExternalDnsServicePrincipal; az role assignment create --role "Reader" --assignee <appId GUID> --scope <resource group resource id>; az role assignment create --role "Contributor" --assignee <appId GUID> --scope <dns zone resource id> 的 Azure 文檔state; az ad sp create-for-rbac -n ExternalDnsServicePrincipal; az role assignment create --role "Reader" --assignee <appId GUID> --scope <resource group resource id>; az role assignment create --role "Contributor" --assignee <appId GUID> --scope <dns zone resource id>

最終,我正在嘗試創建 azure cli 命令的 terraform 版本。

create-for-rbac的支持是 github 上的一項功能請求 這曾經很好用,但發生了很大變化,不適用於當前的 API 版本。 此外,隨着 AAD Graph 被棄用,取而代之的是 Microsoft Graph API,我想知道我是否對此感到困惑。

ExternalDNS 文檔還建議使用托管服務標識 (MSI)。 Service principals, MSI, MSGraph API 集成,老實說,我不關心用哪個。 只要我不必登錄門戶以手動創建或授予權限,或手動運行az cli命令,無論當前的最佳做法是什么都可以。

編輯:權限說明

當然,我正在使用 Terraform 來提供資源。 如果我在沒有 terraform(手動或使用 bash 腳本)的情況下執行所有這些操作,我將使用azure cli我通過執行以下操作開始設置權限:

  • az login
  • az account set -s <my-subscription-id>

我是訂閱的所有者。 我可以毫無問題地運行所有命令、創建 SP、MSI、分配角色等。

在管道中, 我使用的是 charleszipp az pipelines terraform插件。 在日志中,我看到:

  • az login --service-principal -t <my-tenant-id> -u *** -p ***
  • az account set -s <my-subscription-id>

我不確定這是否有所作為。 我將其解釋為最終會在登錄並設置帳戶訂閱后執行命令,就像我手動執行的那樣。

從技術上講,我沒有在其中幾個任務中使用服務連接。 但是,在需要的地方,我創建了一個服務連接並將其 Scope 定義為訂閱級別。 它的類型為 Azure 資源管理器。

但是,如果我單擊“管理服務主體”,它會將我帶到未定義權限的門戶。

雖然我是訂閱的所有者,但我不是根管理組。 我由其他人擁有/提供。 最終,他們控制了 Active Directory。 我無法添加或編輯權限。 如果我嘗試在權限 API 和 select Microsoft Graph 下添加任何內容,它會提示需要授權。 Grant Admin Consent for <parent organization是灰色的。

但是,如果我是訂閱的所有者,那為什么會很重要呢? 如果我可以通過 az cli 命令行做任何我想做的事,是什么阻止我在管道中做同樣的事情?

為此,我正在使用用戶管理的身份,這似乎最簡單,對我來說效果很好。

resource "azurerm_user_managed_identity", "mi" {
    resource_group_name = "rg"
    name = "mi"
    location = "eastus"
}

resource "azurerm_role_assignment" "ra" {
    scope = azurerm_subnet.sn.id  // subnet I created earlier
    role_definition_name = "Network Contributor"  // required with kubenet
    principal_id = azurerm_user_managed_identity.mi.principal_id
}

resource "azurerm_kubernetes_cluster" "aks" {
    name = "aks"
    identity {
        type = "UserAssigned"
        user_assigned_identity_id = azurerm_user_managed_identity.mi.id
    }
    <...remaining attributes...>
    depends_on = [azurerm_role_assignment.ra] // just to be safe
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM