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

Terraform中带depends_on的archive_file在plan阶段仍校验source_dir报错

Terraform Lambda打包在干净CI环境报错:目录缺失的原因与解决办法

问题核心原因

Terraform的data资源(包括archive_file)会在plan阶段就执行验证和数据生成,而null_resource的local-exec provisioner仅在apply阶段运行。即便给data.archive_file添加depends_on,也只能控制apply阶段的执行顺序,无法阻止plan阶段的目录检查。在干净CI工作区中,plan阶段还未执行打包脚本,目标目录根本不存在,直接触发报错。

另外,尝试用resource "archive_file"失败的原因是:该资源的哈希类属性(如output_base64sha256)在plan阶段无法生成有效计算值,而你使用的lambda模块可能依赖这些值提前存在,导致流程卡壳。

有效解决办法

办法1:将打包逻辑移到Terraform执行前(推荐,CI环境最稳定)

在CI流水线中,先单独执行Python依赖安装和打包脚本,再运行terraform plan/apply。这样Terraform执行时,压缩包已提前生成,无需依赖内部provisioner。

示例Bitbucket Pipelines脚本:

script:
  - rm -rf .build/lambda-package
  - mkdir -p .build/lambda-package
  - pip3 install requests -t .build/lambda-package --quiet
  - cp src/handler.py .build/lambda-package/
  - zip -r .build/lambda-package.zip .build/lambda-package/
  - terraform init
  - terraform apply -auto-approve

对应Terraform代码直接引用预生成的压缩包路径:

module "lambda" {
  source  = "terraform-aws-modules/lambda/aws"
  version = "~> 7.0"

  create_package         = false
  local_existing_package = "${path.root}/.build/lambda-package.zip"
  # ... 其他Lambda配置
}

办法2:在null_resource内部完成打包,跳过archive_file数据资源

把压缩逻辑直接整合到build_lambda的local-exec中,无需单独的archive_file资源,直接用预定义的压缩包路径传给lambda模块。

修改后的Terraform代码:

resource "null_resource" "build_lambda" {
  triggers = {
    source_hash = local.source_hash
  }

  provisioner "local-exec" {
    interpreter = ["/bin/bash", "-euo", "pipefail", "-c"]
    command     = <<-EOT
      rm -rf "${local.build_dir}"
      mkdir -p "${local.build_dir}"
      pip3 install requests -t "${local.build_dir}" --quiet
      cp "${var.source_dir}/handler.py" "${local.build_dir}/"
      # 直接在打包步骤后完成压缩
      zip -r "${local.zip_path}" "${local.build_dir}/"
      date -u > "${local.build_dir}/.build_complete"
    EOT
  }
}

module "lambda" {
  source  = "terraform-aws-modules/lambda/aws"
  version = "~> 7.0"

  create_package         = false
  local_existing_package = local.zip_path
  # 确保lambda模块在打包完成后再执行
  depends_on = [null_resource.build_lambda]
  # ... 其他Lambda配置
}

这种方式下,plan阶段仅需确认路径存在即可(lambda模块的local_existing_package在plan阶段不会强制检查文件存在),打包逻辑在apply阶段的provisioner中执行,依赖关系可保证执行顺序。

办法3:使用external数据源触发打包(较复杂,不推荐)

通过data "external"调用外部脚本完成打包,利用external数据源在apply阶段执行的特性,但需要严格处理脚本的JSON输入输出格式,实现成本高于前两种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 13:09:57