【问题标题】:How can I use Terraform to create a service principal and use that principal in a provider?如何使用 Terraform 创建服务主体并在提供程序中使用该主体?
【发布时间】:2019-05-28 05:58:48
【问题描述】:

我已经阅读了网上的文章,但他们似乎并没有完全涵盖这个主题,并希望做过这件事的人能给我一些指导。 我们正在设置一个复杂的 Terraform 模板,以满足与 SaaS 产品相关的 IaC 要求。为此,我们希望模板在启动时使用用户的凭据在 Azure AD 中创建新的服务主体(这部分我没有问题)。然后在模板的下一部分中,我们使用该服务主体作为提供者。问题是它在计划/应用中引发错误,因为服务主体不存在(也就是由于服务提供者部分尚未运行,id 不存在)。 那么有没有办法可以做到这一点?创建一个服务主体,然后在使用该服务主体而不将其拆分为多个模板的提供者别名中使用它?

最后,我希望此模板使用本地用户的权限或 MSI 创建服务提供商,将 RBAC 提供给订阅,然后使用该服务提供商在该订阅中创建资产。

main.ts(根)

provider "azurerm" {
    alias               = "ActiveDirectory"
    subscription_id     = "${var.subscriptionNucleus}"
}

provider "azurerm" {
    alias               = "Infrastructure"
    subscription_id     = "${var.subscriptionInfrastructure}"
}
module "activedirectory" {
    providers                       = { azurerm = "azurerm.ActiveDirectory" 
}
    source                          = "./modules/activedirectory"
    subscription_id_infrastructure  = "${var.subscriptionInfrastructure}"
}
module "infrastructure" {
    providers                   = { azurerm = "azurerm.Infrastructure"}
    source                      = "./modules/infrastructure"
    location                    = "${var.location}"
    application_id              = 
 "${module.activedirectory.service_principal_application_id}"
    subscription_id             = "${var.subscriptionInfrastructure}"
    prefix                      = "${var.prefix}"
}

main.ts (./modules/infrastructure)

data "azurerm_azuread_service_principal" "serviceprincipal" {
    application_id = "${var.application_id}"
}

provider "azurerm" {
    alias           = "InfrastructureSP"
    subscription_id = "${var.subscription_id}"
    client_id       = "${var.application_id}"
    client_secret   = "secret"
    tenant_id       = 
"${data.azurerm_client_config.clientconfig.tenant_id}"  
}

【问题讨论】:

    标签: azure terraform azure-rm


    【解决方案1】:

    对于 Azure 服务主体,有两种使用服务主体的方法。

    首先:如果您已经有一个服务主体并希望在 Terraform 中使用它。您可以像这样使用 Terraform 数据和测试:

    data "azurerm_azuread_service_principal" "sp" {
            application_id  = "21f3e1de-54e2-4951-9743-c280ad7bd74a"
    }
    
    output "test" {
            value = "${data.azurerm_azuread_service_principal.sp.id}"
    }
    

    结果截图在这里:

    第二:你没有服务主体,你可以像这样在 Terraform 中创建一个服务主体:

    resource "azurerm_azuread_service_principal" "test" {
      application_id = "${azurerm_azuread_application.test.application_id}"
    }
    
    resource "azurerm_azuread_service_principal_password" "test" {
      service_principal_id = "${azurerm_azuread_service_principal.test.id}"
      value                = "your pasword"
      end_date             = "2020-01-01T01:02:03Z" 
    }
    

    那么,无论您选择哪种方式,对于大多数资源,您都应该执行一个重要步骤。这一步是您需要创建角色以授予权限,然后将其分配给需要的资源。你可以这样做:

    resource "azurerm_role_assignment" "test" {
      scope                = "yourScope"   # the resource id
      role_definition_name = "the Role In need" # such as "Contributor"
      principal_id         = "your service principal id"
    }
    

    希望这会对你有所帮助。

    【讨论】:

    • 感谢您花时间回复,但正如我所说,我已经按照您所说的选项 2 进行操作。问题不在于创建服务主体,而在于使用作为一部分创建的服务主体要在其他资源或模块中使用的提供程序。遇到的实际错误是:使用客户端密钥作为服务主体进行身份验证时必须配置客户端 ID。 这是因为没有客户端 ID,因为服务主体尚未创建应用/计划,因为它共享一个大模板。
    • 您可以使用 Terraform 数据引用另一个模板中的现有服务主体。但是,如果资源依赖于服务主体并且它不存在,那么您将收到错误消息。你可以看看Terraform Dependencies
    • 这就是我希望有人能解决我的情况的方法。 Depends_on 在提供程序块中不起作用,即使创建提供程序块的模块对先前创建的服务提供程序有轻微的依赖性,应用/计划也不查看该部分并会引发错误。在这一点上,似乎没有什么比把它分成 2 个单独的模板,这是不幸的。
    • 你可以尝试去掉depends_on,看来Terraform会自动解决depends_on。
    • depends_on 不适用于模块,除非您尝试使用 null_reference hack。无论哪种方式,我都没有使用它们,因为它们只是没有解决这个问题。我发现无法在一个模块中创建服务主体,然后在另一个模块中分配 RBAC。需要一个操作顺序,直到模块与depends_on一起工作,这是必需的。
    【解决方案2】:

    目前没有可用于非 hack (null_reference) 的模块的有效“depends_on”。这意味着如果您将模板分解为模块(分离关注点),您的操作顺序必须正确才能成功完成,因为一个模块将不知道服务提供者的数据源必须等待前一个模块完成.我不得不将其分解为 2 个单独的模板,其中第一个创建服务主体,第二个具有模块化分离,然后可以使用 azurerm_azuread_service_principal 的数据源。 一旦 Hashicorp 可以实现模块 depends_on,这将变得更容易。

    【讨论】:

      猜你喜欢
      • 2021-04-18
      • 2021-06-03
      • 1970-01-01
      • 2020-11-11
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多