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
相关产品推荐
相关产品推荐

