所以我试图编写一个可以同时执行工作区和帐户级别操作的模块。是的,我知道这并不理想,它们最终可能应该分开,但我无法完成这项工作,我很好奇是否有任何方法可以完成这项工作。
我在根目录下面(我的
main.tf
)是:
provider "azurerm" {
features {}
subscription_id = "redacted" //non prod subscription id for testing purposes
client_id = "redacted"
client_secret = "redacted"
tenant_id = "redacted"
}
provider "databricks" {
alias = "account"
host = "https://accounts.azuredatabricks.net"
account_id = var.databricks_account_id
azure_tenant_id = "redacted"
azure_client_id = "redacted"
azure_client_secret = "redacted"
}
provider "databricks" {
alias = "workspace"
host = module.dbr_workspace.databricks_workspace_url
}
和 required_providers.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
databricks = {
source = "databricks/databricks"
}
}
}
然后在我的 main.tf 中我称之为:
module "dbr_unity_catalog_metastore" {
source = "./modules/dbr_unity_catalog_metastore"
providers = {
databricks = databricks.workspace # for workspace-level resources
}
depends_on = [module.dbr_unity_catalog_azure, module.dbr_workspace]
azure_resource_group = var.resource_group_name
databricks_workspace_id = module.dbr_workspace.databricks_workspace_id
metastore_name = var.metastore_name
metastore_storage_account_name = var.metastore_storage_account_name
metastore_storage_container_name = var.metastore_storage_container_name
access_connector_name = var.access_connector_name
access_connector_id = module.dbr_unity_catalog_azure.access_connector_id
sp_application_id = var.sp_application_id
sp_display_name = var.sp_display_name
admin_group_id = data.databricks_group.admins.id
tags = var.tags
}
这个模块现在只是尝试做这两件事:
module "unity_catalog_workspace_assignment" {
source = "../unity_catalog_workspace_assignment"
workspace_id = var.databricks_workspace_id
metastore_name = var.metastore_name
}
resource "databricks_storage_credential" "external_mi" {
name = "external_location_mi_credential"
azure_managed_identity {
access_connector_id = var.access_connector_id
}
owner = var.sp_application_id
comment = "Storage credential for all external locations"
depends_on = [ module.unity_catalog_workspace_assignment ]
}
因此它正在调用另一个模块
unity_catalog_workspace_assignment
,该模块正在尝试将 dbr 工作区分配给元存储,并且另一个资源正在创建存储凭证,因此这是工作区级别的操作。
unity_catalog_workspace_assignment
的代码如下所示:
data "databricks_metastores" "all" {
}
resource "databricks_metastore_assignment" "prod" {
metastore_id = data.databricks_metastores.all.ids[var.metastore_name]
workspace_id = var.workspace_id
}
现在,当我运行
tf apply
时,我收到以下错误:
Error: cannot read metastores: cannot get client metastores: invalid Databricks Account configuration
│
│ with module.dbr_unity_catalog_metastore.module.unity_catalog_workspace_assignment.data.databricks_metastores.all,
│ on modules/unity_catalog_workspace_assignment/unity_catalog_workspace_assignment.tf line 1, in data "databricks_metastores" "all":
│ 1: data "databricks_metastores" "all" {
我想这是因为数据源
databricks_metastores
但我不能只是将其修改为:
data "databricks_metastores" "all" {
provider = databricks.accounts
}
resource "databricks_metastore_assignment" "prod" {
provider = databricks.accounts
metastore_id = data.databricks_metastores.all.ids[var.metastore_name]
workspace_id = var.workspace_id
}
因为该模块由于某种原因无法识别别名。 我想我也不能两次使用相同的数据块提供程序,因为源仍然是相同的。 有什么办法可以解决这个问题吗
如果您有一个共享模块,其本身需要使用同一提供者的多个实例,则可以在该模块的
configuration_aliases
块中使用 required_providers
参数进行声明:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
databricks = {
source = "databricks/databricks"
configuration_aliases = [
databricks.account,
databricks.workspace,
]
}
}
}
默认情况下,
configuration_aliases
设置为[ databricks ]
,这意味着模块需要提供程序的单个“默认”(无别名)配置,但如果设置configuration_aliases
,则可以声明模块需要任何混合默认(无别名)和附加(别名)提供程序配置。在上面的示例中,我声明了两个“附加”提供程序配置,其中别名为“account”和“workspace”,因为匹配根模块中的别名似乎很方便。但是,每个模块都有自己的用于提供程序配置的命名空间,因此实际上不需要别名匹配。
当您调用需要额外提供程序配置的模块时,您可以在调用
providers
块中使用 module
参数来指定应将调用模块中的哪个提供程序配置分配给子模块中的每个配置槽:
module "dbr_unity_catalog_metastore" {
source = "./modules/dbr_unity_catalog_metastore"
providers = {
databricks.workspace = databricks.workspace
databricks.account = databricks.account
}
# ...
}
在上面的
providers
参数中,每个=
左侧的地址指定子模块中的提供者配置槽(configuration_aliases
中声明的地址之一),而右侧指定提供者的地址您想要分配给该插槽的 current 模块中的实例。在本例中,我选择对父模块和子模块使用相同的别名,因此每个映射的两侧都会出现相同的地址。