Azure API 无法识别来自 Terraform 的服务主体
Posted
技术标签:
【中文标题】Azure API 无法识别来自 Terraform 的服务主体【英文标题】:Service Principal from Terraform not recognized by Azure API 【发布时间】:2021-04-08 00:41:39 【问题描述】:需要对以下语法进行哪些特定更改,以便 terraform azurerm 提供程序能够对将使用以下代码创建的服务主体进行身份验证?
问题
第二个 Terraform 模块需要通过 azurerm 提供程序向 Azure 进行身份验证,其中 client_id
和 client_secret
是在较早的单独过程中以编程方式创建的。
Second Terraform 模块中的提供程序块如下所示:
provider "azurerm"
subscription_id = var.subscriptionId
client_id = var.clientId
client_secret = var.clientSecret
tenant_id = var.tenantId
当我们在前面的过程中验证的正确值不被接受为上面提供程序代码块中的var.clientId
和var.clientSecret
时,就会出现问题。
如何创建服务主体:
用于向 Second Terraform 模块进行身份验证的 client_id
和 client_secret
目前由 First Terraform 模块创建,其中包括以下内容:
resource "azuread_application" "appReg"
name = var.appName
resource "azuread_service_principal" "example-sp"
application_id = azuread_application.appReg.application_id
resource "azuread_service_principal_password" "example-sp_pwd"
service_principal_id = azuread_service_principal.example-sp.id
value = "long-random-string"
end_date = "2021-06-02T01:02:03Z"
data "azurerm_subscription" "thisSubscription"
subscription_id = var.subscriptionId
resource "azurerm_role_assignment" "example-sp_role_assignment"
scope = data.azurerm_subscription.thisSubscription.id
role_definition_name = "Contributor"
principal_id = azuread_service_principal.example-sp.id
resource "azuread_application_app_role" "example-role"
application_object_id = azuread_application.appReg.id
allowed_member_types = ["User", "Application"]
description = "Admins can manage roles and perform all task actions"
display_name = "Admin"
is_enabled = true
value = "administer"
在上述 First 模块运行后,Terraform 报告 Apply complete
,我们还能够在 Azure 门户中确认正确的 Active Directory 具有名称为 var.appName
的新应用注册,并且ID 等于我们在 First 模块 tfstate
文件中找到的 ID。
错误信息:
当 Terraform 尝试使用 First 模块创建的 Service Principal ID 和 Secret 来 apply
Second 模块时,会引发以下错误:
Error:
Error building account:
Error getting authenticated object ID:
Error listing Service Principals:
autorest.DetailedError
Original:adal.tokenRefreshError
message:"adal: Refresh request failed.
Status Code = '400'.
Response body:
\"error\":\"unauthorized_client\",
\"error_description\":\"AADSTS700016:
Application with identifier 'correct-app-id' was not found in the directory 'the-right-ad-id'.
This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant.
You may have sent your authentication request to the wrong tenant.\\r\\n
Trace ID: some-trace-id\\r\\n
Correlation ID: correlation-id-redacted\\r\\n
Timestamp: 2020-12-31 19:02:19Z\",
\"error_codes\":[700016],
\"timestamp\":\"2020-12-31 19:02:19Z\",
\"trace_id\":\"some-trace-id\",
\"correlation_id\":\"correlation-id-redacted\",
\"error_uri\":\"https://login.microsoftonline.com/error?code=700016\"
",
resp:(*http.Response)(0xc000ac2000),
PackageType:"azure.BearerAuthorizer",
Method:"WithAuthorization",
StatusCode:400,
Message:"Failed to refresh the Token for request to https://graph.windows.net/the-right-ad-id/servicePrincipals?%24filter=appId+eq+%27correct-app-id%27&api-version=1.6",
ServiceError:[]uint8(nil),
Response:(*http.Response)(0xc000ac2000)
错误消息似乎没有帮助,因为我们已验证该应用已向 AAD 实例注册。
我们如何解决这个问题并以编程方式创建
client_id
和client_secret
将被Second 模块接受和使用?
【问题讨论】:
我使用了你的 terraform 代码,我没有遇到任何问题。你在你的问题中留下了一些表明问题的东西。创建一个包含所有内容的两部分示例。用这些部分更新您的问题。 CodeMed 能否分享一下“关于将用于远程 api 调用(如 terraform)需要由脚本创建的服务主体的文章”?或任何其他可能有助于了解您的设置的内容(我不知道 terraform,但做了很多 Azure AD) 我创建了两个 Gist。第 1 部分的输出手动放入第 2 部分。第 1 部分 gist.github.com/jhanley-com/3de93b2243cd1ba5fcad6e2c6dc49da3 和第 2 部分 gist.github.com/jhanley-com/335a9b949e67d9027590219216279811 我认为这可能是指与最终一致性相关的问题:github.com/hashicorp/terraform-provider-azuread/issues/156 @JohnHanley 你的建议奏效了。感谢您再次关注此问题。 【参考方案1】:我认为您的 Terraform 代码没有问题。它应该可以正常工作。但是您收到了在租户中找不到应用程序的错误。所以你需要做的是在第二个模块中检查租户ID是否真的正确。
【讨论】:
租户 ID 正确。那不是问题。一篇文章中有一些最小的参考,即必须使用脚本而不是 Terraform 创建与 API 交互的服务主体,因为 Microsoft 编写了azurerm
Terraform 提供程序。但消息来源并不权威,也没有给出例子。我曾希望这个 OP 能以详尽的工作形式引出那种有用的答案。
@CodeMed 我认为不能通过 Terraform 创建服务主体。你所有的代码在我这边都可以正常工作。服务主体就是服务主体,创建方式没有区别。
@CodeMed 这个问题有什么更新吗?它解决了你的问题吗?【参考方案2】:
我在 Kubernetes 上的 Terraform 部署代理上遇到了同样的问题。当内存或 CPU 不够大时,可能会出现几种类型的错误。
以下是 Terraform 建议:https://www.terraform.io/docs/enterprise/before-installing/index.html
当多个 Terraform 部署并行时,您必须小心共享资源的部署基础架构(K8s、Hypervisor Pool 等),这会导致一些随机错误。
Terraform 不停止、API AZure / AWS 错误、tfstate 锁定等
【讨论】:
以上是关于Azure API 无法识别来自 Terraform 的服务主体的主要内容,如果未能解决你的问题,请参考以下文章
使用 Angular 7 使用 Azure Face Api 进行人脸识别
Flutter 中的 Azure API(面部识别)[关闭]