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

Terraform AWS:用foreach创建多步骤动态SFTP传输工作流遇错

解决Terraform AWS Transfer Workflow多步骤生成异常问题

问题现状

尝试创建可动态修改的多步骤SFTP传输工作流时遇到以下问题:

  • 当前配置生成5个独立工作流,每个工作流包含5个重复步骤,而非预期的1个包含5个不同步骤的工作流
  • 调整变量数据类型后,生成5个各含1个步骤的工作流,不符合需求
  • 移除外部for_each块后,部署直接失败

错误原因

  1. 外部aws_transfer_workflow资源使用for_each = var.workflow_steps,会遍历每个步骤对象生成独立工作流,导致创建多个工作流而非单个
  2. 内部dynamic "steps"块错误地遍历each.value(单个步骤对象),导致每个工作流中重复生成所有类型的步骤块,出现重复步骤

修正后的配置

资源配置

resource "aws_transfer_workflow" "Workflow" {
  # 移除外部for_each,确保只创建一个工作流
  dynamic "steps" {
    # 遍历var.workflow_steps的所有步骤值,生成多个steps块
    for_each = var.workflow_steps
    content {
      dynamic "copy_step_details" {
        for_each = steps.value.type == "COPY" ? [1] : []
        content {
          name                 = steps.value.name
          source_file_location = steps.value.source_file_location
          destination_file_location {
            s3_file_location {
              bucket = steps.value.destination_bucket
              key    = steps.value.destination_key
            }
          }
        }
      }

      dynamic "custom_step_details" {
        for_each = steps.value.type == "CUSTOM" ? [1] : []
        content {
          name                 = steps.value.name
          source_file_location = steps.value.source_file_location
          target               = steps.value.target
          timeout_seconds      = steps.value.timeout_seconds
        }
      }

      dynamic "delete_step_details" {
        for_each = steps.value.type == "DELETE" ? [1] : []
        content {
          name                 = steps.value.name
          source_file_location = steps.value.source_file_location
        }
      }

      dynamic "decrypt_step_details" {
        for_each = steps.value.type == "DECRYPT" ? [1] : []
        content {
          name                 = steps.value.name
          type                 = "PGP"
          source_file_location = steps.value.source_file_location
          destination_file_location {
            s3_file_location {
              bucket = steps.value.destination_bucket
              key    = steps.value.destination_key
            }
          }
        }
      }

      dynamic "tag_step_details" {
        for_each = steps.value.type == "TAG" ? [1] : []
        content {
          name                 = steps.value.name
          source_file_location = steps.value.source_file_location
          tags {
            key   = steps.value.tag_key
            value = steps.value.tag_value
          }
        }
      }
      type = steps.value.type
    }
  }
}

变量配置(优化类型定义,避免属性缺失报错)

variable "workflow_steps" {
  description = "Map of workflow steps"
  type        = map(object({
    type                  = string
    name                  = string
    source_file_location  = string
    destination_bucket    = optional(string)
    destination_key       = optional(string)
    target                = optional(string)
    timeout_seconds       = optional(number)
    tag_key               = optional(string)
    tag_value             = optional(string)
  }))
  default = {
    step1 = {
      type = "COPY"
      name = "Copy"
      source_file_location = "$${original.file}"
      destination_bucket = ""
      destination_key = ""
    }
    step2 = {
      type = "CUSTOM"
      name = "Custom"
      source_file_location = "$${original.file}"
      target = "arn:aws:lambda"
      timeout_seconds = 60
    }
    step3 = {
      type = "TAG"
      name = "Tag"
      source_file_location = "$${original.file}"
      tag_key = "Name"
      tag_value = "Hello World"
    }
    step4 = {
      type = "DECRYPT"
      name = "Decrypt"
      source_file_location = "$${original.file}"
      destination_bucket = ""
      destination_key = "test"
    }
    step5 = {
      type = "DELETE"
      name = "Delete"
      source_file_location = "$${original.file}"
    }
  }
}

关键修改点

  • 移除aws_transfer_workflow资源的外部for_each,确保仅创建一个工作流
  • 将内部dynamic "steps"的for_each改为var.workflow_steps,遍历所有步骤生成对应的steps块
  • 内部所有步骤细节块中,将each.value替换为steps.value,正确引用当前遍历的步骤属性
  • 变量类型补充optional()修饰符,避免因不同步骤缺少部分属性导致的验证错误

内容的提问来源于stack exchange,提问作者Louis Johnson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:12:32