Terraform S3 Bucket 对象的 etag 在每次应用时不断更新

Yu *_*hen 16 amazon-s3 amazon-web-services terraform

我正在将 AWS Lambda 代码作为 zip 文件上传到 S3 存储桶中。

我有一个为 S3 存储桶对象声明的资源:

resource "aws_s3_bucket_object" "source-code-object" {
  bucket = "${aws_s3_bucket.my-bucket.id}"
  key = "source-code.zip"
  source = "lambda_source_code/source-code.zip"
  etag = "${base64sha256(file("lambda_source_code/source-code.zip"))}"
}
Run Code Online (Sandbox Code Playgroud)

我还有一个数据声明来压缩我的代码:

data "archive_file" "source-code-zip" {
  type = "zip"
  source_file = "${path.module}/lambda_source_code/run.py"
  output_path = "${path.module}/lambda_source_code/source-code.zip"
}
Run Code Online (Sandbox Code Playgroud)

输出terraform apply不断向我显示哈希值的更改:

  ~ aws_s3_bucket_object.source-code-object
      etag: "old_hash" => "new_hash"
Run Code Online (Sandbox Code Playgroud)

即使我的源代码中没有任何更改。为什么会出现这种行为?我见过类似的帖子,其中 Lambda 的源代码不断变化,但我的 Lambda 实际上并没有每次都更新(在控制台中检查了上次更新时间)。但是,看起来确实在每个apply.

Mat*_*t F 15

默认情况下,您的 S3 存储桶可能使用 KMS 密钥来应用加密。当以这种方式配置时,它etag不是文件内容 ( doc ) 的 MD5。

由 PUT 对象、POST 对象或复制操作或通过 AWS 管理控制台创建并由 SSE-C 或 SSE-KMS 加密的对象具有不是其对象数据的 MD5 摘要的 ETag。

如果不知道他们的哈希实现,就没有办法预先计算 terraform 的值并使其成为稳定的计划。

相反,您应该使用该source_hash属性来解决该限制。


tjh*_*in1 6

为了防止每次应用更新时,使用新aws_s3_object资源,您可以使用output_base64sha256属性引用。

aws_s3_bucket_object 数据源已弃用,并将在未来版本中删除!请改用 aws_s3_object,其中将添加新功能和修复。

data "archive_file" "source-code-zip" {
  type = "zip"
  source_file = "${path.module}/lambda_source_code/run.py"
  output_path = "${path.module}/lambda_source_code/source-code.zip"
}

resource "aws_s3_object" "source-code-object" {
  bucket = aws_s3_bucket.my-bucket.id
  key    = "source-code.zip"

  # we can also reference `output_path` from `archive_file`
  # so as not to repeat the path
  source      = data.archive_file.source-code-zip.output_path
  source_hash = data.archive_file.source-code-zip.output_base64sha256
}
Run Code Online (Sandbox Code Playgroud)

output_base64sha256正如 @Matt F 指出的,使用 KMS 加密的 s3 对象还有一个额外的好处。


bwe*_*est 4

默认情况下,Zip 存档包含元数据,例如时间戳,这会导致哈希值不同,即使源文件不一样。手动构建存档时,您可以使用--no-extra-X标志来避免这种情况。我不确定 Terraform 是否支持这个标志。

从 zip 手册页:

-X

不要保存额外的文件属性(OS/2 上的扩展属性、Unix 上的 uid/gid 和文件时间)。zip 格式使用额外的字段来包含每个条目的附加信息。一些额外字段特定于特定系统,而其他字段则适用于所有系统。通常,当 zip 从现有存档中读取条目时,它会读取它知道的额外字段,删除其余字段,并添加适用于该系统的额外字段。使用 -X 时,zip 会删除所有旧字段,只包含 Unicode 和 Zip64 额外字段(目前这两个额外字段无法禁用)。

否定此选项 -X- 包括所有默认的额外字段,但也会复制任何无法识别的额外字段。