繁体   English   中英

Terraform S3 Bucket 对象的 etag 在每次申请时不断更新

[英]Terraform S3 Bucket Object's etag keeps updating on each apply

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

我为 S3 存储桶 object 声明了一个资源:

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"))}"
}

我的代码中还有一个数据声明为 zip:

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"
}

terraform apply output 不断向我显示对 hash 的更改:

  ~ aws_s3_bucket_object.source-code-object
      etag: "old_hash" => "new_hash"

即使我的源代码中没有任何更改。 为什么会出现这种行为? 我看过类似的帖子,其中 Lambdas 的源代码不断变化,但我的 Lambdas 实际上并没有每次都更新(上次更新时间在控制台中检查)。 然而,它看起来像一个新的 S3 bucket object 被上传到每个apply

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

从zip手册页:

-X

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

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

为防止每次应用更新,使用新的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
}

正如@Matt F 指出的那样, output_base64sha256具有处理使用 KMS 加密的 s3 对象的额外好处。

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

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

在不知道它们的散列实现的情况下,没有办法预先计算 terraform 的值并使其成为一个稳定的计划。

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

我将etag替换为source_hash https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_object#source_hash最后得到:

No changes. Your infrastructure matches the configuration.

hash 存储在 tf state 而不是 aws 中。 就像它在文档中说的那样:

Triggers updates like etag but useful to address etag encryption limitations. Set using filemd5("path/to/source") (Terraform 0.11.12 or later). (The value is only stored in state and not saved by AWS.)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM