You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform合并多for_each资源值及解决concat参数报错问题

解决Terraform合并多个for_each创建的azuredevops_environment资源并筛选的问题

问题背景

需求:合并多个通过for_each创建的azuredevops_environment资源(实现环境、测试环境、预览环境等),筛选名称包含"US"的环境ID,用于azuredevops_check_business_hours资源的for_each配置。
使用版本:

  • Terraform Version: v1.4.2
  • provider registry.terraform.io/microsoft/azuredevops v0.4.0

原代码与执行报错

环境资源定义

# Implementation environments
resource "azuredevops_environment" "impl_regional_environment" {
  for_each    = toset(var.environment_regions)
  project_id  = data.azuredevops_project.vrx.id
  name        = "${each.key} - IMPL"
  description = "${each.key} Implementation Environment. \n**Managed by Terraform**"  
}

# Test environments
resource "azuredevops_environment" "test_regional_environment" {
  for_each    = toset(var.environment_regions)
  project_id  = data.azuredevops_project.vrx.id
  name        = "${each.key} - TEST"
  description = "${each.key} Test Environment. \n**Managed by Terraform**"
}

# Preview environments
resource "azuredevops_environment" "prev_regional_environment" {
  for_each    = toset(var.environment_regions)
  project_id  = data.azuredevops_project.vrx.id
  name        = "${each.key} - PREV"
  description = "${each.key} Preview Environment. \n**Managed by Terraform**"
}

尝试合并筛选的代码

resource "azuredevops_check_business_hours" "us_non-production" {
  project_id           = data.azuredevops_project.vrx.id
  display_name         = "Daily Deployment Window \n**Managed by Terraform**"
  for_each =  {for key, val in concat(azuredevops_environment.impl_regional_environment,azuredevops_environment.test_regional_environment,azuredevops_environment.prev_regional_environment,azuredevops_environment.pcpy_regional_environment):
               key => val if length(regexall("US - ", val.name)) > 0}
  target_resource_id   = each.value.id
  target_resource_type = "environment"
  start_time           = "18:00"
  end_time             = "23:30"
  time_zone            = "Central Standard Time"
  monday               = true
  tuesday              = true
  wednesday            = true
  thursday             = true
  friday               = true
  saturday             = true
  sunday               = true
}

报错信息

│ Error: Invalid function argument
│
│   on modules\project_vrx\vrx_environments\main.tf line 144, in resource "azuredevops_check_business_hours" "us_non-production":
│  144:   for_each =  {for key, val in concat(azuredevops_environment.impl_regional_environment,azuredevops_environment.test_regional_environment,azuredevops_environment.prev_regional_environment,azuredevops_environment.pcpy_regional_environment):
│     ├────────────────
│     │ while calling concat(seqs...)
│     │ azuredevops_environment.impl_regional_environment is object with 6 attributes
│
│ Invalid value for "seqs" parameter: all arguments must be lists or tuples; got object.

错误原因

concat()函数要求所有参数必须是列表或元组类型,但通过for_each创建的资源实例是Map类型(对象),直接传入concat()会触发类型不匹配错误。

解决方案

需要先将每个资源的Map实例转换为列表(提取所有值),再进行合并,最后通过for表达式筛选并构造符合for_each要求的唯一键Map:

修改后的azuredevops_check_business_hours资源代码

resource "azuredevops_check_business_hours" "us_non-production" {
  project_id           = data.azuredevops_project.vrx.id
  display_name         = "Daily Deployment Window \n**Managed by Terraform**"
  # 先将每个资源的map转为列表,合并后筛选并构造新的唯一键map
  for_each = {
    for env in concat(
      values(azuredevops_environment.impl_regional_environment),
      values(azuredevops_environment.test_regional_environment),
      values(azuredevops_environment.prev_regional_environment),
      values(azuredevops_environment.pcpy_regional_environment)
    ) : env.id => env if contains(env.name, "US - ")
  }
  target_resource_id   = each.value.id
  target_resource_type = "environment"
  start_time           = "18:00"
  end_time             = "23:30"
  time_zone            = "Central Standard Time"
  monday               = true
  tuesday              = true
  wednesday            = true
  thursday             = true
  friday               = true
  saturday             = true
  sunday               = true
}

代码说明

  1. values()函数:将每个azuredevops_environment资源的Map实例转换为包含所有环境对象的列表
  2. concat()函数:合并所有环境列表为一个大列表
  3. for表达式:遍历合并后的列表,以环境的id作为Map的键(保证唯一),筛选出名称包含"US - "的环境对象,最终生成的Map符合for_each的要求

内容的提问来源于stack exchange,提问作者Scott E

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 10:28:20