在Terraform中实现Databricks集群与实例配置文件的匹配映射
解决Terraform中Databricks集群与实例配置文件的映射问题
需求背景
需要生成一个键值对映射表,键为集群名称,值为对应的AWS实例配置文件ARN,用于databricks_cluster资源的for_each参数。核心逻辑:
- 从集群名称中剔除
-clusterN后缀,提取前缀(比如client1-dev-cluster1处理后得到client1-dev) - 匹配ARN中包含该前缀的实例配置文件,建立一一对应关系
现有数据
集群列表
cluster_envs = [ "client1-dev-cluster1", "client1-dev-cluster2", "client1-prod-cluster1", "client1-prod-cluster2", ]
实例配置文件列表
databricks_instance_profiles = [ "arn:aws:iam::<AWS_account_ID>:instance-profile/databricks-client1-dev-instance_profile", "arn:aws:iam::<AWS_account_ID>:instance-profile/databricks-client1-prod-instance_profile", "arn:aws:iam::<AWS_account_ID>:instance-profile/databricks-client2-dev-instance_profile", "arn:aws:iam::<AWS_account_ID>:instance-profile/databricks-client2-prod-instance_profile", ]
之前的错误尝试
使用嵌套循环加regexall的代码:
temp_cluster_envs = flatten([ for env in local.cluster_envs : [ for arn in local.databricks_instance_profiles: map(env, arn) if regexall( join("-", [ split("-", env)[0], split("-", env)[1], split("-", env)[2] ]), arn) ] ])
触发错误:
│ Error: Invalid 'for' condition │ │ on modules/manage-workspaces/locals.tf line 93, in locals: │ 92: for env in local.cluster_envs : [ │ 93: for arn in local.databricks_instance_profiles: map(env, arn) if regexall( │ 94: join("-", [ │ 95: split("-", env)[0], │ 96: split("-", env)[1], │ 97: split("-", env)[2] │ 98: ]), arn) │ 99: ] │ │ The 'if' clause value is invalid: bool required. ╵
解决方案
1. 提取集群前缀
用正则替换去掉-clusterN后缀,比固定分割更灵活:
locals { # 从集群名称中提取前缀(剔除-clusterN结尾部分) cluster_prefixes = { for env in local.cluster_envs : env => regex_replace(env, "-cluster\\d+$", "") } }
-cluster\\d+$正则会精准匹配以-cluster加数字结尾的片段,替换为空后得到目标前缀。
2. 建立实例配置文件的前缀映射
先把实例配置文件列表转换成「前缀-ARN」的映射表,方便后续快速查找:
locals { # 从ARN中提取前缀,生成前缀到ARN的映射 instance_profile_map = { for arn in local.databricks_instance_profiles : regex( "databricks-(.*)-instance_profile", element(split("/", arn), length(split("/", arn)) - 1) )[0] => arn } }
通过split("/", arn)获取ARN的最后一段路径,再用正则提取出clientX-env格式的前缀,最终得到前缀与ARN的对应关系。
3. 生成最终的集群-实例配置文件映射
结合前两步的结果,直接生成符合for_each要求的映射表:
locals { cluster_instance_profile_map = { for cluster_name, prefix in local.cluster_prefixes : cluster_name => local.instance_profile_map[prefix] } }
4. 应用到资源定义
直接在databricks_cluster资源中使用这个映射:
resource "databricks_cluster" "multi_tenant" { for_each = local.cluster_instance_profile_map cluster_name = each.key spark_version = data.databricks_spark_version.latest_lts.id aws_attributes { zone_id = data.aws_availability_zones.available.names[0] instance_profile_arn = each.value } custom_tags = var.tags }
额外说明
- 正则替换比固定分割更健壮,即使集群名称结构略有变化(比如
client1-test-cluster10)也能正确处理 - 先建立实例配置文件的前缀映射,避免嵌套循环,提升代码可读性和执行效率
- 最终生成的映射表完全满足
for_each的要求:键是唯一的集群名称,值是对应的ARN
内容的提问来源于stack exchange,提问作者hyperwiser
相关产品推荐
相关产品推荐

