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

Terraform如何配置让null_resource先执行后再更新aws_s3_bucket_object资源

解决方案

你需要通过显式声明资源依赖+适配Terraform执行阶段特性两步实现目标执行顺序:

1. 添加显式资源依赖

在aws_s3_bucket_object.file_upload资源块中新增depends_on参数,明确要求该资源必须等待null_resource.cert执行完成后再运行,修改后的代码示例:

resource "aws_s3_bucket_object" "file_upload" {
  for_each = fileset("init_conf/", "*")
  bucket = aws_s3_bucket.conf_bucket.id
  acl    = "private"
  key    = "config/${local.service_name}/${each.value}"
  source = "init_conf/${each.value}"
  source_hash = filemd5("init_conf/${each.value}")
  kms_key_id = "arn:aws:kms:##################:###################"
  server_side_encryption = "aws:kms"
  
  # 新增依赖声明
  depends_on = [null_resource.cert]

  tags = merge(tomap({
               "Name" = local.service_name,
  }), local.default_tags)
}

2. 适配Terraform执行阶段特性

注意Terraform的fileset、filemd5这类文件读取函数会在计划阶段就执行,而null_resource的local-exec供应器是apply阶段才会运行,第一次执行时计划阶段init_conf目录下还没有生成的证书文件,会导致s3资源匹配不到新生成的.crt、.key文件,还可能抛出文件不存在的错误,你可以任选以下一种方案规避:

  • 方案A:显式声明上传文件列表,替换动态目录扫描
    提前把要上传的静态文件和生成的证书文件名统一声明,避免计划阶段漏扫新生成的证书:
    locals {
      # concat里的第二个数组放你会动态生成的所有文件名
      upload_files = toset(concat(fileset("init_conf/", "*"), ["${var.cname}.key", "${var.cname}.crt"]))
    }
    
    resource "aws_s3_bucket_object" "file_upload" {
      for_each = local.upload_files
      # 其余原有配置保持不变,depends_on保留
    }
    
  • 方案B:提前创建证书占位文件
    执行terraform apply前,先在init_conf目录下创建和生成证书同名的空.crt、.key文件,计划阶段会读取到这两个文件,apply阶段生成证书时会覆盖文件内容,结合source_hash的变更会自动触发s3对象的更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:45:01