尝试使用 etag 时找不到文件

Lud*_*udo 3 terraform

我尝试etag在更新存储桶 S3 时使用,但收到此错误:

Error: Error in function call
   on config.tf line 48, in resource "aws_s3_bucket_object" "bucket_app":
   48:   etag = filemd5("${path.module}/${var.env}/app-config.json")
     |----------------
     | path.module is "."
     | var.env is "develop"
 Call to function "filemd5" failed: no file exists at develop/app-config.json.
Run Code Online (Sandbox Code Playgroud)

然而,这工作得很好:

resource "aws_s3_bucket_object" "bucket_app" {
  bucket = "${var.app}-${var.env}-app-assets"
  key    = "config.json"
  source = "${path.module}/${var.env}/app-config.json"

  // etag = filemd5("${path.module}/${var.env}/app-config.json")

  depends_on = [
    local_file.app_config_json
  ]
}
Run Code Online (Sandbox Code Playgroud)

我这样生成文件:

resource "local_file" "app_config_json" {
  content  = local.app_config_json
  filename = "${path.module}/${var.env}/app-config.json"
}
Run Code Online (Sandbox Code Playgroud)

我真的不明白我做错了什么......

Mik*_*ple 9

如果您碰巧到达此处并正在使用archive_file数据源,则会有一个名为 的导出属性output_md5。这似乎提供了与您从中获得的相同结果filemd5(data.archive_file.app_config_json.output_path)

这是一个完整的示例:

data archive_file config {
  type        = "zip"
  output_path = "${path.module}/config.zip"
  source {
    filename = "config/template-configuration.json"
    content  = "some content"
  }
}

resource aws_s3_bucket_object config{
  bucket       = aws_s3_bucket.stacks.bucket
  key          = "config.zip"
  content_type = "application/zip"
  source       = data.archive_file.config.output_path
  etag         = data.archive_file.config.output_md5
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ins 6

Terraform 中的所有函数都在初始配置处理期间运行,而不是在图形遍历期间运行。对于读取磁盘上文件的所有函数,这意味着文件必须在运行 Terraform 之前作为配置本身的一部分存在于磁盘上(通常签入版本控制),而不是在 Terraform 期间动态生成手术。

file建立在 [ ]之上的文档filemd5对此有以下说明:

此函数只能用于 Terraform 运行开始时磁盘上已存在的文件。函数不参与依赖关系图,因此此函数不能与 Terraform 操作期间动态生成的文件一起使用。我们不建议在 Terraform 配置中使用动态本地文件,但在极少数有必要的情况下,您可以使用数据local_file读取文件,同时尊重资源依赖性。

正如那里的文档所暗示的那样,local_file数据源提供了一种在图形遍历期间将文件作为资源读入内存的方法,尽管仍然需要传递其结果md5才能获得此处所需的结果。

因为无论如何您都是使用资源创建文件local_file,所以您可以跳过对附加资源的需要data,并直接从您的资源派生 MD5 哈希值local_file.app_config_json

resource "aws_s3_bucket_object" "bucket_app" {
  bucket = "${var.app}-${var.env}-app-assets"
  key    = "config.json"
  source = local_file.app_config_json.filename
  etag   = md5(local_file.app_config_json.content)
}
Run Code Online (Sandbox Code Playgroud)

depends_on请注意,如果我们从资源的属性派生配置,则不需要使用local_file.app_config_json,因为 Terraform 因此已经可以看到依赖关系存在。